1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>
5 #ifndef __LINUX_FS_NFS_NFS4_2XDR_H
6 #define __LINUX_FS_NFS_NFS4_2XDR_H
10 #define encode_fallocate_maxsz (encode_stateid_maxsz + \
13 #define NFS42_WRITE_RES_SIZE (1 /* wr_callback_id size */ +\
14 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
16 1 /* wr_committed */ + \
17 XDR_QUADLEN(NFS4_VERIFIER_SIZE))
18 #define encode_allocate_maxsz (op_encode_hdr_maxsz + \
19 encode_fallocate_maxsz)
20 #define decode_allocate_maxsz (op_decode_hdr_maxsz)
21 #define encode_copy_maxsz (op_encode_hdr_maxsz + \
22 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
23 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
24 2 + 2 + 2 + 1 + 1 + 1)
25 #define decode_copy_maxsz (op_decode_hdr_maxsz + \
26 NFS42_WRITE_RES_SIZE + \
27 1 /* cr_consecutive */ + \
28 1 /* cr_synchronous */)
29 #define encode_offload_cancel_maxsz (op_encode_hdr_maxsz + \
30 XDR_QUADLEN(NFS4_STATEID_SIZE))
31 #define decode_offload_cancel_maxsz (op_decode_hdr_maxsz)
32 #define encode_deallocate_maxsz (op_encode_hdr_maxsz + \
33 encode_fallocate_maxsz)
34 #define decode_deallocate_maxsz (op_decode_hdr_maxsz)
35 #define encode_seek_maxsz (op_encode_hdr_maxsz + \
36 encode_stateid_maxsz + \
39 #define decode_seek_maxsz (op_decode_hdr_maxsz + \
44 #define encode_io_info_maxsz 4
45 #define encode_layoutstats_maxsz (op_decode_hdr_maxsz + \
48 encode_stateid_maxsz + \
49 encode_io_info_maxsz + \
50 encode_io_info_maxsz + \
51 1 /* opaque devaddr4 length */ + \
52 XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE))
53 #define decode_layoutstats_maxsz (op_decode_hdr_maxsz)
54 #define encode_clone_maxsz (encode_stateid_maxsz + \
55 encode_stateid_maxsz + \
56 2 /* src offset */ + \
57 2 /* dst offset */ + \
59 #define decode_clone_maxsz (op_decode_hdr_maxsz)
61 #define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \
62 encode_sequence_maxsz + \
63 encode_putfh_maxsz + \
64 encode_allocate_maxsz + \
66 #define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \
67 decode_sequence_maxsz + \
68 decode_putfh_maxsz + \
69 decode_allocate_maxsz + \
71 #define NFS4_enc_copy_sz (compound_encode_hdr_maxsz + \
72 encode_sequence_maxsz + \
73 encode_putfh_maxsz + \
74 encode_savefh_maxsz + \
75 encode_putfh_maxsz + \
78 #define NFS4_dec_copy_sz (compound_decode_hdr_maxsz + \
79 decode_sequence_maxsz + \
80 decode_putfh_maxsz + \
81 decode_savefh_maxsz + \
82 decode_putfh_maxsz + \
85 #define NFS4_enc_offload_cancel_sz (compound_encode_hdr_maxsz + \
86 encode_sequence_maxsz + \
87 encode_putfh_maxsz + \
88 encode_offload_cancel_maxsz)
89 #define NFS4_dec_offload_cancel_sz (compound_decode_hdr_maxsz + \
90 decode_sequence_maxsz + \
91 decode_putfh_maxsz + \
92 decode_offload_cancel_maxsz)
93 #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \
94 encode_sequence_maxsz + \
95 encode_putfh_maxsz + \
96 encode_deallocate_maxsz + \
98 #define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \
99 decode_sequence_maxsz + \
100 decode_putfh_maxsz + \
101 decode_deallocate_maxsz + \
102 decode_getattr_maxsz)
103 #define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \
104 encode_sequence_maxsz + \
105 encode_putfh_maxsz + \
107 #define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \
108 decode_sequence_maxsz + \
109 decode_putfh_maxsz + \
111 #define NFS4_enc_layoutstats_sz (compound_encode_hdr_maxsz + \
112 encode_sequence_maxsz + \
113 encode_putfh_maxsz + \
114 PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz)
115 #define NFS4_dec_layoutstats_sz (compound_decode_hdr_maxsz + \
116 decode_sequence_maxsz + \
117 decode_putfh_maxsz + \
118 PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz)
119 #define NFS4_enc_clone_sz (compound_encode_hdr_maxsz + \
120 encode_sequence_maxsz + \
121 encode_putfh_maxsz + \
122 encode_savefh_maxsz + \
123 encode_putfh_maxsz + \
124 encode_clone_maxsz + \
125 encode_getattr_maxsz)
126 #define NFS4_dec_clone_sz (compound_decode_hdr_maxsz + \
127 decode_sequence_maxsz + \
128 decode_putfh_maxsz + \
129 decode_savefh_maxsz + \
130 decode_putfh_maxsz + \
131 decode_clone_maxsz + \
132 decode_getattr_maxsz)
134 static void encode_fallocate(struct xdr_stream *xdr,
135 const struct nfs42_falloc_args *args)
137 encode_nfs4_stateid(xdr, &args->falloc_stateid);
138 encode_uint64(xdr, args->falloc_offset);
139 encode_uint64(xdr, args->falloc_length);
142 static void encode_allocate(struct xdr_stream *xdr,
143 const struct nfs42_falloc_args *args,
144 struct compound_hdr *hdr)
146 encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
147 encode_fallocate(xdr, args);
150 static void encode_copy(struct xdr_stream *xdr,
151 const struct nfs42_copy_args *args,
152 struct compound_hdr *hdr)
154 encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr);
155 encode_nfs4_stateid(xdr, &args->src_stateid);
156 encode_nfs4_stateid(xdr, &args->dst_stateid);
158 encode_uint64(xdr, args->src_pos);
159 encode_uint64(xdr, args->dst_pos);
160 encode_uint64(xdr, args->count);
162 encode_uint32(xdr, 1); /* consecutive = true */
163 encode_uint32(xdr, args->sync);
164 encode_uint32(xdr, 0); /* src server list */
167 static void encode_offload_cancel(struct xdr_stream *xdr,
168 const struct nfs42_offload_status_args *args,
169 struct compound_hdr *hdr)
171 encode_op_hdr(xdr, OP_OFFLOAD_CANCEL, decode_offload_cancel_maxsz, hdr);
172 encode_nfs4_stateid(xdr, &args->osa_stateid);
175 static void encode_deallocate(struct xdr_stream *xdr,
176 const struct nfs42_falloc_args *args,
177 struct compound_hdr *hdr)
179 encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
180 encode_fallocate(xdr, args);
183 static void encode_seek(struct xdr_stream *xdr,
184 const struct nfs42_seek_args *args,
185 struct compound_hdr *hdr)
187 encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr);
188 encode_nfs4_stateid(xdr, &args->sa_stateid);
189 encode_uint64(xdr, args->sa_offset);
190 encode_uint32(xdr, args->sa_what);
193 static void encode_layoutstats(struct xdr_stream *xdr,
194 const struct nfs42_layoutstat_args *args,
195 struct nfs42_layoutstat_devinfo *devinfo,
196 struct compound_hdr *hdr)
200 encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr);
201 p = reserve_space(xdr, 8 + 8);
202 p = xdr_encode_hyper(p, devinfo->offset);
203 p = xdr_encode_hyper(p, devinfo->length);
204 encode_nfs4_stateid(xdr, &args->stateid);
205 p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4);
206 p = xdr_encode_hyper(p, devinfo->read_count);
207 p = xdr_encode_hyper(p, devinfo->read_bytes);
208 p = xdr_encode_hyper(p, devinfo->write_count);
209 p = xdr_encode_hyper(p, devinfo->write_bytes);
210 p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data,
211 NFS4_DEVICEID4_SIZE);
212 /* Encode layoutupdate4 */
213 *p++ = cpu_to_be32(devinfo->layout_type);
214 if (devinfo->ld_private.ops)
215 devinfo->ld_private.ops->encode(xdr, args,
216 &devinfo->ld_private);
218 encode_uint32(xdr, 0);
221 static void encode_clone(struct xdr_stream *xdr,
222 const struct nfs42_clone_args *args,
223 struct compound_hdr *hdr)
227 encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr);
228 encode_nfs4_stateid(xdr, &args->src_stateid);
229 encode_nfs4_stateid(xdr, &args->dst_stateid);
230 p = reserve_space(xdr, 3*8);
231 p = xdr_encode_hyper(p, args->src_offset);
232 p = xdr_encode_hyper(p, args->dst_offset);
233 xdr_encode_hyper(p, args->count);
237 * Encode ALLOCATE request
239 static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
240 struct xdr_stream *xdr,
243 const struct nfs42_falloc_args *args = data;
244 struct compound_hdr hdr = {
245 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
248 encode_compound_hdr(xdr, req, &hdr);
249 encode_sequence(xdr, &args->seq_args, &hdr);
250 encode_putfh(xdr, args->falloc_fh, &hdr);
251 encode_allocate(xdr, args, &hdr);
252 encode_getfattr(xdr, args->falloc_bitmask, &hdr);
256 static void encode_copy_commit(struct xdr_stream *xdr,
257 const struct nfs42_copy_args *args,
258 struct compound_hdr *hdr)
262 encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr);
263 p = reserve_space(xdr, 12);
264 p = xdr_encode_hyper(p, args->dst_pos);
265 *p = cpu_to_be32(args->count);
269 * Encode COPY request
271 static void nfs4_xdr_enc_copy(struct rpc_rqst *req,
272 struct xdr_stream *xdr,
275 const struct nfs42_copy_args *args = data;
276 struct compound_hdr hdr = {
277 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
280 encode_compound_hdr(xdr, req, &hdr);
281 encode_sequence(xdr, &args->seq_args, &hdr);
282 encode_putfh(xdr, args->src_fh, &hdr);
283 encode_savefh(xdr, &hdr);
284 encode_putfh(xdr, args->dst_fh, &hdr);
285 encode_copy(xdr, args, &hdr);
287 encode_copy_commit(xdr, args, &hdr);
292 * Encode OFFLOAD_CANEL request
294 static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req,
295 struct xdr_stream *xdr,
298 const struct nfs42_offload_status_args *args = data;
299 struct compound_hdr hdr = {
300 .minorversion = nfs4_xdr_minorversion(&args->osa_seq_args),
303 encode_compound_hdr(xdr, req, &hdr);
304 encode_sequence(xdr, &args->osa_seq_args, &hdr);
305 encode_putfh(xdr, args->osa_src_fh, &hdr);
306 encode_offload_cancel(xdr, args, &hdr);
311 * Encode DEALLOCATE request
313 static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
314 struct xdr_stream *xdr,
317 const struct nfs42_falloc_args *args = data;
318 struct compound_hdr hdr = {
319 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
322 encode_compound_hdr(xdr, req, &hdr);
323 encode_sequence(xdr, &args->seq_args, &hdr);
324 encode_putfh(xdr, args->falloc_fh, &hdr);
325 encode_deallocate(xdr, args, &hdr);
326 encode_getfattr(xdr, args->falloc_bitmask, &hdr);
331 * Encode SEEK request
333 static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
334 struct xdr_stream *xdr,
337 const struct nfs42_seek_args *args = data;
338 struct compound_hdr hdr = {
339 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
342 encode_compound_hdr(xdr, req, &hdr);
343 encode_sequence(xdr, &args->seq_args, &hdr);
344 encode_putfh(xdr, args->sa_fh, &hdr);
345 encode_seek(xdr, args, &hdr);
350 * Encode LAYOUTSTATS request
352 static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req,
353 struct xdr_stream *xdr,
356 const struct nfs42_layoutstat_args *args = data;
359 struct compound_hdr hdr = {
360 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
363 encode_compound_hdr(xdr, req, &hdr);
364 encode_sequence(xdr, &args->seq_args, &hdr);
365 encode_putfh(xdr, args->fh, &hdr);
366 WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
367 for (i = 0; i < args->num_dev; i++)
368 encode_layoutstats(xdr, args, &args->devinfo[i], &hdr);
373 * Encode CLONE request
375 static void nfs4_xdr_enc_clone(struct rpc_rqst *req,
376 struct xdr_stream *xdr,
379 const struct nfs42_clone_args *args = data;
380 struct compound_hdr hdr = {
381 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
384 encode_compound_hdr(xdr, req, &hdr);
385 encode_sequence(xdr, &args->seq_args, &hdr);
386 encode_putfh(xdr, args->src_fh, &hdr);
387 encode_savefh(xdr, &hdr);
388 encode_putfh(xdr, args->dst_fh, &hdr);
389 encode_clone(xdr, args, &hdr);
390 encode_getfattr(xdr, args->dst_bitmask, &hdr);
394 static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
396 return decode_op_hdr(xdr, OP_ALLOCATE);
399 static int decode_write_response(struct xdr_stream *xdr,
400 struct nfs42_write_res *res)
405 p = xdr_inline_decode(xdr, 4);
408 count = be32_to_cpup(p);
411 else if (count == 1) {
412 status = decode_opaque_fixed(xdr, &res->stateid,
414 if (unlikely(status))
417 p = xdr_inline_decode(xdr, 8 + 4);
420 p = xdr_decode_hyper(p, &res->count);
421 res->verifier.committed = be32_to_cpup(p);
422 return decode_verifier(xdr, &res->verifier.verifier);
425 print_overflow_msg(__func__, xdr);
429 static int decode_copy_requirements(struct xdr_stream *xdr,
430 struct nfs42_copy_res *res) {
433 p = xdr_inline_decode(xdr, 4 + 4);
437 res->consecutive = be32_to_cpup(p++);
438 res->synchronous = be32_to_cpup(p++);
441 print_overflow_msg(__func__, xdr);
445 static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res)
449 status = decode_op_hdr(xdr, OP_COPY);
450 if (status == NFS4ERR_OFFLOAD_NO_REQS) {
451 status = decode_copy_requirements(xdr, res);
454 return NFS4ERR_OFFLOAD_NO_REQS;
458 status = decode_write_response(xdr, &res->write_res);
462 return decode_copy_requirements(xdr, res);
465 static int decode_offload_cancel(struct xdr_stream *xdr,
466 struct nfs42_offload_status_res *res)
468 return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);
471 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
473 return decode_op_hdr(xdr, OP_DEALLOCATE);
476 static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
481 status = decode_op_hdr(xdr, OP_SEEK);
485 p = xdr_inline_decode(xdr, 4 + 8);
489 res->sr_eof = be32_to_cpup(p++);
490 p = xdr_decode_hyper(p, &res->sr_offset);
494 print_overflow_msg(__func__, xdr);
498 static int decode_layoutstats(struct xdr_stream *xdr)
500 return decode_op_hdr(xdr, OP_LAYOUTSTATS);
503 static int decode_clone(struct xdr_stream *xdr)
505 return decode_op_hdr(xdr, OP_CLONE);
509 * Decode ALLOCATE request
511 static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
512 struct xdr_stream *xdr,
515 struct nfs42_falloc_res *res = data;
516 struct compound_hdr hdr;
519 status = decode_compound_hdr(xdr, &hdr);
522 status = decode_sequence(xdr, &res->seq_res, rqstp);
525 status = decode_putfh(xdr);
528 status = decode_allocate(xdr, res);
531 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
537 * Decode COPY response
539 static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp,
540 struct xdr_stream *xdr,
543 struct nfs42_copy_res *res = data;
544 struct compound_hdr hdr;
547 status = decode_compound_hdr(xdr, &hdr);
550 status = decode_sequence(xdr, &res->seq_res, rqstp);
553 status = decode_putfh(xdr);
556 status = decode_savefh(xdr);
559 status = decode_putfh(xdr);
562 status = decode_copy(xdr, res);
565 if (res->commit_res.verf)
566 status = decode_commit(xdr, &res->commit_res);
572 * Decode OFFLOAD_CANCEL response
574 static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp,
575 struct xdr_stream *xdr,
578 struct nfs42_offload_status_res *res = data;
579 struct compound_hdr hdr;
582 status = decode_compound_hdr(xdr, &hdr);
585 status = decode_sequence(xdr, &res->osr_seq_res, rqstp);
588 status = decode_putfh(xdr);
591 status = decode_offload_cancel(xdr, res);
598 * Decode DEALLOCATE request
600 static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
601 struct xdr_stream *xdr,
604 struct nfs42_falloc_res *res = data;
605 struct compound_hdr hdr;
608 status = decode_compound_hdr(xdr, &hdr);
611 status = decode_sequence(xdr, &res->seq_res, rqstp);
614 status = decode_putfh(xdr);
617 status = decode_deallocate(xdr, res);
620 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
626 * Decode SEEK request
628 static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
629 struct xdr_stream *xdr,
632 struct nfs42_seek_res *res = data;
633 struct compound_hdr hdr;
636 status = decode_compound_hdr(xdr, &hdr);
639 status = decode_sequence(xdr, &res->seq_res, rqstp);
642 status = decode_putfh(xdr);
645 status = decode_seek(xdr, res);
651 * Decode LAYOUTSTATS request
653 static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp,
654 struct xdr_stream *xdr,
657 struct nfs42_layoutstat_res *res = data;
658 struct compound_hdr hdr;
661 status = decode_compound_hdr(xdr, &hdr);
664 status = decode_sequence(xdr, &res->seq_res, rqstp);
667 status = decode_putfh(xdr);
670 WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
671 for (i = 0; i < res->num_dev; i++) {
672 status = decode_layoutstats(xdr);
677 res->rpc_status = status;
682 * Decode CLONE request
684 static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp,
685 struct xdr_stream *xdr,
688 struct nfs42_clone_res *res = data;
689 struct compound_hdr hdr;
692 status = decode_compound_hdr(xdr, &hdr);
695 status = decode_sequence(xdr, &res->seq_res, rqstp);
698 status = decode_putfh(xdr);
701 status = decode_savefh(xdr);
704 status = decode_putfh(xdr);
707 status = decode_clone(xdr);
710 status = decode_getfattr(xdr, res->dst_fattr, res->server);
713 res->rpc_status = status;
717 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */