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 1 + /* One cnr_source_server */\
27 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
28 #define decode_copy_maxsz (op_decode_hdr_maxsz + \
29 NFS42_WRITE_RES_SIZE + \
30 1 /* cr_consecutive */ + \
31 1 /* cr_synchronous */)
32 #define encode_offload_cancel_maxsz (op_encode_hdr_maxsz + \
33 XDR_QUADLEN(NFS4_STATEID_SIZE))
34 #define decode_offload_cancel_maxsz (op_decode_hdr_maxsz)
35 #define encode_copy_notify_maxsz (op_encode_hdr_maxsz + \
36 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
38 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
39 #define decode_copy_notify_maxsz (op_decode_hdr_maxsz + \
40 3 + /* cnr_lease_time */\
41 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
42 1 + /* Support 1 cnr_source_server */\
44 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
45 #define encode_deallocate_maxsz (op_encode_hdr_maxsz + \
46 encode_fallocate_maxsz)
47 #define decode_deallocate_maxsz (op_decode_hdr_maxsz)
48 #define encode_seek_maxsz (op_encode_hdr_maxsz + \
49 encode_stateid_maxsz + \
52 #define decode_seek_maxsz (op_decode_hdr_maxsz + \
57 #define encode_io_info_maxsz 4
58 #define encode_layoutstats_maxsz (op_decode_hdr_maxsz + \
61 encode_stateid_maxsz + \
62 encode_io_info_maxsz + \
63 encode_io_info_maxsz + \
64 1 /* opaque devaddr4 length */ + \
65 XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE))
66 #define decode_layoutstats_maxsz (op_decode_hdr_maxsz)
67 #define encode_device_error_maxsz (XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \
68 1 /* status */ + 1 /* opnum */)
69 #define encode_layouterror_maxsz (op_decode_hdr_maxsz + \
72 encode_stateid_maxsz + \
73 1 /* Array size */ + \
74 encode_device_error_maxsz)
75 #define decode_layouterror_maxsz (op_decode_hdr_maxsz)
76 #define encode_clone_maxsz (encode_stateid_maxsz + \
77 encode_stateid_maxsz + \
78 2 /* src offset */ + \
79 2 /* dst offset */ + \
81 #define decode_clone_maxsz (op_decode_hdr_maxsz)
83 #define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \
84 encode_sequence_maxsz + \
85 encode_putfh_maxsz + \
86 encode_allocate_maxsz + \
88 #define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \
89 decode_sequence_maxsz + \
90 decode_putfh_maxsz + \
91 decode_allocate_maxsz + \
93 #define NFS4_enc_copy_sz (compound_encode_hdr_maxsz + \
94 encode_sequence_maxsz + \
95 encode_putfh_maxsz + \
96 encode_savefh_maxsz + \
97 encode_putfh_maxsz + \
100 #define NFS4_dec_copy_sz (compound_decode_hdr_maxsz + \
101 decode_sequence_maxsz + \
102 decode_putfh_maxsz + \
103 decode_savefh_maxsz + \
104 decode_putfh_maxsz + \
105 decode_copy_maxsz + \
107 #define NFS4_enc_offload_cancel_sz (compound_encode_hdr_maxsz + \
108 encode_sequence_maxsz + \
109 encode_putfh_maxsz + \
110 encode_offload_cancel_maxsz)
111 #define NFS4_dec_offload_cancel_sz (compound_decode_hdr_maxsz + \
112 decode_sequence_maxsz + \
113 decode_putfh_maxsz + \
114 decode_offload_cancel_maxsz)
115 #define NFS4_enc_copy_notify_sz (compound_encode_hdr_maxsz + \
116 encode_putfh_maxsz + \
117 encode_copy_notify_maxsz)
118 #define NFS4_dec_copy_notify_sz (compound_decode_hdr_maxsz + \
119 decode_putfh_maxsz + \
120 decode_copy_notify_maxsz)
121 #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \
122 encode_sequence_maxsz + \
123 encode_putfh_maxsz + \
124 encode_deallocate_maxsz + \
125 encode_getattr_maxsz)
126 #define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \
127 decode_sequence_maxsz + \
128 decode_putfh_maxsz + \
129 decode_deallocate_maxsz + \
130 decode_getattr_maxsz)
131 #define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \
132 encode_sequence_maxsz + \
133 encode_putfh_maxsz + \
135 #define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \
136 decode_sequence_maxsz + \
137 decode_putfh_maxsz + \
139 #define NFS4_enc_layoutstats_sz (compound_encode_hdr_maxsz + \
140 encode_sequence_maxsz + \
141 encode_putfh_maxsz + \
142 PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz)
143 #define NFS4_dec_layoutstats_sz (compound_decode_hdr_maxsz + \
144 decode_sequence_maxsz + \
145 decode_putfh_maxsz + \
146 PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz)
147 #define NFS4_enc_layouterror_sz (compound_encode_hdr_maxsz + \
148 encode_sequence_maxsz + \
149 encode_putfh_maxsz + \
150 NFS42_LAYOUTERROR_MAX * \
151 encode_layouterror_maxsz)
152 #define NFS4_dec_layouterror_sz (compound_decode_hdr_maxsz + \
153 decode_sequence_maxsz + \
154 decode_putfh_maxsz + \
155 NFS42_LAYOUTERROR_MAX * \
156 decode_layouterror_maxsz)
157 #define NFS4_enc_clone_sz (compound_encode_hdr_maxsz + \
158 encode_sequence_maxsz + \
159 encode_putfh_maxsz + \
160 encode_savefh_maxsz + \
161 encode_putfh_maxsz + \
162 encode_clone_maxsz + \
163 encode_getattr_maxsz)
164 #define NFS4_dec_clone_sz (compound_decode_hdr_maxsz + \
165 decode_sequence_maxsz + \
166 decode_putfh_maxsz + \
167 decode_savefh_maxsz + \
168 decode_putfh_maxsz + \
169 decode_clone_maxsz + \
170 decode_getattr_maxsz)
172 /* Not limited by NFS itself, limited by the generic xattr code */
173 #define nfs4_xattr_name_maxsz XDR_QUADLEN(XATTR_NAME_MAX)
175 #define encode_getxattr_maxsz (op_encode_hdr_maxsz + 1 + \
176 nfs4_xattr_name_maxsz)
177 #define decode_getxattr_maxsz (op_decode_hdr_maxsz + 1 + 1)
178 #define encode_setxattr_maxsz (op_encode_hdr_maxsz + \
179 1 + nfs4_xattr_name_maxsz + 1)
180 #define decode_setxattr_maxsz (op_decode_hdr_maxsz + decode_change_info_maxsz)
181 #define encode_listxattrs_maxsz (op_encode_hdr_maxsz + 2 + 1)
182 #define decode_listxattrs_maxsz (op_decode_hdr_maxsz + 2 + 1 + 1)
183 #define encode_removexattr_maxsz (op_encode_hdr_maxsz + 1 + \
184 nfs4_xattr_name_maxsz)
185 #define decode_removexattr_maxsz (op_decode_hdr_maxsz + \
186 decode_change_info_maxsz)
188 #define NFS4_enc_getxattr_sz (compound_encode_hdr_maxsz + \
189 encode_sequence_maxsz + \
190 encode_putfh_maxsz + \
191 encode_getxattr_maxsz)
192 #define NFS4_dec_getxattr_sz (compound_decode_hdr_maxsz + \
193 decode_sequence_maxsz + \
194 decode_putfh_maxsz + \
195 decode_getxattr_maxsz)
196 #define NFS4_enc_setxattr_sz (compound_encode_hdr_maxsz + \
197 encode_sequence_maxsz + \
198 encode_putfh_maxsz + \
199 encode_setxattr_maxsz)
200 #define NFS4_dec_setxattr_sz (compound_decode_hdr_maxsz + \
201 decode_sequence_maxsz + \
202 decode_putfh_maxsz + \
203 decode_setxattr_maxsz)
204 #define NFS4_enc_listxattrs_sz (compound_encode_hdr_maxsz + \
205 encode_sequence_maxsz + \
206 encode_putfh_maxsz + \
207 encode_listxattrs_maxsz)
208 #define NFS4_dec_listxattrs_sz (compound_decode_hdr_maxsz + \
209 decode_sequence_maxsz + \
210 decode_putfh_maxsz + \
211 decode_listxattrs_maxsz)
212 #define NFS4_enc_removexattr_sz (compound_encode_hdr_maxsz + \
213 encode_sequence_maxsz + \
214 encode_putfh_maxsz + \
215 encode_removexattr_maxsz)
216 #define NFS4_dec_removexattr_sz (compound_decode_hdr_maxsz + \
217 decode_sequence_maxsz + \
218 decode_putfh_maxsz + \
219 decode_removexattr_maxsz)
222 * These values specify the maximum amount of data that is not
223 * associated with the extended attribute name or extended
224 * attribute list in the SETXATTR, GETXATTR and LISTXATTR
227 const u32 nfs42_maxsetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
228 compound_encode_hdr_maxsz +
229 encode_sequence_maxsz +
230 encode_putfh_maxsz + 1 +
231 nfs4_xattr_name_maxsz)
234 const u32 nfs42_maxgetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
235 compound_decode_hdr_maxsz +
236 decode_sequence_maxsz +
237 decode_putfh_maxsz + 1) * XDR_UNIT);
239 const u32 nfs42_maxlistxattrs_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
240 compound_decode_hdr_maxsz +
241 decode_sequence_maxsz +
242 decode_putfh_maxsz + 3) * XDR_UNIT);
244 static void encode_fallocate(struct xdr_stream *xdr,
245 const struct nfs42_falloc_args *args)
247 encode_nfs4_stateid(xdr, &args->falloc_stateid);
248 encode_uint64(xdr, args->falloc_offset);
249 encode_uint64(xdr, args->falloc_length);
252 static void encode_allocate(struct xdr_stream *xdr,
253 const struct nfs42_falloc_args *args,
254 struct compound_hdr *hdr)
256 encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
257 encode_fallocate(xdr, args);
260 static void encode_nl4_server(struct xdr_stream *xdr,
261 const struct nl4_server *ns)
263 encode_uint32(xdr, ns->nl4_type);
264 switch (ns->nl4_type) {
267 encode_string(xdr, ns->u.nl4_str_sz, ns->u.nl4_str);
270 encode_string(xdr, ns->u.nl4_addr.netid_len,
271 ns->u.nl4_addr.netid);
272 encode_string(xdr, ns->u.nl4_addr.addr_len,
273 ns->u.nl4_addr.addr);
280 static void encode_copy(struct xdr_stream *xdr,
281 const struct nfs42_copy_args *args,
282 struct compound_hdr *hdr)
284 encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr);
285 encode_nfs4_stateid(xdr, &args->src_stateid);
286 encode_nfs4_stateid(xdr, &args->dst_stateid);
288 encode_uint64(xdr, args->src_pos);
289 encode_uint64(xdr, args->dst_pos);
290 encode_uint64(xdr, args->count);
292 encode_uint32(xdr, 1); /* consecutive = true */
293 encode_uint32(xdr, args->sync);
294 if (args->cp_src == NULL) { /* intra-ssc */
295 encode_uint32(xdr, 0); /* no src server list */
298 encode_uint32(xdr, 1); /* supporting 1 server */
299 encode_nl4_server(xdr, args->cp_src);
302 static void encode_offload_cancel(struct xdr_stream *xdr,
303 const struct nfs42_offload_status_args *args,
304 struct compound_hdr *hdr)
306 encode_op_hdr(xdr, OP_OFFLOAD_CANCEL, decode_offload_cancel_maxsz, hdr);
307 encode_nfs4_stateid(xdr, &args->osa_stateid);
310 static void encode_copy_notify(struct xdr_stream *xdr,
311 const struct nfs42_copy_notify_args *args,
312 struct compound_hdr *hdr)
314 encode_op_hdr(xdr, OP_COPY_NOTIFY, decode_copy_notify_maxsz, hdr);
315 encode_nfs4_stateid(xdr, &args->cna_src_stateid);
316 encode_nl4_server(xdr, &args->cna_dst);
319 static void encode_deallocate(struct xdr_stream *xdr,
320 const struct nfs42_falloc_args *args,
321 struct compound_hdr *hdr)
323 encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
324 encode_fallocate(xdr, args);
327 static void encode_seek(struct xdr_stream *xdr,
328 const struct nfs42_seek_args *args,
329 struct compound_hdr *hdr)
331 encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr);
332 encode_nfs4_stateid(xdr, &args->sa_stateid);
333 encode_uint64(xdr, args->sa_offset);
334 encode_uint32(xdr, args->sa_what);
337 static void encode_layoutstats(struct xdr_stream *xdr,
338 const struct nfs42_layoutstat_args *args,
339 struct nfs42_layoutstat_devinfo *devinfo,
340 struct compound_hdr *hdr)
344 encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr);
345 p = reserve_space(xdr, 8 + 8);
346 p = xdr_encode_hyper(p, devinfo->offset);
347 p = xdr_encode_hyper(p, devinfo->length);
348 encode_nfs4_stateid(xdr, &args->stateid);
349 p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4);
350 p = xdr_encode_hyper(p, devinfo->read_count);
351 p = xdr_encode_hyper(p, devinfo->read_bytes);
352 p = xdr_encode_hyper(p, devinfo->write_count);
353 p = xdr_encode_hyper(p, devinfo->write_bytes);
354 p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data,
355 NFS4_DEVICEID4_SIZE);
356 /* Encode layoutupdate4 */
357 *p++ = cpu_to_be32(devinfo->layout_type);
358 if (devinfo->ld_private.ops)
359 devinfo->ld_private.ops->encode(xdr, args,
360 &devinfo->ld_private);
362 encode_uint32(xdr, 0);
365 static void encode_clone(struct xdr_stream *xdr,
366 const struct nfs42_clone_args *args,
367 struct compound_hdr *hdr)
371 encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr);
372 encode_nfs4_stateid(xdr, &args->src_stateid);
373 encode_nfs4_stateid(xdr, &args->dst_stateid);
374 p = reserve_space(xdr, 3*8);
375 p = xdr_encode_hyper(p, args->src_offset);
376 p = xdr_encode_hyper(p, args->dst_offset);
377 xdr_encode_hyper(p, args->count);
380 static void encode_device_error(struct xdr_stream *xdr,
381 const struct nfs42_device_error *error)
385 p = reserve_space(xdr, NFS4_DEVICEID4_SIZE + 2*4);
386 p = xdr_encode_opaque_fixed(p, error->dev_id.data,
387 NFS4_DEVICEID4_SIZE);
388 *p++ = cpu_to_be32(error->status);
389 *p = cpu_to_be32(error->opnum);
392 static void encode_layouterror(struct xdr_stream *xdr,
393 const struct nfs42_layout_error *args,
394 struct compound_hdr *hdr)
398 encode_op_hdr(xdr, OP_LAYOUTERROR, decode_layouterror_maxsz, hdr);
399 p = reserve_space(xdr, 8 + 8);
400 p = xdr_encode_hyper(p, args->offset);
401 p = xdr_encode_hyper(p, args->length);
402 encode_nfs4_stateid(xdr, &args->stateid);
403 p = reserve_space(xdr, 4);
405 encode_device_error(xdr, &args->errors[0]);
408 static void encode_setxattr(struct xdr_stream *xdr,
409 const struct nfs42_setxattrargs *arg,
410 struct compound_hdr *hdr)
414 BUILD_BUG_ON(XATTR_CREATE != SETXATTR4_CREATE);
415 BUILD_BUG_ON(XATTR_REPLACE != SETXATTR4_REPLACE);
417 encode_op_hdr(xdr, OP_SETXATTR, decode_setxattr_maxsz, hdr);
418 p = reserve_space(xdr, 4);
419 *p = cpu_to_be32(arg->xattr_flags);
420 encode_string(xdr, strlen(arg->xattr_name), arg->xattr_name);
421 p = reserve_space(xdr, 4);
422 *p = cpu_to_be32(arg->xattr_len);
424 xdr_write_pages(xdr, arg->xattr_pages, 0, arg->xattr_len);
427 static int decode_setxattr(struct xdr_stream *xdr,
428 struct nfs4_change_info *cinfo)
432 status = decode_op_hdr(xdr, OP_SETXATTR);
435 status = decode_change_info(xdr, cinfo);
441 static void encode_getxattr(struct xdr_stream *xdr, const char *name,
442 struct compound_hdr *hdr)
444 encode_op_hdr(xdr, OP_GETXATTR, decode_getxattr_maxsz, hdr);
445 encode_string(xdr, strlen(name), name);
448 static int decode_getxattr(struct xdr_stream *xdr,
449 struct nfs42_getxattrres *res,
450 struct rpc_rqst *req)
456 status = decode_op_hdr(xdr, OP_GETXATTR);
460 p = xdr_inline_decode(xdr, 4);
464 len = be32_to_cpup(p);
465 if (len > req->rq_rcv_buf.page_len)
468 res->xattr_len = len;
471 rdlen = xdr_read_pages(xdr, len);
479 static void encode_removexattr(struct xdr_stream *xdr, const char *name,
480 struct compound_hdr *hdr)
482 encode_op_hdr(xdr, OP_REMOVEXATTR, decode_removexattr_maxsz, hdr);
483 encode_string(xdr, strlen(name), name);
487 static int decode_removexattr(struct xdr_stream *xdr,
488 struct nfs4_change_info *cinfo)
492 status = decode_op_hdr(xdr, OP_REMOVEXATTR);
496 status = decode_change_info(xdr, cinfo);
501 static void encode_listxattrs(struct xdr_stream *xdr,
502 const struct nfs42_listxattrsargs *arg,
503 struct compound_hdr *hdr)
507 encode_op_hdr(xdr, OP_LISTXATTRS, decode_listxattrs_maxsz + 1, hdr);
509 p = reserve_space(xdr, 12);
513 p = xdr_encode_hyper(p, arg->cookie);
515 * RFC 8276 says to specify the full max length of the LISTXATTRS
516 * XDR reply. Count is set to the XDR length of the names array
517 * plus the EOF marker. So, add the cookie and the names count.
519 *p = cpu_to_be32(arg->count + 8 + 4);
522 static int decode_listxattrs(struct xdr_stream *xdr,
523 struct nfs42_listxattrsres *res)
527 u32 count, len, ulen;
531 status = decode_op_hdr(xdr, OP_LISTXATTRS);
534 * Special case: for LISTXATTRS, NFS4ERR_TOOSMALL
535 * should be translated to ERANGE.
537 if (status == -ETOOSMALL)
542 p = xdr_inline_decode(xdr, 8);
546 xdr_decode_hyper(p, &res->cookie);
548 p = xdr_inline_decode(xdr, 4);
552 left = res->xattr_len;
553 buf = res->xattr_buf;
555 count = be32_to_cpup(p);
559 * We have asked for enough room to encode the maximum number
560 * of possible attribute names, so everything should fit.
562 * But, don't rely on that assumption. Just decode entries
563 * until they don't fit anymore, just in case the server did
567 p = xdr_inline_decode(xdr, 4);
571 len = be32_to_cpup(p);
572 if (len > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) {
577 p = xdr_inline_decode(xdr, len);
581 ulen = len + XATTR_USER_PREFIX_LEN + 1;
588 memcpy(buf, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
589 memcpy(buf + XATTR_USER_PREFIX_LEN, p, len);
598 p = xdr_inline_decode(xdr, 4);
602 res->eof = be32_to_cpup(p);
603 res->copied = copied;
606 if (status == -ERANGE && res->xattr_len == XATTR_LIST_MAX)
613 * Encode ALLOCATE request
615 static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
616 struct xdr_stream *xdr,
619 const struct nfs42_falloc_args *args = data;
620 struct compound_hdr hdr = {
621 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
624 encode_compound_hdr(xdr, req, &hdr);
625 encode_sequence(xdr, &args->seq_args, &hdr);
626 encode_putfh(xdr, args->falloc_fh, &hdr);
627 encode_allocate(xdr, args, &hdr);
628 encode_getfattr(xdr, args->falloc_bitmask, &hdr);
632 static void encode_copy_commit(struct xdr_stream *xdr,
633 const struct nfs42_copy_args *args,
634 struct compound_hdr *hdr)
638 encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr);
639 p = reserve_space(xdr, 12);
640 p = xdr_encode_hyper(p, args->dst_pos);
641 *p = cpu_to_be32(args->count);
645 * Encode COPY request
647 static void nfs4_xdr_enc_copy(struct rpc_rqst *req,
648 struct xdr_stream *xdr,
651 const struct nfs42_copy_args *args = data;
652 struct compound_hdr hdr = {
653 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
656 encode_compound_hdr(xdr, req, &hdr);
657 encode_sequence(xdr, &args->seq_args, &hdr);
658 encode_putfh(xdr, args->src_fh, &hdr);
659 encode_savefh(xdr, &hdr);
660 encode_putfh(xdr, args->dst_fh, &hdr);
661 encode_copy(xdr, args, &hdr);
663 encode_copy_commit(xdr, args, &hdr);
668 * Encode OFFLOAD_CANEL request
670 static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req,
671 struct xdr_stream *xdr,
674 const struct nfs42_offload_status_args *args = data;
675 struct compound_hdr hdr = {
676 .minorversion = nfs4_xdr_minorversion(&args->osa_seq_args),
679 encode_compound_hdr(xdr, req, &hdr);
680 encode_sequence(xdr, &args->osa_seq_args, &hdr);
681 encode_putfh(xdr, args->osa_src_fh, &hdr);
682 encode_offload_cancel(xdr, args, &hdr);
687 * Encode COPY_NOTIFY request
689 static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req,
690 struct xdr_stream *xdr,
693 const struct nfs42_copy_notify_args *args = data;
694 struct compound_hdr hdr = {
695 .minorversion = nfs4_xdr_minorversion(&args->cna_seq_args),
698 encode_compound_hdr(xdr, req, &hdr);
699 encode_sequence(xdr, &args->cna_seq_args, &hdr);
700 encode_putfh(xdr, args->cna_src_fh, &hdr);
701 encode_copy_notify(xdr, args, &hdr);
706 * Encode DEALLOCATE request
708 static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
709 struct xdr_stream *xdr,
712 const struct nfs42_falloc_args *args = data;
713 struct compound_hdr hdr = {
714 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
717 encode_compound_hdr(xdr, req, &hdr);
718 encode_sequence(xdr, &args->seq_args, &hdr);
719 encode_putfh(xdr, args->falloc_fh, &hdr);
720 encode_deallocate(xdr, args, &hdr);
721 encode_getfattr(xdr, args->falloc_bitmask, &hdr);
726 * Encode SEEK request
728 static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
729 struct xdr_stream *xdr,
732 const struct nfs42_seek_args *args = data;
733 struct compound_hdr hdr = {
734 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
737 encode_compound_hdr(xdr, req, &hdr);
738 encode_sequence(xdr, &args->seq_args, &hdr);
739 encode_putfh(xdr, args->sa_fh, &hdr);
740 encode_seek(xdr, args, &hdr);
745 * Encode LAYOUTSTATS request
747 static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req,
748 struct xdr_stream *xdr,
751 const struct nfs42_layoutstat_args *args = data;
754 struct compound_hdr hdr = {
755 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
758 encode_compound_hdr(xdr, req, &hdr);
759 encode_sequence(xdr, &args->seq_args, &hdr);
760 encode_putfh(xdr, args->fh, &hdr);
761 WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
762 for (i = 0; i < args->num_dev; i++)
763 encode_layoutstats(xdr, args, &args->devinfo[i], &hdr);
768 * Encode CLONE request
770 static void nfs4_xdr_enc_clone(struct rpc_rqst *req,
771 struct xdr_stream *xdr,
774 const struct nfs42_clone_args *args = data;
775 struct compound_hdr hdr = {
776 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
779 encode_compound_hdr(xdr, req, &hdr);
780 encode_sequence(xdr, &args->seq_args, &hdr);
781 encode_putfh(xdr, args->src_fh, &hdr);
782 encode_savefh(xdr, &hdr);
783 encode_putfh(xdr, args->dst_fh, &hdr);
784 encode_clone(xdr, args, &hdr);
785 encode_getfattr(xdr, args->dst_bitmask, &hdr);
790 * Encode LAYOUTERROR request
792 static void nfs4_xdr_enc_layouterror(struct rpc_rqst *req,
793 struct xdr_stream *xdr,
796 const struct nfs42_layouterror_args *args = data;
797 struct compound_hdr hdr = {
798 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
802 encode_compound_hdr(xdr, req, &hdr);
803 encode_sequence(xdr, &args->seq_args, &hdr);
804 encode_putfh(xdr, NFS_FH(args->inode), &hdr);
805 for (i = 0; i < args->num_errors; i++)
806 encode_layouterror(xdr, &args->errors[i], &hdr);
810 static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
812 return decode_op_hdr(xdr, OP_ALLOCATE);
815 static int decode_write_response(struct xdr_stream *xdr,
816 struct nfs42_write_res *res)
821 p = xdr_inline_decode(xdr, 4);
824 count = be32_to_cpup(p);
827 else if (count == 1) {
828 status = decode_opaque_fixed(xdr, &res->stateid,
830 if (unlikely(status))
833 p = xdr_inline_decode(xdr, 8 + 4);
836 p = xdr_decode_hyper(p, &res->count);
837 res->verifier.committed = be32_to_cpup(p);
838 return decode_verifier(xdr, &res->verifier.verifier);
841 static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns)
843 struct nfs42_netaddr *naddr;
850 p = xdr_inline_decode(xdr, 4);
853 ns->nl4_type = be32_to_cpup(p);
854 switch (ns->nl4_type) {
857 status = decode_opaque_inline(xdr, &dummy, &dummy_str);
858 if (unlikely(status))
860 if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
862 memcpy(&ns->u.nl4_str, dummy_str, dummy);
863 ns->u.nl4_str_sz = dummy;
866 naddr = &ns->u.nl4_addr;
869 status = decode_opaque_inline(xdr, &dummy, &dummy_str);
870 if (unlikely(status))
872 if (unlikely(dummy > RPCBIND_MAXNETIDLEN))
874 naddr->netid_len = dummy;
875 memcpy(naddr->netid, dummy_str, naddr->netid_len);
878 status = decode_opaque_inline(xdr, &dummy, &dummy_str);
879 if (unlikely(status))
881 if (unlikely(dummy > RPCBIND_MAXUADDRLEN))
883 naddr->addr_len = dummy;
884 memcpy(naddr->addr, dummy_str, naddr->addr_len);
893 static int decode_copy_requirements(struct xdr_stream *xdr,
894 struct nfs42_copy_res *res) {
897 p = xdr_inline_decode(xdr, 4 + 4);
901 res->consecutive = be32_to_cpup(p++);
902 res->synchronous = be32_to_cpup(p++);
906 static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res)
910 status = decode_op_hdr(xdr, OP_COPY);
911 if (status == NFS4ERR_OFFLOAD_NO_REQS) {
912 status = decode_copy_requirements(xdr, res);
915 return NFS4ERR_OFFLOAD_NO_REQS;
919 status = decode_write_response(xdr, &res->write_res);
923 return decode_copy_requirements(xdr, res);
926 static int decode_offload_cancel(struct xdr_stream *xdr,
927 struct nfs42_offload_status_res *res)
929 return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);
932 static int decode_copy_notify(struct xdr_stream *xdr,
933 struct nfs42_copy_notify_res *res)
938 status = decode_op_hdr(xdr, OP_COPY_NOTIFY);
942 p = xdr_inline_decode(xdr, 12);
945 p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds);
946 res->cnr_lease_time.nseconds = be32_to_cpup(p);
948 status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE);
949 if (unlikely(status))
952 /* number of source addresses */
953 p = xdr_inline_decode(xdr, 4);
957 count = be32_to_cpup(p);
959 pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n",
962 status = decode_nl4_server(xdr, &res->cnr_src);
963 if (unlikely(status))
968 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
970 return decode_op_hdr(xdr, OP_DEALLOCATE);
973 static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
978 status = decode_op_hdr(xdr, OP_SEEK);
982 p = xdr_inline_decode(xdr, 4 + 8);
986 res->sr_eof = be32_to_cpup(p++);
987 p = xdr_decode_hyper(p, &res->sr_offset);
991 static int decode_layoutstats(struct xdr_stream *xdr)
993 return decode_op_hdr(xdr, OP_LAYOUTSTATS);
996 static int decode_clone(struct xdr_stream *xdr)
998 return decode_op_hdr(xdr, OP_CLONE);
1001 static int decode_layouterror(struct xdr_stream *xdr)
1003 return decode_op_hdr(xdr, OP_LAYOUTERROR);
1007 * Decode ALLOCATE request
1009 static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
1010 struct xdr_stream *xdr,
1013 struct nfs42_falloc_res *res = data;
1014 struct compound_hdr hdr;
1017 status = decode_compound_hdr(xdr, &hdr);
1020 status = decode_sequence(xdr, &res->seq_res, rqstp);
1023 status = decode_putfh(xdr);
1026 status = decode_allocate(xdr, res);
1029 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
1035 * Decode COPY response
1037 static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp,
1038 struct xdr_stream *xdr,
1041 struct nfs42_copy_res *res = data;
1042 struct compound_hdr hdr;
1045 status = decode_compound_hdr(xdr, &hdr);
1048 status = decode_sequence(xdr, &res->seq_res, rqstp);
1051 status = decode_putfh(xdr);
1054 status = decode_savefh(xdr);
1057 status = decode_putfh(xdr);
1060 status = decode_copy(xdr, res);
1063 if (res->commit_res.verf)
1064 status = decode_commit(xdr, &res->commit_res);
1070 * Decode OFFLOAD_CANCEL response
1072 static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp,
1073 struct xdr_stream *xdr,
1076 struct nfs42_offload_status_res *res = data;
1077 struct compound_hdr hdr;
1080 status = decode_compound_hdr(xdr, &hdr);
1083 status = decode_sequence(xdr, &res->osr_seq_res, rqstp);
1086 status = decode_putfh(xdr);
1089 status = decode_offload_cancel(xdr, res);
1096 * Decode COPY_NOTIFY response
1098 static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp,
1099 struct xdr_stream *xdr,
1102 struct nfs42_copy_notify_res *res = data;
1103 struct compound_hdr hdr;
1106 status = decode_compound_hdr(xdr, &hdr);
1109 status = decode_sequence(xdr, &res->cnr_seq_res, rqstp);
1112 status = decode_putfh(xdr);
1115 status = decode_copy_notify(xdr, res);
1122 * Decode DEALLOCATE request
1124 static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
1125 struct xdr_stream *xdr,
1128 struct nfs42_falloc_res *res = data;
1129 struct compound_hdr hdr;
1132 status = decode_compound_hdr(xdr, &hdr);
1135 status = decode_sequence(xdr, &res->seq_res, rqstp);
1138 status = decode_putfh(xdr);
1141 status = decode_deallocate(xdr, res);
1144 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
1150 * Decode SEEK request
1152 static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
1153 struct xdr_stream *xdr,
1156 struct nfs42_seek_res *res = data;
1157 struct compound_hdr hdr;
1160 status = decode_compound_hdr(xdr, &hdr);
1163 status = decode_sequence(xdr, &res->seq_res, rqstp);
1166 status = decode_putfh(xdr);
1169 status = decode_seek(xdr, res);
1175 * Decode LAYOUTSTATS request
1177 static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp,
1178 struct xdr_stream *xdr,
1181 struct nfs42_layoutstat_res *res = data;
1182 struct compound_hdr hdr;
1185 status = decode_compound_hdr(xdr, &hdr);
1188 status = decode_sequence(xdr, &res->seq_res, rqstp);
1191 status = decode_putfh(xdr);
1194 WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
1195 for (i = 0; i < res->num_dev; i++) {
1196 status = decode_layoutstats(xdr);
1201 res->rpc_status = status;
1206 * Decode CLONE request
1208 static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp,
1209 struct xdr_stream *xdr,
1212 struct nfs42_clone_res *res = data;
1213 struct compound_hdr hdr;
1216 status = decode_compound_hdr(xdr, &hdr);
1219 status = decode_sequence(xdr, &res->seq_res, rqstp);
1222 status = decode_putfh(xdr);
1225 status = decode_savefh(xdr);
1228 status = decode_putfh(xdr);
1231 status = decode_clone(xdr);
1234 status = decode_getfattr(xdr, res->dst_fattr, res->server);
1237 res->rpc_status = status;
1242 * Decode LAYOUTERROR request
1244 static int nfs4_xdr_dec_layouterror(struct rpc_rqst *rqstp,
1245 struct xdr_stream *xdr,
1248 struct nfs42_layouterror_res *res = data;
1249 struct compound_hdr hdr;
1252 status = decode_compound_hdr(xdr, &hdr);
1255 status = decode_sequence(xdr, &res->seq_res, rqstp);
1258 status = decode_putfh(xdr);
1260 for (i = 0; i < res->num_errors && status == 0; i++)
1261 status = decode_layouterror(xdr);
1263 res->rpc_status = status;
1267 #ifdef CONFIG_NFS_V4_2
1268 static void nfs4_xdr_enc_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
1271 const struct nfs42_setxattrargs *args = data;
1272 struct compound_hdr hdr = {
1273 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1276 encode_compound_hdr(xdr, req, &hdr);
1277 encode_sequence(xdr, &args->seq_args, &hdr);
1278 encode_putfh(xdr, args->fh, &hdr);
1279 encode_setxattr(xdr, args, &hdr);
1283 static int nfs4_xdr_dec_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
1286 struct nfs42_setxattrres *res = data;
1287 struct compound_hdr hdr;
1290 status = decode_compound_hdr(xdr, &hdr);
1293 status = decode_sequence(xdr, &res->seq_res, req);
1296 status = decode_putfh(xdr);
1300 status = decode_setxattr(xdr, &res->cinfo);
1305 static void nfs4_xdr_enc_getxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
1308 const struct nfs42_getxattrargs *args = data;
1309 struct compound_hdr hdr = {
1310 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1314 encode_compound_hdr(xdr, req, &hdr);
1315 encode_sequence(xdr, &args->seq_args, &hdr);
1316 encode_putfh(xdr, args->fh, &hdr);
1317 encode_getxattr(xdr, args->xattr_name, &hdr);
1319 plen = args->xattr_len ? args->xattr_len : XATTR_SIZE_MAX;
1321 rpc_prepare_reply_pages(req, args->xattr_pages, 0, plen,
1323 req->rq_rcv_buf.flags |= XDRBUF_SPARSE_PAGES;
1328 static int nfs4_xdr_dec_getxattr(struct rpc_rqst *rqstp,
1329 struct xdr_stream *xdr, void *data)
1331 struct nfs42_getxattrres *res = data;
1332 struct compound_hdr hdr;
1335 status = decode_compound_hdr(xdr, &hdr);
1338 status = decode_sequence(xdr, &res->seq_res, rqstp);
1341 status = decode_putfh(xdr);
1344 status = decode_getxattr(xdr, res, rqstp);
1349 static void nfs4_xdr_enc_listxattrs(struct rpc_rqst *req,
1350 struct xdr_stream *xdr, const void *data)
1352 const struct nfs42_listxattrsargs *args = data;
1353 struct compound_hdr hdr = {
1354 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1357 encode_compound_hdr(xdr, req, &hdr);
1358 encode_sequence(xdr, &args->seq_args, &hdr);
1359 encode_putfh(xdr, args->fh, &hdr);
1360 encode_listxattrs(xdr, args, &hdr);
1362 rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->count,
1364 req->rq_rcv_buf.flags |= XDRBUF_SPARSE_PAGES;
1369 static int nfs4_xdr_dec_listxattrs(struct rpc_rqst *rqstp,
1370 struct xdr_stream *xdr, void *data)
1372 struct nfs42_listxattrsres *res = data;
1373 struct compound_hdr hdr;
1376 xdr_set_scratch_buffer(xdr, page_address(res->scratch), PAGE_SIZE);
1378 status = decode_compound_hdr(xdr, &hdr);
1381 status = decode_sequence(xdr, &res->seq_res, rqstp);
1384 status = decode_putfh(xdr);
1387 status = decode_listxattrs(xdr, res);
1392 static void nfs4_xdr_enc_removexattr(struct rpc_rqst *req,
1393 struct xdr_stream *xdr, const void *data)
1395 const struct nfs42_removexattrargs *args = data;
1396 struct compound_hdr hdr = {
1397 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1400 encode_compound_hdr(xdr, req, &hdr);
1401 encode_sequence(xdr, &args->seq_args, &hdr);
1402 encode_putfh(xdr, args->fh, &hdr);
1403 encode_removexattr(xdr, args->xattr_name, &hdr);
1407 static int nfs4_xdr_dec_removexattr(struct rpc_rqst *req,
1408 struct xdr_stream *xdr, void *data)
1410 struct nfs42_removexattrres *res = data;
1411 struct compound_hdr hdr;
1414 status = decode_compound_hdr(xdr, &hdr);
1417 status = decode_sequence(xdr, &res->seq_res, req);
1420 status = decode_putfh(xdr);
1424 status = decode_removexattr(xdr, &res->cinfo);
1429 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */