]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - fs/nfs/nfs42xdr.c
UBUNTU: [Config] updateconfigs after removing powerpc builds
[mirror_ubuntu-zesty-kernel.git] / fs / nfs / nfs42xdr.c
CommitLineData
1c6dcbe5
AS
1/*
2 * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>
3 */
4#ifndef __LINUX_FS_NFS_NFS4_2XDR_H
5#define __LINUX_FS_NFS_NFS4_2XDR_H
6
be3a5d23
TM
7#include "nfs42.h"
8
f4ac1674
AS
9#define encode_fallocate_maxsz (encode_stateid_maxsz + \
10 2 /* offset */ + \
11 2 /* length */)
2e72448b
AS
12#define NFS42_WRITE_RES_SIZE (1 /* wr_callback_id size */ +\
13 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
14 2 /* wr_count */ + \
15 1 /* wr_committed */ + \
16 XDR_QUADLEN(NFS4_VERIFIER_SIZE))
f4ac1674
AS
17#define encode_allocate_maxsz (op_encode_hdr_maxsz + \
18 encode_fallocate_maxsz)
19#define decode_allocate_maxsz (op_decode_hdr_maxsz)
2e72448b
AS
20#define encode_copy_maxsz (op_encode_hdr_maxsz + \
21 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
22 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
23 2 + 2 + 2 + 1 + 1 + 1)
24#define decode_copy_maxsz (op_decode_hdr_maxsz + \
25 NFS42_WRITE_RES_SIZE + \
26 1 /* cr_consecutive */ + \
27 1 /* cr_synchronous */)
624bd5b7
AS
28#define encode_deallocate_maxsz (op_encode_hdr_maxsz + \
29 encode_fallocate_maxsz)
30#define decode_deallocate_maxsz (op_decode_hdr_maxsz)
1c6dcbe5
AS
31#define encode_seek_maxsz (op_encode_hdr_maxsz + \
32 encode_stateid_maxsz + \
33 2 /* offset */ + \
34 1 /* whence */)
35#define decode_seek_maxsz (op_decode_hdr_maxsz + \
36 1 /* eof */ + \
37 1 /* whence */ + \
38 2 /* offset */ + \
39 2 /* length */)
be3a5d23
TM
40#define encode_io_info_maxsz 4
41#define encode_layoutstats_maxsz (op_decode_hdr_maxsz + \
42 2 /* offset */ + \
43 2 /* length */ + \
44 encode_stateid_maxsz + \
45 encode_io_info_maxsz + \
46 encode_io_info_maxsz + \
47 1 /* opaque devaddr4 length */ + \
48 XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE))
49#define decode_layoutstats_maxsz (op_decode_hdr_maxsz)
36022770
PT
50#define encode_clone_maxsz (encode_stateid_maxsz + \
51 encode_stateid_maxsz + \
52 2 /* src offset */ + \
53 2 /* dst offset */ + \
54 2 /* count */)
55#define decode_clone_maxsz (op_decode_hdr_maxsz)
1c6dcbe5 56
f4ac1674
AS
57#define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \
58 encode_putfh_maxsz + \
9a51940b
AS
59 encode_allocate_maxsz + \
60 encode_getattr_maxsz)
f4ac1674
AS
61#define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \
62 decode_putfh_maxsz + \
9a51940b
AS
63 decode_allocate_maxsz + \
64 decode_getattr_maxsz)
2e72448b
AS
65#define NFS4_enc_copy_sz (compound_encode_hdr_maxsz + \
66 encode_putfh_maxsz + \
67 encode_savefh_maxsz + \
68 encode_putfh_maxsz + \
69 encode_copy_maxsz)
70#define NFS4_dec_copy_sz (compound_decode_hdr_maxsz + \
71 decode_putfh_maxsz + \
72 decode_savefh_maxsz + \
73 decode_putfh_maxsz + \
74 decode_copy_maxsz)
624bd5b7
AS
75#define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \
76 encode_putfh_maxsz + \
9a51940b
AS
77 encode_deallocate_maxsz + \
78 encode_getattr_maxsz)
624bd5b7
AS
79#define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \
80 decode_putfh_maxsz + \
9a51940b
AS
81 decode_deallocate_maxsz + \
82 decode_getattr_maxsz)
1c6dcbe5
AS
83#define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \
84 encode_putfh_maxsz + \
85 encode_seek_maxsz)
86#define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \
87 decode_putfh_maxsz + \
88 decode_seek_maxsz)
be3a5d23
TM
89#define NFS4_enc_layoutstats_sz (compound_encode_hdr_maxsz + \
90 encode_sequence_maxsz + \
91 encode_putfh_maxsz + \
92 PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz)
93#define NFS4_dec_layoutstats_sz (compound_decode_hdr_maxsz + \
94 decode_sequence_maxsz + \
95 decode_putfh_maxsz + \
96 PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz)
36022770
PT
97#define NFS4_enc_clone_sz (compound_encode_hdr_maxsz + \
98 encode_sequence_maxsz + \
99 encode_putfh_maxsz + \
100 encode_savefh_maxsz + \
101 encode_putfh_maxsz + \
102 encode_clone_maxsz + \
103 encode_getattr_maxsz)
104#define NFS4_dec_clone_sz (compound_decode_hdr_maxsz + \
105 decode_sequence_maxsz + \
106 decode_putfh_maxsz + \
107 decode_savefh_maxsz + \
108 decode_putfh_maxsz + \
109 decode_clone_maxsz + \
110 decode_getattr_maxsz)
1c6dcbe5 111
f4ac1674
AS
112static void encode_fallocate(struct xdr_stream *xdr,
113 struct nfs42_falloc_args *args)
114{
115 encode_nfs4_stateid(xdr, &args->falloc_stateid);
116 encode_uint64(xdr, args->falloc_offset);
117 encode_uint64(xdr, args->falloc_length);
118}
119
120static void encode_allocate(struct xdr_stream *xdr,
121 struct nfs42_falloc_args *args,
122 struct compound_hdr *hdr)
123{
124 encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
125 encode_fallocate(xdr, args);
126}
127
2e72448b
AS
128static void encode_copy(struct xdr_stream *xdr,
129 struct nfs42_copy_args *args,
130 struct compound_hdr *hdr)
131{
132 encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr);
133 encode_nfs4_stateid(xdr, &args->src_stateid);
134 encode_nfs4_stateid(xdr, &args->dst_stateid);
135
136 encode_uint64(xdr, args->src_pos);
137 encode_uint64(xdr, args->dst_pos);
138 encode_uint64(xdr, args->count);
139
140 encode_uint32(xdr, 1); /* consecutive = true */
141 encode_uint32(xdr, 1); /* synchronous = true */
142 encode_uint32(xdr, 0); /* src server list */
143}
144
624bd5b7
AS
145static void encode_deallocate(struct xdr_stream *xdr,
146 struct nfs42_falloc_args *args,
147 struct compound_hdr *hdr)
148{
149 encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
150 encode_fallocate(xdr, args);
151}
152
1c6dcbe5
AS
153static void encode_seek(struct xdr_stream *xdr,
154 struct nfs42_seek_args *args,
155 struct compound_hdr *hdr)
156{
157 encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr);
158 encode_nfs4_stateid(xdr, &args->sa_stateid);
159 encode_uint64(xdr, args->sa_offset);
160 encode_uint32(xdr, args->sa_what);
161}
162
be3a5d23
TM
163static void encode_layoutstats(struct xdr_stream *xdr,
164 struct nfs42_layoutstat_args *args,
165 struct nfs42_layoutstat_devinfo *devinfo,
166 struct compound_hdr *hdr)
167{
168 __be32 *p;
169
170 encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr);
171 p = reserve_space(xdr, 8 + 8);
172 p = xdr_encode_hyper(p, devinfo->offset);
173 p = xdr_encode_hyper(p, devinfo->length);
174 encode_nfs4_stateid(xdr, &args->stateid);
175 p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4);
176 p = xdr_encode_hyper(p, devinfo->read_count);
177 p = xdr_encode_hyper(p, devinfo->read_bytes);
178 p = xdr_encode_hyper(p, devinfo->write_count);
179 p = xdr_encode_hyper(p, devinfo->write_bytes);
180 p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data,
181 NFS4_DEVICEID4_SIZE);
182 /* Encode layoutupdate4 */
183 *p++ = cpu_to_be32(devinfo->layout_type);
422c93c8
TM
184 if (devinfo->ld_private.ops)
185 devinfo->ld_private.ops->encode(xdr, args,
186 &devinfo->ld_private);
be3a5d23
TM
187 else
188 encode_uint32(xdr, 0);
189}
190
36022770
PT
191static void encode_clone(struct xdr_stream *xdr,
192 struct nfs42_clone_args *args,
193 struct compound_hdr *hdr)
194{
195 __be32 *p;
196
197 encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr);
198 encode_nfs4_stateid(xdr, &args->src_stateid);
199 encode_nfs4_stateid(xdr, &args->dst_stateid);
200 p = reserve_space(xdr, 3*8);
201 p = xdr_encode_hyper(p, args->src_offset);
202 p = xdr_encode_hyper(p, args->dst_offset);
203 xdr_encode_hyper(p, args->count);
204}
205
f4ac1674
AS
206/*
207 * Encode ALLOCATE request
208 */
209static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
210 struct xdr_stream *xdr,
211 struct nfs42_falloc_args *args)
212{
213 struct compound_hdr hdr = {
214 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
215 };
216
217 encode_compound_hdr(xdr, req, &hdr);
218 encode_sequence(xdr, &args->seq_args, &hdr);
219 encode_putfh(xdr, args->falloc_fh, &hdr);
220 encode_allocate(xdr, args, &hdr);
9a51940b 221 encode_getfattr(xdr, args->falloc_bitmask, &hdr);
f4ac1674
AS
222 encode_nops(&hdr);
223}
224
2e72448b
AS
225/*
226 * Encode COPY request
227 */
228static void nfs4_xdr_enc_copy(struct rpc_rqst *req,
229 struct xdr_stream *xdr,
230 struct nfs42_copy_args *args)
231{
232 struct compound_hdr hdr = {
233 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
234 };
235
236 encode_compound_hdr(xdr, req, &hdr);
237 encode_sequence(xdr, &args->seq_args, &hdr);
238 encode_putfh(xdr, args->src_fh, &hdr);
239 encode_savefh(xdr, &hdr);
240 encode_putfh(xdr, args->dst_fh, &hdr);
241 encode_copy(xdr, args, &hdr);
242 encode_nops(&hdr);
243}
244
624bd5b7
AS
245/*
246 * Encode DEALLOCATE request
247 */
248static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
249 struct xdr_stream *xdr,
250 struct nfs42_falloc_args *args)
251{
252 struct compound_hdr hdr = {
253 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
254 };
255
256 encode_compound_hdr(xdr, req, &hdr);
257 encode_sequence(xdr, &args->seq_args, &hdr);
258 encode_putfh(xdr, args->falloc_fh, &hdr);
259 encode_deallocate(xdr, args, &hdr);
9a51940b 260 encode_getfattr(xdr, args->falloc_bitmask, &hdr);
624bd5b7
AS
261 encode_nops(&hdr);
262}
263
1c6dcbe5
AS
264/*
265 * Encode SEEK request
266 */
267static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
268 struct xdr_stream *xdr,
269 struct nfs42_seek_args *args)
270{
271 struct compound_hdr hdr = {
272 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
273 };
274
275 encode_compound_hdr(xdr, req, &hdr);
276 encode_sequence(xdr, &args->seq_args, &hdr);
277 encode_putfh(xdr, args->sa_fh, &hdr);
278 encode_seek(xdr, args, &hdr);
279 encode_nops(&hdr);
280}
281
be3a5d23
TM
282/*
283 * Encode LAYOUTSTATS request
284 */
285static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req,
286 struct xdr_stream *xdr,
287 struct nfs42_layoutstat_args *args)
288{
289 int i;
290
291 struct compound_hdr hdr = {
292 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
293 };
294
295 encode_compound_hdr(xdr, req, &hdr);
296 encode_sequence(xdr, &args->seq_args, &hdr);
297 encode_putfh(xdr, args->fh, &hdr);
298 WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
299 for (i = 0; i < args->num_dev; i++)
300 encode_layoutstats(xdr, args, &args->devinfo[i], &hdr);
301 encode_nops(&hdr);
302}
303
36022770
PT
304/*
305 * Encode CLONE request
306 */
307static void nfs4_xdr_enc_clone(struct rpc_rqst *req,
308 struct xdr_stream *xdr,
309 struct nfs42_clone_args *args)
310{
311 struct compound_hdr hdr = {
312 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
313 };
314
315 encode_compound_hdr(xdr, req, &hdr);
316 encode_sequence(xdr, &args->seq_args, &hdr);
317 encode_putfh(xdr, args->src_fh, &hdr);
318 encode_savefh(xdr, &hdr);
319 encode_putfh(xdr, args->dst_fh, &hdr);
320 encode_clone(xdr, args, &hdr);
321 encode_getfattr(xdr, args->dst_bitmask, &hdr);
322 encode_nops(&hdr);
323}
324
f4ac1674
AS
325static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
326{
327 return decode_op_hdr(xdr, OP_ALLOCATE);
328}
329
2e72448b
AS
330static int decode_write_response(struct xdr_stream *xdr,
331 struct nfs42_write_res *res)
332{
333 __be32 *p;
2e72448b
AS
334
335 p = xdr_inline_decode(xdr, 4 + 8 + 4);
336 if (unlikely(!p))
337 goto out_overflow;
338
6fdf339b
TM
339 /*
340 * We never use asynchronous mode, so warn if a server returns
341 * a stateid.
342 */
343 if (unlikely(*p != 0)) {
344 pr_err_once("%s: server has set unrequested "
345 "asynchronous mode\n", __func__);
346 return -EREMOTEIO;
347 }
348 p++;
2e72448b
AS
349 p = xdr_decode_hyper(p, &res->count);
350 res->verifier.committed = be32_to_cpup(p);
351 return decode_verifier(xdr, &res->verifier.verifier);
352
353out_overflow:
354 print_overflow_msg(__func__, xdr);
355 return -EIO;
356}
357
358static int decode_copy_requirements(struct xdr_stream *xdr,
359 struct nfs42_copy_res *res) {
360 __be32 *p;
361
362 p = xdr_inline_decode(xdr, 4 + 4);
363 if (unlikely(!p))
364 goto out_overflow;
365
366 res->consecutive = be32_to_cpup(p++);
367 res->synchronous = be32_to_cpup(p++);
368 return 0;
369out_overflow:
370 print_overflow_msg(__func__, xdr);
371 return -EIO;
372}
373
374static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res)
375{
376 int status;
377
378 status = decode_op_hdr(xdr, OP_COPY);
379 if (status == NFS4ERR_OFFLOAD_NO_REQS) {
380 status = decode_copy_requirements(xdr, res);
381 if (status)
382 return status;
383 return NFS4ERR_OFFLOAD_NO_REQS;
384 } else if (status)
385 return status;
386
387 status = decode_write_response(xdr, &res->write_res);
388 if (status)
389 return status;
390
391 return decode_copy_requirements(xdr, res);
392}
393
624bd5b7
AS
394static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
395{
396 return decode_op_hdr(xdr, OP_DEALLOCATE);
397}
398
1c6dcbe5
AS
399static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
400{
401 int status;
402 __be32 *p;
403
404 status = decode_op_hdr(xdr, OP_SEEK);
405 if (status)
406 return status;
407
408 p = xdr_inline_decode(xdr, 4 + 8);
409 if (unlikely(!p))
410 goto out_overflow;
411
412 res->sr_eof = be32_to_cpup(p++);
413 p = xdr_decode_hyper(p, &res->sr_offset);
414 return 0;
415
416out_overflow:
417 print_overflow_msg(__func__, xdr);
418 return -EIO;
419}
420
19cf6335 421static int decode_layoutstats(struct xdr_stream *xdr)
be3a5d23 422{
da2e8127 423 return decode_op_hdr(xdr, OP_LAYOUTSTATS);
be3a5d23
TM
424}
425
36022770
PT
426static int decode_clone(struct xdr_stream *xdr)
427{
428 return decode_op_hdr(xdr, OP_CLONE);
429}
430
f4ac1674
AS
431/*
432 * Decode ALLOCATE request
433 */
434static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
435 struct xdr_stream *xdr,
436 struct nfs42_falloc_res *res)
437{
438 struct compound_hdr hdr;
439 int status;
440
441 status = decode_compound_hdr(xdr, &hdr);
442 if (status)
443 goto out;
444 status = decode_sequence(xdr, &res->seq_res, rqstp);
445 if (status)
446 goto out;
447 status = decode_putfh(xdr);
448 if (status)
449 goto out;
450 status = decode_allocate(xdr, res);
9a51940b
AS
451 if (status)
452 goto out;
453 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
f4ac1674
AS
454out:
455 return status;
456}
457
2e72448b
AS
458/*
459 * Decode COPY response
460 */
461static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp,
462 struct xdr_stream *xdr,
463 struct nfs42_copy_res *res)
464{
465 struct compound_hdr hdr;
466 int status;
467
468 status = decode_compound_hdr(xdr, &hdr);
469 if (status)
470 goto out;
471 status = decode_sequence(xdr, &res->seq_res, rqstp);
472 if (status)
473 goto out;
474 status = decode_putfh(xdr);
475 if (status)
476 goto out;
477 status = decode_savefh(xdr);
478 if (status)
479 goto out;
480 status = decode_putfh(xdr);
481 if (status)
482 goto out;
483 status = decode_copy(xdr, res);
484out:
485 return status;
486}
487
624bd5b7
AS
488/*
489 * Decode DEALLOCATE request
490 */
491static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
492 struct xdr_stream *xdr,
493 struct nfs42_falloc_res *res)
494{
495 struct compound_hdr hdr;
496 int status;
497
498 status = decode_compound_hdr(xdr, &hdr);
499 if (status)
500 goto out;
501 status = decode_sequence(xdr, &res->seq_res, rqstp);
502 if (status)
503 goto out;
504 status = decode_putfh(xdr);
505 if (status)
506 goto out;
507 status = decode_deallocate(xdr, res);
9a51940b
AS
508 if (status)
509 goto out;
510 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
624bd5b7
AS
511out:
512 return status;
513}
514
1c6dcbe5
AS
515/*
516 * Decode SEEK request
517 */
518static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
519 struct xdr_stream *xdr,
520 struct nfs42_seek_res *res)
521{
522 struct compound_hdr hdr;
523 int status;
524
525 status = decode_compound_hdr(xdr, &hdr);
526 if (status)
527 goto out;
528 status = decode_sequence(xdr, &res->seq_res, rqstp);
529 if (status)
530 goto out;
531 status = decode_putfh(xdr);
532 if (status)
533 goto out;
534 status = decode_seek(xdr, res);
535out:
536 return status;
537}
be3a5d23
TM
538
539/*
540 * Decode LAYOUTSTATS request
541 */
542static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp,
543 struct xdr_stream *xdr,
544 struct nfs42_layoutstat_res *res)
545{
546 struct compound_hdr hdr;
547 int status, i;
548
549 status = decode_compound_hdr(xdr, &hdr);
550 if (status)
551 goto out;
552 status = decode_sequence(xdr, &res->seq_res, rqstp);
553 if (status)
554 goto out;
555 status = decode_putfh(xdr);
556 if (status)
557 goto out;
558 WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
559 for (i = 0; i < res->num_dev; i++) {
19cf6335 560 status = decode_layoutstats(xdr);
be3a5d23
TM
561 if (status)
562 goto out;
563 }
564out:
565 res->rpc_status = status;
566 return status;
567}
568
36022770
PT
569/*
570 * Decode CLONE request
571 */
572static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp,
573 struct xdr_stream *xdr,
574 struct nfs42_clone_res *res)
575{
576 struct compound_hdr hdr;
577 int status;
578
579 status = decode_compound_hdr(xdr, &hdr);
580 if (status)
581 goto out;
582 status = decode_sequence(xdr, &res->seq_res, rqstp);
583 if (status)
584 goto out;
585 status = decode_putfh(xdr);
586 if (status)
587 goto out;
588 status = decode_savefh(xdr);
589 if (status)
590 goto out;
591 status = decode_putfh(xdr);
592 if (status)
593 goto out;
594 status = decode_clone(xdr);
595 if (status)
596 goto out;
597 status = decode_getfattr(xdr, res->dst_fattr, res->server);
598
599out:
600 res->rpc_status = status;
601 return status;
602}
603
1c6dcbe5 604#endif /* __LINUX_FS_NFS_NFS4_2XDR_H */