1 // SPDX-License-Identifier: GPL-2.0
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_read_plus_maxsz (op_encode_hdr_maxsz + \
49 encode_stateid_maxsz + 3)
50 #define NFS42_READ_PLUS_DATA_SEGMENT_SIZE \
51 (1 /* data_content4 */ + \
52 2 /* data_info4.di_offset */ + \
53 1 /* data_info4.di_length */)
54 #define decode_read_plus_maxsz (op_decode_hdr_maxsz + \
56 1 /* rpr_contents count */ + \
57 NFS42_READ_PLUS_DATA_SEGMENT_SIZE)
58 #define encode_seek_maxsz (op_encode_hdr_maxsz + \
59 encode_stateid_maxsz + \
62 #define decode_seek_maxsz (op_decode_hdr_maxsz + \
67 #define encode_io_info_maxsz 4
68 #define encode_layoutstats_maxsz (op_decode_hdr_maxsz + \
71 encode_stateid_maxsz + \
72 encode_io_info_maxsz + \
73 encode_io_info_maxsz + \
74 1 /* opaque devaddr4 length */ + \
75 XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE))
76 #define decode_layoutstats_maxsz (op_decode_hdr_maxsz)
77 #define encode_device_error_maxsz (XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \
78 1 /* status */ + 1 /* opnum */)
79 #define encode_layouterror_maxsz (op_decode_hdr_maxsz + \
82 encode_stateid_maxsz + \
83 1 /* Array size */ + \
84 encode_device_error_maxsz)
85 #define decode_layouterror_maxsz (op_decode_hdr_maxsz)
86 #define encode_clone_maxsz (encode_stateid_maxsz + \
87 encode_stateid_maxsz + \
88 2 /* src offset */ + \
89 2 /* dst offset */ + \
91 #define decode_clone_maxsz (op_decode_hdr_maxsz)
93 #define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \
94 encode_sequence_maxsz + \
95 encode_putfh_maxsz + \
96 encode_allocate_maxsz + \
98 #define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \
99 decode_sequence_maxsz + \
100 decode_putfh_maxsz + \
101 decode_allocate_maxsz + \
102 decode_getattr_maxsz)
103 #define NFS4_enc_copy_sz (compound_encode_hdr_maxsz + \
104 encode_sequence_maxsz + \
105 encode_putfh_maxsz + \
106 encode_savefh_maxsz + \
107 encode_putfh_maxsz + \
108 encode_copy_maxsz + \
110 #define NFS4_dec_copy_sz (compound_decode_hdr_maxsz + \
111 decode_sequence_maxsz + \
112 decode_putfh_maxsz + \
113 decode_savefh_maxsz + \
114 decode_putfh_maxsz + \
115 decode_copy_maxsz + \
117 #define NFS4_enc_offload_cancel_sz (compound_encode_hdr_maxsz + \
118 encode_sequence_maxsz + \
119 encode_putfh_maxsz + \
120 encode_offload_cancel_maxsz)
121 #define NFS4_dec_offload_cancel_sz (compound_decode_hdr_maxsz + \
122 decode_sequence_maxsz + \
123 decode_putfh_maxsz + \
124 decode_offload_cancel_maxsz)
125 #define NFS4_enc_copy_notify_sz (compound_encode_hdr_maxsz + \
126 encode_putfh_maxsz + \
127 encode_copy_notify_maxsz)
128 #define NFS4_dec_copy_notify_sz (compound_decode_hdr_maxsz + \
129 decode_putfh_maxsz + \
130 decode_copy_notify_maxsz)
131 #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \
132 encode_sequence_maxsz + \
133 encode_putfh_maxsz + \
134 encode_deallocate_maxsz + \
135 encode_getattr_maxsz)
136 #define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \
137 decode_sequence_maxsz + \
138 decode_putfh_maxsz + \
139 decode_deallocate_maxsz + \
140 decode_getattr_maxsz)
141 #define NFS4_enc_read_plus_sz (compound_encode_hdr_maxsz + \
142 encode_sequence_maxsz + \
143 encode_putfh_maxsz + \
144 encode_read_plus_maxsz)
145 #define NFS4_dec_read_plus_sz (compound_decode_hdr_maxsz + \
146 decode_sequence_maxsz + \
147 decode_putfh_maxsz + \
148 decode_read_plus_maxsz)
149 #define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \
150 encode_sequence_maxsz + \
151 encode_putfh_maxsz + \
153 #define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \
154 decode_sequence_maxsz + \
155 decode_putfh_maxsz + \
157 #define NFS4_enc_layoutstats_sz (compound_encode_hdr_maxsz + \
158 encode_sequence_maxsz + \
159 encode_putfh_maxsz + \
160 PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz)
161 #define NFS4_dec_layoutstats_sz (compound_decode_hdr_maxsz + \
162 decode_sequence_maxsz + \
163 decode_putfh_maxsz + \
164 PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz)
165 #define NFS4_enc_layouterror_sz (compound_encode_hdr_maxsz + \
166 encode_sequence_maxsz + \
167 encode_putfh_maxsz + \
168 NFS42_LAYOUTERROR_MAX * \
169 encode_layouterror_maxsz)
170 #define NFS4_dec_layouterror_sz (compound_decode_hdr_maxsz + \
171 decode_sequence_maxsz + \
172 decode_putfh_maxsz + \
173 NFS42_LAYOUTERROR_MAX * \
174 decode_layouterror_maxsz)
175 #define NFS4_enc_clone_sz (compound_encode_hdr_maxsz + \
176 encode_sequence_maxsz + \
177 encode_putfh_maxsz + \
178 encode_savefh_maxsz + \
179 encode_putfh_maxsz + \
180 encode_clone_maxsz + \
181 encode_getattr_maxsz)
182 #define NFS4_dec_clone_sz (compound_decode_hdr_maxsz + \
183 decode_sequence_maxsz + \
184 decode_putfh_maxsz + \
185 decode_savefh_maxsz + \
186 decode_putfh_maxsz + \
187 decode_clone_maxsz + \
188 decode_getattr_maxsz)
190 /* Not limited by NFS itself, limited by the generic xattr code */
191 #define nfs4_xattr_name_maxsz XDR_QUADLEN(XATTR_NAME_MAX)
193 #define encode_getxattr_maxsz (op_encode_hdr_maxsz + 1 + \
194 nfs4_xattr_name_maxsz)
195 #define decode_getxattr_maxsz (op_decode_hdr_maxsz + 1 + pagepad_maxsz)
196 #define encode_setxattr_maxsz (op_encode_hdr_maxsz + \
197 1 + nfs4_xattr_name_maxsz + 1)
198 #define decode_setxattr_maxsz (op_decode_hdr_maxsz + decode_change_info_maxsz)
199 #define encode_listxattrs_maxsz (op_encode_hdr_maxsz + 2 + 1)
200 #define decode_listxattrs_maxsz (op_decode_hdr_maxsz + 2 + 1 + 1 + 1)
201 #define encode_removexattr_maxsz (op_encode_hdr_maxsz + 1 + \
202 nfs4_xattr_name_maxsz)
203 #define decode_removexattr_maxsz (op_decode_hdr_maxsz + \
204 decode_change_info_maxsz)
206 #define NFS4_enc_getxattr_sz (compound_encode_hdr_maxsz + \
207 encode_sequence_maxsz + \
208 encode_putfh_maxsz + \
209 encode_getxattr_maxsz)
210 #define NFS4_dec_getxattr_sz (compound_decode_hdr_maxsz + \
211 decode_sequence_maxsz + \
212 decode_putfh_maxsz + \
213 decode_getxattr_maxsz)
214 #define NFS4_enc_setxattr_sz (compound_encode_hdr_maxsz + \
215 encode_sequence_maxsz + \
216 encode_putfh_maxsz + \
217 encode_setxattr_maxsz)
218 #define NFS4_dec_setxattr_sz (compound_decode_hdr_maxsz + \
219 decode_sequence_maxsz + \
220 decode_putfh_maxsz + \
221 decode_setxattr_maxsz)
222 #define NFS4_enc_listxattrs_sz (compound_encode_hdr_maxsz + \
223 encode_sequence_maxsz + \
224 encode_putfh_maxsz + \
225 encode_listxattrs_maxsz)
226 #define NFS4_dec_listxattrs_sz (compound_decode_hdr_maxsz + \
227 decode_sequence_maxsz + \
228 decode_putfh_maxsz + \
229 decode_listxattrs_maxsz)
230 #define NFS4_enc_removexattr_sz (compound_encode_hdr_maxsz + \
231 encode_sequence_maxsz + \
232 encode_putfh_maxsz + \
233 encode_removexattr_maxsz)
234 #define NFS4_dec_removexattr_sz (compound_decode_hdr_maxsz + \
235 decode_sequence_maxsz + \
236 decode_putfh_maxsz + \
237 decode_removexattr_maxsz)
240 * These values specify the maximum amount of data that is not
241 * associated with the extended attribute name or extended
242 * attribute list in the SETXATTR, GETXATTR and LISTXATTR
245 const u32 nfs42_maxsetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
246 compound_encode_hdr_maxsz +
247 encode_sequence_maxsz +
248 encode_putfh_maxsz + 1 +
249 nfs4_xattr_name_maxsz)
252 const u32 nfs42_maxgetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
253 compound_decode_hdr_maxsz +
254 decode_sequence_maxsz +
255 decode_putfh_maxsz + 1) * XDR_UNIT);
257 const u32 nfs42_maxlistxattrs_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
258 compound_decode_hdr_maxsz +
259 decode_sequence_maxsz +
260 decode_putfh_maxsz + 3) * XDR_UNIT);
262 static void encode_fallocate(struct xdr_stream *xdr,
263 const struct nfs42_falloc_args *args)
265 encode_nfs4_stateid(xdr, &args->falloc_stateid);
266 encode_uint64(xdr, args->falloc_offset);
267 encode_uint64(xdr, args->falloc_length);
270 static void encode_allocate(struct xdr_stream *xdr,
271 const struct nfs42_falloc_args *args,
272 struct compound_hdr *hdr)
274 encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
275 encode_fallocate(xdr, args);
278 static void encode_nl4_server(struct xdr_stream *xdr,
279 const struct nl4_server *ns)
281 encode_uint32(xdr, ns->nl4_type);
282 switch (ns->nl4_type) {
285 encode_string(xdr, ns->u.nl4_str_sz, ns->u.nl4_str);
288 encode_string(xdr, ns->u.nl4_addr.netid_len,
289 ns->u.nl4_addr.netid);
290 encode_string(xdr, ns->u.nl4_addr.addr_len,
291 ns->u.nl4_addr.addr);
298 static void encode_copy(struct xdr_stream *xdr,
299 const struct nfs42_copy_args *args,
300 struct compound_hdr *hdr)
302 encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr);
303 encode_nfs4_stateid(xdr, &args->src_stateid);
304 encode_nfs4_stateid(xdr, &args->dst_stateid);
306 encode_uint64(xdr, args->src_pos);
307 encode_uint64(xdr, args->dst_pos);
308 encode_uint64(xdr, args->count);
310 encode_uint32(xdr, 1); /* consecutive = true */
311 encode_uint32(xdr, args->sync);
312 if (args->cp_src == NULL) { /* intra-ssc */
313 encode_uint32(xdr, 0); /* no src server list */
316 encode_uint32(xdr, 1); /* supporting 1 server */
317 encode_nl4_server(xdr, args->cp_src);
320 static void encode_offload_cancel(struct xdr_stream *xdr,
321 const struct nfs42_offload_status_args *args,
322 struct compound_hdr *hdr)
324 encode_op_hdr(xdr, OP_OFFLOAD_CANCEL, decode_offload_cancel_maxsz, hdr);
325 encode_nfs4_stateid(xdr, &args->osa_stateid);
328 static void encode_copy_notify(struct xdr_stream *xdr,
329 const struct nfs42_copy_notify_args *args,
330 struct compound_hdr *hdr)
332 encode_op_hdr(xdr, OP_COPY_NOTIFY, decode_copy_notify_maxsz, hdr);
333 encode_nfs4_stateid(xdr, &args->cna_src_stateid);
334 encode_nl4_server(xdr, &args->cna_dst);
337 static void encode_deallocate(struct xdr_stream *xdr,
338 const struct nfs42_falloc_args *args,
339 struct compound_hdr *hdr)
341 encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
342 encode_fallocate(xdr, args);
345 static void encode_read_plus(struct xdr_stream *xdr,
346 const struct nfs_pgio_args *args,
347 struct compound_hdr *hdr)
349 encode_op_hdr(xdr, OP_READ_PLUS, decode_read_plus_maxsz, hdr);
350 encode_nfs4_stateid(xdr, &args->stateid);
351 encode_uint64(xdr, args->offset);
352 encode_uint32(xdr, args->count);
355 static void encode_seek(struct xdr_stream *xdr,
356 const struct nfs42_seek_args *args,
357 struct compound_hdr *hdr)
359 encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr);
360 encode_nfs4_stateid(xdr, &args->sa_stateid);
361 encode_uint64(xdr, args->sa_offset);
362 encode_uint32(xdr, args->sa_what);
365 static void encode_layoutstats(struct xdr_stream *xdr,
366 const struct nfs42_layoutstat_args *args,
367 struct nfs42_layoutstat_devinfo *devinfo,
368 struct compound_hdr *hdr)
372 encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr);
373 p = reserve_space(xdr, 8 + 8);
374 p = xdr_encode_hyper(p, devinfo->offset);
375 p = xdr_encode_hyper(p, devinfo->length);
376 encode_nfs4_stateid(xdr, &args->stateid);
377 p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4);
378 p = xdr_encode_hyper(p, devinfo->read_count);
379 p = xdr_encode_hyper(p, devinfo->read_bytes);
380 p = xdr_encode_hyper(p, devinfo->write_count);
381 p = xdr_encode_hyper(p, devinfo->write_bytes);
382 p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data,
383 NFS4_DEVICEID4_SIZE);
384 /* Encode layoutupdate4 */
385 *p++ = cpu_to_be32(devinfo->layout_type);
386 if (devinfo->ld_private.ops)
387 devinfo->ld_private.ops->encode(xdr, args,
388 &devinfo->ld_private);
390 encode_uint32(xdr, 0);
393 static void encode_clone(struct xdr_stream *xdr,
394 const struct nfs42_clone_args *args,
395 struct compound_hdr *hdr)
399 encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr);
400 encode_nfs4_stateid(xdr, &args->src_stateid);
401 encode_nfs4_stateid(xdr, &args->dst_stateid);
402 p = reserve_space(xdr, 3*8);
403 p = xdr_encode_hyper(p, args->src_offset);
404 p = xdr_encode_hyper(p, args->dst_offset);
405 xdr_encode_hyper(p, args->count);
408 static void encode_device_error(struct xdr_stream *xdr,
409 const struct nfs42_device_error *error)
413 p = reserve_space(xdr, NFS4_DEVICEID4_SIZE + 2*4);
414 p = xdr_encode_opaque_fixed(p, error->dev_id.data,
415 NFS4_DEVICEID4_SIZE);
416 *p++ = cpu_to_be32(error->status);
417 *p = cpu_to_be32(error->opnum);
420 static void encode_layouterror(struct xdr_stream *xdr,
421 const struct nfs42_layout_error *args,
422 struct compound_hdr *hdr)
426 encode_op_hdr(xdr, OP_LAYOUTERROR, decode_layouterror_maxsz, hdr);
427 p = reserve_space(xdr, 8 + 8);
428 p = xdr_encode_hyper(p, args->offset);
429 p = xdr_encode_hyper(p, args->length);
430 encode_nfs4_stateid(xdr, &args->stateid);
431 p = reserve_space(xdr, 4);
433 encode_device_error(xdr, &args->errors[0]);
436 static void encode_setxattr(struct xdr_stream *xdr,
437 const struct nfs42_setxattrargs *arg,
438 struct compound_hdr *hdr)
442 BUILD_BUG_ON(XATTR_CREATE != SETXATTR4_CREATE);
443 BUILD_BUG_ON(XATTR_REPLACE != SETXATTR4_REPLACE);
445 encode_op_hdr(xdr, OP_SETXATTR, decode_setxattr_maxsz, hdr);
446 p = reserve_space(xdr, 4);
447 *p = cpu_to_be32(arg->xattr_flags);
448 encode_string(xdr, strlen(arg->xattr_name), arg->xattr_name);
449 p = reserve_space(xdr, 4);
450 *p = cpu_to_be32(arg->xattr_len);
452 xdr_write_pages(xdr, arg->xattr_pages, 0, arg->xattr_len);
455 static int decode_setxattr(struct xdr_stream *xdr,
456 struct nfs4_change_info *cinfo)
460 status = decode_op_hdr(xdr, OP_SETXATTR);
463 status = decode_change_info(xdr, cinfo);
469 static void encode_getxattr(struct xdr_stream *xdr, const char *name,
470 struct compound_hdr *hdr)
472 encode_op_hdr(xdr, OP_GETXATTR, decode_getxattr_maxsz, hdr);
473 encode_string(xdr, strlen(name), name);
476 static int decode_getxattr(struct xdr_stream *xdr,
477 struct nfs42_getxattrres *res,
478 struct rpc_rqst *req)
484 status = decode_op_hdr(xdr, OP_GETXATTR);
488 p = xdr_inline_decode(xdr, 4);
492 len = be32_to_cpup(p);
495 * Only check against the page length here. The actual
496 * requested length may be smaller, but that is only
497 * checked against after possibly caching a valid reply.
499 if (len > req->rq_rcv_buf.page_len)
502 res->xattr_len = len;
505 rdlen = xdr_read_pages(xdr, len);
513 static void encode_removexattr(struct xdr_stream *xdr, const char *name,
514 struct compound_hdr *hdr)
516 encode_op_hdr(xdr, OP_REMOVEXATTR, decode_removexattr_maxsz, hdr);
517 encode_string(xdr, strlen(name), name);
521 static int decode_removexattr(struct xdr_stream *xdr,
522 struct nfs4_change_info *cinfo)
526 status = decode_op_hdr(xdr, OP_REMOVEXATTR);
530 status = decode_change_info(xdr, cinfo);
535 static void encode_listxattrs(struct xdr_stream *xdr,
536 const struct nfs42_listxattrsargs *arg,
537 struct compound_hdr *hdr)
541 encode_op_hdr(xdr, OP_LISTXATTRS, decode_listxattrs_maxsz, hdr);
543 p = reserve_space(xdr, 12);
547 p = xdr_encode_hyper(p, arg->cookie);
549 * RFC 8276 says to specify the full max length of the LISTXATTRS
550 * XDR reply. Count is set to the XDR length of the names array
551 * plus the EOF marker. So, add the cookie and the names count.
553 *p = cpu_to_be32(arg->count + 8 + 4);
556 static int decode_listxattrs(struct xdr_stream *xdr,
557 struct nfs42_listxattrsres *res)
561 u32 count, len, ulen;
565 status = decode_op_hdr(xdr, OP_LISTXATTRS);
568 * Special case: for LISTXATTRS, NFS4ERR_TOOSMALL
569 * should be translated to ERANGE.
571 if (status == -ETOOSMALL)
574 * Special case: for LISTXATTRS, NFS4ERR_NOXATTR
575 * should be translated to success with zero-length reply.
577 if (status == -ENODATA) {
584 p = xdr_inline_decode(xdr, 8);
588 xdr_decode_hyper(p, &res->cookie);
590 p = xdr_inline_decode(xdr, 4);
594 left = res->xattr_len;
595 buf = res->xattr_buf;
597 count = be32_to_cpup(p);
601 * We have asked for enough room to encode the maximum number
602 * of possible attribute names, so everything should fit.
604 * But, don't rely on that assumption. Just decode entries
605 * until they don't fit anymore, just in case the server did
609 p = xdr_inline_decode(xdr, 4);
613 len = be32_to_cpup(p);
614 if (len > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) {
619 p = xdr_inline_decode(xdr, len);
623 ulen = len + XATTR_USER_PREFIX_LEN + 1;
630 memcpy(buf, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
631 memcpy(buf + XATTR_USER_PREFIX_LEN, p, len);
640 p = xdr_inline_decode(xdr, 4);
644 res->eof = be32_to_cpup(p);
645 res->copied = copied;
648 if (status == -ERANGE && res->xattr_len == XATTR_LIST_MAX)
655 * Encode ALLOCATE request
657 static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
658 struct xdr_stream *xdr,
661 const struct nfs42_falloc_args *args = data;
662 struct compound_hdr hdr = {
663 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
666 encode_compound_hdr(xdr, req, &hdr);
667 encode_sequence(xdr, &args->seq_args, &hdr);
668 encode_putfh(xdr, args->falloc_fh, &hdr);
669 encode_allocate(xdr, args, &hdr);
670 encode_getfattr(xdr, args->falloc_bitmask, &hdr);
674 static void encode_copy_commit(struct xdr_stream *xdr,
675 const struct nfs42_copy_args *args,
676 struct compound_hdr *hdr)
680 encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr);
681 p = reserve_space(xdr, 12);
682 p = xdr_encode_hyper(p, args->dst_pos);
683 *p = cpu_to_be32(args->count);
687 * Encode COPY request
689 static void nfs4_xdr_enc_copy(struct rpc_rqst *req,
690 struct xdr_stream *xdr,
693 const struct nfs42_copy_args *args = data;
694 struct compound_hdr hdr = {
695 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
698 encode_compound_hdr(xdr, req, &hdr);
699 encode_sequence(xdr, &args->seq_args, &hdr);
700 encode_putfh(xdr, args->src_fh, &hdr);
701 encode_savefh(xdr, &hdr);
702 encode_putfh(xdr, args->dst_fh, &hdr);
703 encode_copy(xdr, args, &hdr);
705 encode_copy_commit(xdr, args, &hdr);
710 * Encode OFFLOAD_CANEL request
712 static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req,
713 struct xdr_stream *xdr,
716 const struct nfs42_offload_status_args *args = data;
717 struct compound_hdr hdr = {
718 .minorversion = nfs4_xdr_minorversion(&args->osa_seq_args),
721 encode_compound_hdr(xdr, req, &hdr);
722 encode_sequence(xdr, &args->osa_seq_args, &hdr);
723 encode_putfh(xdr, args->osa_src_fh, &hdr);
724 encode_offload_cancel(xdr, args, &hdr);
729 * Encode COPY_NOTIFY request
731 static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req,
732 struct xdr_stream *xdr,
735 const struct nfs42_copy_notify_args *args = data;
736 struct compound_hdr hdr = {
737 .minorversion = nfs4_xdr_minorversion(&args->cna_seq_args),
740 encode_compound_hdr(xdr, req, &hdr);
741 encode_sequence(xdr, &args->cna_seq_args, &hdr);
742 encode_putfh(xdr, args->cna_src_fh, &hdr);
743 encode_copy_notify(xdr, args, &hdr);
748 * Encode DEALLOCATE request
750 static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
751 struct xdr_stream *xdr,
754 const struct nfs42_falloc_args *args = data;
755 struct compound_hdr hdr = {
756 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
759 encode_compound_hdr(xdr, req, &hdr);
760 encode_sequence(xdr, &args->seq_args, &hdr);
761 encode_putfh(xdr, args->falloc_fh, &hdr);
762 encode_deallocate(xdr, args, &hdr);
763 encode_getfattr(xdr, args->falloc_bitmask, &hdr);
768 * Encode READ_PLUS request
770 static void nfs4_xdr_enc_read_plus(struct rpc_rqst *req,
771 struct xdr_stream *xdr,
774 const struct nfs_pgio_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->fh, &hdr);
782 encode_read_plus(xdr, args, &hdr);
784 rpc_prepare_reply_pages(req, args->pages, args->pgbase,
785 args->count, hdr.replen);
790 * Encode SEEK request
792 static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
793 struct xdr_stream *xdr,
796 const struct nfs42_seek_args *args = data;
797 struct compound_hdr hdr = {
798 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
801 encode_compound_hdr(xdr, req, &hdr);
802 encode_sequence(xdr, &args->seq_args, &hdr);
803 encode_putfh(xdr, args->sa_fh, &hdr);
804 encode_seek(xdr, args, &hdr);
809 * Encode LAYOUTSTATS request
811 static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req,
812 struct xdr_stream *xdr,
815 const struct nfs42_layoutstat_args *args = data;
818 struct compound_hdr hdr = {
819 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
822 encode_compound_hdr(xdr, req, &hdr);
823 encode_sequence(xdr, &args->seq_args, &hdr);
824 encode_putfh(xdr, args->fh, &hdr);
825 WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
826 for (i = 0; i < args->num_dev; i++)
827 encode_layoutstats(xdr, args, &args->devinfo[i], &hdr);
832 * Encode CLONE request
834 static void nfs4_xdr_enc_clone(struct rpc_rqst *req,
835 struct xdr_stream *xdr,
838 const struct nfs42_clone_args *args = data;
839 struct compound_hdr hdr = {
840 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
843 encode_compound_hdr(xdr, req, &hdr);
844 encode_sequence(xdr, &args->seq_args, &hdr);
845 encode_putfh(xdr, args->src_fh, &hdr);
846 encode_savefh(xdr, &hdr);
847 encode_putfh(xdr, args->dst_fh, &hdr);
848 encode_clone(xdr, args, &hdr);
849 encode_getfattr(xdr, args->dst_bitmask, &hdr);
854 * Encode LAYOUTERROR request
856 static void nfs4_xdr_enc_layouterror(struct rpc_rqst *req,
857 struct xdr_stream *xdr,
860 const struct nfs42_layouterror_args *args = data;
861 struct compound_hdr hdr = {
862 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
866 encode_compound_hdr(xdr, req, &hdr);
867 encode_sequence(xdr, &args->seq_args, &hdr);
868 encode_putfh(xdr, NFS_FH(args->inode), &hdr);
869 for (i = 0; i < args->num_errors; i++)
870 encode_layouterror(xdr, &args->errors[i], &hdr);
874 static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
876 return decode_op_hdr(xdr, OP_ALLOCATE);
879 static int decode_write_response(struct xdr_stream *xdr,
880 struct nfs42_write_res *res)
885 p = xdr_inline_decode(xdr, 4);
888 count = be32_to_cpup(p);
891 else if (count == 1) {
892 status = decode_opaque_fixed(xdr, &res->stateid,
894 if (unlikely(status))
897 p = xdr_inline_decode(xdr, 8 + 4);
900 p = xdr_decode_hyper(p, &res->count);
901 res->verifier.committed = be32_to_cpup(p);
902 return decode_verifier(xdr, &res->verifier.verifier);
905 static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns)
907 struct nfs42_netaddr *naddr;
914 p = xdr_inline_decode(xdr, 4);
917 ns->nl4_type = be32_to_cpup(p);
918 switch (ns->nl4_type) {
921 status = decode_opaque_inline(xdr, &dummy, &dummy_str);
922 if (unlikely(status))
924 if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
926 memcpy(&ns->u.nl4_str, dummy_str, dummy);
927 ns->u.nl4_str_sz = dummy;
930 naddr = &ns->u.nl4_addr;
933 status = decode_opaque_inline(xdr, &dummy, &dummy_str);
934 if (unlikely(status))
936 if (unlikely(dummy > RPCBIND_MAXNETIDLEN))
938 naddr->netid_len = dummy;
939 memcpy(naddr->netid, dummy_str, naddr->netid_len);
942 status = decode_opaque_inline(xdr, &dummy, &dummy_str);
943 if (unlikely(status))
945 if (unlikely(dummy > RPCBIND_MAXUADDRLEN))
947 naddr->addr_len = dummy;
948 memcpy(naddr->addr, dummy_str, naddr->addr_len);
957 static int decode_copy_requirements(struct xdr_stream *xdr,
958 struct nfs42_copy_res *res) {
961 p = xdr_inline_decode(xdr, 4 + 4);
965 res->consecutive = be32_to_cpup(p++);
966 res->synchronous = be32_to_cpup(p++);
970 static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res)
974 status = decode_op_hdr(xdr, OP_COPY);
975 if (status == NFS4ERR_OFFLOAD_NO_REQS) {
976 status = decode_copy_requirements(xdr, res);
979 return NFS4ERR_OFFLOAD_NO_REQS;
983 status = decode_write_response(xdr, &res->write_res);
987 return decode_copy_requirements(xdr, res);
990 static int decode_offload_cancel(struct xdr_stream *xdr,
991 struct nfs42_offload_status_res *res)
993 return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);
996 static int decode_copy_notify(struct xdr_stream *xdr,
997 struct nfs42_copy_notify_res *res)
1002 status = decode_op_hdr(xdr, OP_COPY_NOTIFY);
1005 /* cnr_lease_time */
1006 p = xdr_inline_decode(xdr, 12);
1009 p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds);
1010 res->cnr_lease_time.nseconds = be32_to_cpup(p);
1012 status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE);
1013 if (unlikely(status))
1016 /* number of source addresses */
1017 p = xdr_inline_decode(xdr, 4);
1021 count = be32_to_cpup(p);
1023 pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n",
1026 status = decode_nl4_server(xdr, &res->cnr_src);
1027 if (unlikely(status))
1032 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
1034 return decode_op_hdr(xdr, OP_DEALLOCATE);
1037 struct read_plus_segment {
1038 enum data_content4 type;
1052 static inline uint64_t read_plus_segment_length(struct read_plus_segment *seg)
1054 return seg->type == NFS4_CONTENT_DATA ? seg->data.length : seg->hole.length;
1057 static int decode_read_plus_segment(struct xdr_stream *xdr,
1058 struct read_plus_segment *seg)
1062 p = xdr_inline_decode(xdr, 4);
1065 seg->type = be32_to_cpup(p++);
1067 p = xdr_inline_decode(xdr, seg->type == NFS4_CONTENT_DATA ? 12 : 16);
1070 p = xdr_decode_hyper(p, &seg->offset);
1072 if (seg->type == NFS4_CONTENT_DATA) {
1074 uint32_t len = be32_to_cpup(p);
1076 seg->data.length = len;
1077 seg->data.from = xdr_stream_pos(xdr);
1079 if (!xdr_stream_subsegment(xdr, &buf, xdr_align_size(len)))
1081 } else if (seg->type == NFS4_CONTENT_HOLE) {
1082 xdr_decode_hyper(p, &seg->hole.length);
1088 static int process_read_plus_segment(struct xdr_stream *xdr,
1089 struct nfs_pgio_args *args,
1090 struct nfs_pgio_res *res,
1091 struct read_plus_segment *seg)
1093 unsigned long offset = seg->offset;
1094 unsigned long length = read_plus_segment_length(seg);
1095 unsigned int bufpos;
1097 if (offset + length < args->offset)
1099 else if (offset > args->offset + args->count) {
1102 } else if (offset < args->offset) {
1103 length -= (args->offset - offset);
1104 offset = args->offset;
1105 } else if (offset + length > args->offset + args->count) {
1106 length = (args->offset + args->count) - offset;
1110 bufpos = xdr->buf->head[0].iov_len + (offset - args->offset);
1111 if (seg->type == NFS4_CONTENT_HOLE)
1112 return xdr_stream_zero(xdr, bufpos, length);
1114 return xdr_stream_move_subsegment(xdr, seg->data.from, bufpos, length);
1117 static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
1119 struct nfs_pgio_header *hdr =
1120 container_of(res, struct nfs_pgio_header, res);
1121 struct nfs_pgio_args *args = &hdr->args;
1123 struct read_plus_segment *segs;
1127 status = decode_op_hdr(xdr, OP_READ_PLUS);
1131 p = xdr_inline_decode(xdr, 4 + 4);
1136 res->eof = be32_to_cpup(p++);
1137 segments = be32_to_cpup(p++);
1141 segs = kmalloc_array(segments, sizeof(*segs), GFP_KERNEL);
1146 for (i = 0; i < segments; i++) {
1147 status = decode_read_plus_segment(xdr, &segs[i]);
1152 xdr_set_pagelen(xdr, xdr_align_size(args->count));
1153 for (i = segments; i > 0; i--)
1154 res->count += process_read_plus_segment(xdr, args, res, &segs[i-1]);
1162 static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
1167 status = decode_op_hdr(xdr, OP_SEEK);
1171 p = xdr_inline_decode(xdr, 4 + 8);
1175 res->sr_eof = be32_to_cpup(p++);
1176 p = xdr_decode_hyper(p, &res->sr_offset);
1180 static int decode_layoutstats(struct xdr_stream *xdr)
1182 return decode_op_hdr(xdr, OP_LAYOUTSTATS);
1185 static int decode_clone(struct xdr_stream *xdr)
1187 return decode_op_hdr(xdr, OP_CLONE);
1190 static int decode_layouterror(struct xdr_stream *xdr)
1192 return decode_op_hdr(xdr, OP_LAYOUTERROR);
1196 * Decode ALLOCATE request
1198 static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
1199 struct xdr_stream *xdr,
1202 struct nfs42_falloc_res *res = data;
1203 struct compound_hdr hdr;
1206 status = decode_compound_hdr(xdr, &hdr);
1209 status = decode_sequence(xdr, &res->seq_res, rqstp);
1212 status = decode_putfh(xdr);
1215 status = decode_allocate(xdr, res);
1218 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
1224 * Decode COPY response
1226 static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp,
1227 struct xdr_stream *xdr,
1230 struct nfs42_copy_res *res = data;
1231 struct compound_hdr hdr;
1234 status = decode_compound_hdr(xdr, &hdr);
1237 status = decode_sequence(xdr, &res->seq_res, rqstp);
1240 status = decode_putfh(xdr);
1243 status = decode_savefh(xdr);
1246 status = decode_putfh(xdr);
1249 status = decode_copy(xdr, res);
1252 if (res->commit_res.verf)
1253 status = decode_commit(xdr, &res->commit_res);
1259 * Decode OFFLOAD_CANCEL response
1261 static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp,
1262 struct xdr_stream *xdr,
1265 struct nfs42_offload_status_res *res = data;
1266 struct compound_hdr hdr;
1269 status = decode_compound_hdr(xdr, &hdr);
1272 status = decode_sequence(xdr, &res->osr_seq_res, rqstp);
1275 status = decode_putfh(xdr);
1278 status = decode_offload_cancel(xdr, res);
1285 * Decode COPY_NOTIFY response
1287 static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp,
1288 struct xdr_stream *xdr,
1291 struct nfs42_copy_notify_res *res = data;
1292 struct compound_hdr hdr;
1295 status = decode_compound_hdr(xdr, &hdr);
1298 status = decode_sequence(xdr, &res->cnr_seq_res, rqstp);
1301 status = decode_putfh(xdr);
1304 status = decode_copy_notify(xdr, res);
1311 * Decode DEALLOCATE request
1313 static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
1314 struct xdr_stream *xdr,
1317 struct nfs42_falloc_res *res = data;
1318 struct compound_hdr hdr;
1321 status = decode_compound_hdr(xdr, &hdr);
1324 status = decode_sequence(xdr, &res->seq_res, rqstp);
1327 status = decode_putfh(xdr);
1330 status = decode_deallocate(xdr, res);
1333 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
1339 * Decode READ_PLUS request
1341 static int nfs4_xdr_dec_read_plus(struct rpc_rqst *rqstp,
1342 struct xdr_stream *xdr,
1345 struct nfs_pgio_res *res = data;
1346 struct compound_hdr hdr;
1349 xdr_set_scratch_buffer(xdr, res->scratch, sizeof(res->scratch));
1351 status = decode_compound_hdr(xdr, &hdr);
1354 status = decode_sequence(xdr, &res->seq_res, rqstp);
1357 status = decode_putfh(xdr);
1360 status = decode_read_plus(xdr, res);
1362 status = res->count;
1368 * Decode SEEK request
1370 static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
1371 struct xdr_stream *xdr,
1374 struct nfs42_seek_res *res = data;
1375 struct compound_hdr hdr;
1378 status = decode_compound_hdr(xdr, &hdr);
1381 status = decode_sequence(xdr, &res->seq_res, rqstp);
1384 status = decode_putfh(xdr);
1387 status = decode_seek(xdr, res);
1393 * Decode LAYOUTSTATS request
1395 static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp,
1396 struct xdr_stream *xdr,
1399 struct nfs42_layoutstat_res *res = data;
1400 struct compound_hdr hdr;
1403 status = decode_compound_hdr(xdr, &hdr);
1406 status = decode_sequence(xdr, &res->seq_res, rqstp);
1409 status = decode_putfh(xdr);
1412 WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
1413 for (i = 0; i < res->num_dev; i++) {
1414 status = decode_layoutstats(xdr);
1419 res->rpc_status = status;
1424 * Decode CLONE request
1426 static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp,
1427 struct xdr_stream *xdr,
1430 struct nfs42_clone_res *res = data;
1431 struct compound_hdr hdr;
1434 status = decode_compound_hdr(xdr, &hdr);
1437 status = decode_sequence(xdr, &res->seq_res, rqstp);
1440 status = decode_putfh(xdr);
1443 status = decode_savefh(xdr);
1446 status = decode_putfh(xdr);
1449 status = decode_clone(xdr);
1452 decode_getfattr(xdr, res->dst_fattr, res->server);
1454 res->rpc_status = status;
1459 * Decode LAYOUTERROR request
1461 static int nfs4_xdr_dec_layouterror(struct rpc_rqst *rqstp,
1462 struct xdr_stream *xdr,
1465 struct nfs42_layouterror_res *res = data;
1466 struct compound_hdr hdr;
1469 status = decode_compound_hdr(xdr, &hdr);
1472 status = decode_sequence(xdr, &res->seq_res, rqstp);
1475 status = decode_putfh(xdr);
1477 for (i = 0; i < res->num_errors && status == 0; i++)
1478 status = decode_layouterror(xdr);
1480 res->rpc_status = status;
1484 #ifdef CONFIG_NFS_V4_2
1485 static void nfs4_xdr_enc_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
1488 const struct nfs42_setxattrargs *args = data;
1489 struct compound_hdr hdr = {
1490 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1493 encode_compound_hdr(xdr, req, &hdr);
1494 encode_sequence(xdr, &args->seq_args, &hdr);
1495 encode_putfh(xdr, args->fh, &hdr);
1496 encode_setxattr(xdr, args, &hdr);
1500 static int nfs4_xdr_dec_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
1503 struct nfs42_setxattrres *res = data;
1504 struct compound_hdr hdr;
1507 status = decode_compound_hdr(xdr, &hdr);
1510 status = decode_sequence(xdr, &res->seq_res, req);
1513 status = decode_putfh(xdr);
1517 status = decode_setxattr(xdr, &res->cinfo);
1522 static void nfs4_xdr_enc_getxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
1525 const struct nfs42_getxattrargs *args = data;
1526 struct compound_hdr hdr = {
1527 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1531 encode_compound_hdr(xdr, req, &hdr);
1532 encode_sequence(xdr, &args->seq_args, &hdr);
1533 encode_putfh(xdr, args->fh, &hdr);
1534 replen = hdr.replen + op_decode_hdr_maxsz + 1;
1535 encode_getxattr(xdr, args->xattr_name, &hdr);
1537 rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->xattr_len,
1543 static int nfs4_xdr_dec_getxattr(struct rpc_rqst *rqstp,
1544 struct xdr_stream *xdr, void *data)
1546 struct nfs42_getxattrres *res = data;
1547 struct compound_hdr hdr;
1550 status = decode_compound_hdr(xdr, &hdr);
1553 status = decode_sequence(xdr, &res->seq_res, rqstp);
1556 status = decode_putfh(xdr);
1559 status = decode_getxattr(xdr, res, rqstp);
1564 static void nfs4_xdr_enc_listxattrs(struct rpc_rqst *req,
1565 struct xdr_stream *xdr, const void *data)
1567 const struct nfs42_listxattrsargs *args = data;
1568 struct compound_hdr hdr = {
1569 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1573 encode_compound_hdr(xdr, req, &hdr);
1574 encode_sequence(xdr, &args->seq_args, &hdr);
1575 encode_putfh(xdr, args->fh, &hdr);
1576 replen = hdr.replen + op_decode_hdr_maxsz + 2 + 1;
1577 encode_listxattrs(xdr, args, &hdr);
1579 rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->count, replen);
1584 static int nfs4_xdr_dec_listxattrs(struct rpc_rqst *rqstp,
1585 struct xdr_stream *xdr, void *data)
1587 struct nfs42_listxattrsres *res = data;
1588 struct compound_hdr hdr;
1591 xdr_set_scratch_page(xdr, res->scratch);
1593 status = decode_compound_hdr(xdr, &hdr);
1596 status = decode_sequence(xdr, &res->seq_res, rqstp);
1599 status = decode_putfh(xdr);
1602 status = decode_listxattrs(xdr, res);
1607 static void nfs4_xdr_enc_removexattr(struct rpc_rqst *req,
1608 struct xdr_stream *xdr, const void *data)
1610 const struct nfs42_removexattrargs *args = data;
1611 struct compound_hdr hdr = {
1612 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1615 encode_compound_hdr(xdr, req, &hdr);
1616 encode_sequence(xdr, &args->seq_args, &hdr);
1617 encode_putfh(xdr, args->fh, &hdr);
1618 encode_removexattr(xdr, args->xattr_name, &hdr);
1622 static int nfs4_xdr_dec_removexattr(struct rpc_rqst *req,
1623 struct xdr_stream *xdr, void *data)
1625 struct nfs42_removexattrres *res = data;
1626 struct compound_hdr hdr;
1629 status = decode_compound_hdr(xdr, &hdr);
1632 status = decode_sequence(xdr, &res->seq_res, req);
1635 status = decode_putfh(xdr);
1639 status = decode_removexattr(xdr, &res->cinfo);
1644 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */