xref: /openbmc/linux/fs/nfs/nfs42xdr.c (revision 2a12187d)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>
4  */
5 #ifndef __LINUX_FS_NFS_NFS4_2XDR_H
6 #define __LINUX_FS_NFS_NFS4_2XDR_H
7 
8 #include "nfs42.h"
9 
10 #define encode_fallocate_maxsz		(encode_stateid_maxsz + \
11 					 2 /* offset */ + \
12 					 2 /* length */)
13 #define NFS42_WRITE_RES_SIZE		(1 /* wr_callback_id size */ +\
14 					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
15 					 2 /* wr_count */ + \
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 */\
26 					 1 + /* nl4_type */ \
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) + \
37 					 1 + /* nl4_type */ \
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 */\
43 					 1 + /* nl4_type */ \
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 + \
55 					 1 /* rpr_eof */ + \
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 + \
60 					 2 /* offset */ + \
61 					 1 /* whence */)
62 #define decode_seek_maxsz		(op_decode_hdr_maxsz + \
63 					 1 /* eof */ + \
64 					 1 /* whence */ + \
65 					 2 /* offset */ + \
66 					 2 /* length */)
67 #define encode_io_info_maxsz		4
68 #define encode_layoutstats_maxsz	(op_decode_hdr_maxsz + \
69 					2 /* offset */ + \
70 					2 /* length */ + \
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 + \
80 					2 /* offset */ + \
81 					2 /* length */ + \
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 */ + \
90 					2 /* count */)
91 #define decode_clone_maxsz		(op_decode_hdr_maxsz)
92 
93 #define NFS4_enc_allocate_sz		(compound_encode_hdr_maxsz + \
94 					 encode_sequence_maxsz + \
95 					 encode_putfh_maxsz + \
96 					 encode_allocate_maxsz + \
97 					 encode_getattr_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 + \
109 					 encode_commit_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 + \
116 					 decode_commit_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 + \
152 					 encode_seek_maxsz)
153 #define NFS4_dec_seek_sz		(compound_decode_hdr_maxsz + \
154 					 decode_sequence_maxsz + \
155 					 decode_putfh_maxsz + \
156 					 decode_seek_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)
189 
190 /* Not limited by NFS itself, limited by the generic xattr code */
191 #define nfs4_xattr_name_maxsz   XDR_QUADLEN(XATTR_NAME_MAX)
192 
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)
205 
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)
238 
239 /*
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
243  * respectively.
244  */
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)
250 					* XDR_UNIT);
251 
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);
256 
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);
261 
262 static void encode_fallocate(struct xdr_stream *xdr,
263 			     const struct nfs42_falloc_args *args)
264 {
265 	encode_nfs4_stateid(xdr, &args->falloc_stateid);
266 	encode_uint64(xdr, args->falloc_offset);
267 	encode_uint64(xdr, args->falloc_length);
268 }
269 
270 static void encode_allocate(struct xdr_stream *xdr,
271 			    const struct nfs42_falloc_args *args,
272 			    struct compound_hdr *hdr)
273 {
274 	encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
275 	encode_fallocate(xdr, args);
276 }
277 
278 static void encode_nl4_server(struct xdr_stream *xdr,
279 			      const struct nl4_server *ns)
280 {
281 	encode_uint32(xdr, ns->nl4_type);
282 	switch (ns->nl4_type) {
283 	case NL4_NAME:
284 	case NL4_URL:
285 		encode_string(xdr, ns->u.nl4_str_sz, ns->u.nl4_str);
286 		break;
287 	case NL4_NETADDR:
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);
292 		break;
293 	default:
294 		WARN_ON_ONCE(1);
295 	}
296 }
297 
298 static void encode_copy(struct xdr_stream *xdr,
299 			const struct nfs42_copy_args *args,
300 			struct compound_hdr *hdr)
301 {
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);
305 
306 	encode_uint64(xdr, args->src_pos);
307 	encode_uint64(xdr, args->dst_pos);
308 	encode_uint64(xdr, args->count);
309 
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 */
314 		return;
315 	}
316 	encode_uint32(xdr, 1); /* supporting 1 server */
317 	encode_nl4_server(xdr, args->cp_src);
318 }
319 
320 static void encode_offload_cancel(struct xdr_stream *xdr,
321 				  const struct nfs42_offload_status_args *args,
322 				  struct compound_hdr *hdr)
323 {
324 	encode_op_hdr(xdr, OP_OFFLOAD_CANCEL, decode_offload_cancel_maxsz, hdr);
325 	encode_nfs4_stateid(xdr, &args->osa_stateid);
326 }
327 
328 static void encode_copy_notify(struct xdr_stream *xdr,
329 			       const struct nfs42_copy_notify_args *args,
330 			       struct compound_hdr *hdr)
331 {
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);
335 }
336 
337 static void encode_deallocate(struct xdr_stream *xdr,
338 			      const struct nfs42_falloc_args *args,
339 			      struct compound_hdr *hdr)
340 {
341 	encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
342 	encode_fallocate(xdr, args);
343 }
344 
345 static void encode_read_plus(struct xdr_stream *xdr,
346 			     const struct nfs_pgio_args *args,
347 			     struct compound_hdr *hdr)
348 {
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);
353 }
354 
355 static void encode_seek(struct xdr_stream *xdr,
356 			const struct nfs42_seek_args *args,
357 			struct compound_hdr *hdr)
358 {
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);
363 }
364 
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)
369 {
370 	__be32 *p;
371 
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);
389 	else
390 		encode_uint32(xdr, 0);
391 }
392 
393 static void encode_clone(struct xdr_stream *xdr,
394 			 const struct nfs42_clone_args *args,
395 			 struct compound_hdr *hdr)
396 {
397 	__be32 *p;
398 
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);
406 }
407 
408 static void encode_device_error(struct xdr_stream *xdr,
409 				const struct nfs42_device_error *error)
410 {
411 	__be32 *p;
412 
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);
418 }
419 
420 static void encode_layouterror(struct xdr_stream *xdr,
421 			       const struct nfs42_layout_error *args,
422 			       struct compound_hdr *hdr)
423 {
424 	__be32 *p;
425 
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);
432 	*p = cpu_to_be32(1);
433 	encode_device_error(xdr, &args->errors[0]);
434 }
435 
436 static void encode_setxattr(struct xdr_stream *xdr,
437 			    const struct nfs42_setxattrargs *arg,
438 			    struct compound_hdr *hdr)
439 {
440 	__be32 *p;
441 
442 	BUILD_BUG_ON(XATTR_CREATE != SETXATTR4_CREATE);
443 	BUILD_BUG_ON(XATTR_REPLACE != SETXATTR4_REPLACE);
444 
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);
451 	if (arg->xattr_len)
452 		xdr_write_pages(xdr, arg->xattr_pages, 0, arg->xattr_len);
453 }
454 
455 static int decode_setxattr(struct xdr_stream *xdr,
456 			   struct nfs4_change_info *cinfo)
457 {
458 	int status;
459 
460 	status = decode_op_hdr(xdr, OP_SETXATTR);
461 	if (status)
462 		goto out;
463 	status = decode_change_info(xdr, cinfo);
464 out:
465 	return status;
466 }
467 
468 
469 static void encode_getxattr(struct xdr_stream *xdr, const char *name,
470 			    struct compound_hdr *hdr)
471 {
472 	encode_op_hdr(xdr, OP_GETXATTR, decode_getxattr_maxsz, hdr);
473 	encode_string(xdr, strlen(name), name);
474 }
475 
476 static int decode_getxattr(struct xdr_stream *xdr,
477 			   struct nfs42_getxattrres *res,
478 			   struct rpc_rqst *req)
479 {
480 	int status;
481 	__be32 *p;
482 	u32 len, rdlen;
483 
484 	status = decode_op_hdr(xdr, OP_GETXATTR);
485 	if (status)
486 		return status;
487 
488 	p = xdr_inline_decode(xdr, 4);
489 	if (unlikely(!p))
490 		return -EIO;
491 
492 	len = be32_to_cpup(p);
493 
494 	/*
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.
498 	 */
499 	if (len > req->rq_rcv_buf.page_len)
500 		return -ERANGE;
501 
502 	res->xattr_len = len;
503 
504 	if (len > 0) {
505 		rdlen = xdr_read_pages(xdr, len);
506 		if (rdlen < len)
507 			return -EIO;
508 	}
509 
510 	return 0;
511 }
512 
513 static void encode_removexattr(struct xdr_stream *xdr, const char *name,
514 			       struct compound_hdr *hdr)
515 {
516 	encode_op_hdr(xdr, OP_REMOVEXATTR, decode_removexattr_maxsz, hdr);
517 	encode_string(xdr, strlen(name), name);
518 }
519 
520 
521 static int decode_removexattr(struct xdr_stream *xdr,
522 			   struct nfs4_change_info *cinfo)
523 {
524 	int status;
525 
526 	status = decode_op_hdr(xdr, OP_REMOVEXATTR);
527 	if (status)
528 		goto out;
529 
530 	status = decode_change_info(xdr, cinfo);
531 out:
532 	return status;
533 }
534 
535 static void encode_listxattrs(struct xdr_stream *xdr,
536 			     const struct nfs42_listxattrsargs *arg,
537 			     struct compound_hdr *hdr)
538 {
539 	__be32 *p;
540 
541 	encode_op_hdr(xdr, OP_LISTXATTRS, decode_listxattrs_maxsz, hdr);
542 
543 	p = reserve_space(xdr, 12);
544 	if (unlikely(!p))
545 		return;
546 
547 	p = xdr_encode_hyper(p, arg->cookie);
548 	/*
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.
552 	 */
553 	*p = cpu_to_be32(arg->count + 8 + 4);
554 }
555 
556 static int decode_listxattrs(struct xdr_stream *xdr,
557 			    struct nfs42_listxattrsres *res)
558 {
559 	int status;
560 	__be32 *p;
561 	u32 count, len, ulen;
562 	size_t left, copied;
563 	char *buf;
564 
565 	status = decode_op_hdr(xdr, OP_LISTXATTRS);
566 	if (status) {
567 		/*
568 		 * Special case: for LISTXATTRS, NFS4ERR_TOOSMALL
569 		 * should be translated to ERANGE.
570 		 */
571 		if (status == -ETOOSMALL)
572 			status = -ERANGE;
573 		/*
574 		 * Special case: for LISTXATTRS, NFS4ERR_NOXATTR
575 		 * should be translated to success with zero-length reply.
576 		 */
577 		if (status == -ENODATA) {
578 			res->eof = true;
579 			status = 0;
580 		}
581 		goto out;
582 	}
583 
584 	p = xdr_inline_decode(xdr, 8);
585 	if (unlikely(!p))
586 		return -EIO;
587 
588 	xdr_decode_hyper(p, &res->cookie);
589 
590 	p = xdr_inline_decode(xdr, 4);
591 	if (unlikely(!p))
592 		return -EIO;
593 
594 	left = res->xattr_len;
595 	buf = res->xattr_buf;
596 
597 	count = be32_to_cpup(p);
598 	copied = 0;
599 
600 	/*
601 	 * We have asked for enough room to encode the maximum number
602 	 * of possible attribute names, so everything should fit.
603 	 *
604 	 * But, don't rely on that assumption. Just decode entries
605 	 * until they don't fit anymore, just in case the server did
606 	 * something odd.
607 	 */
608 	while (count--) {
609 		p = xdr_inline_decode(xdr, 4);
610 		if (unlikely(!p))
611 			return -EIO;
612 
613 		len = be32_to_cpup(p);
614 		if (len > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) {
615 			status = -ERANGE;
616 			goto out;
617 		}
618 
619 		p = xdr_inline_decode(xdr, len);
620 		if (unlikely(!p))
621 			return -EIO;
622 
623 		ulen = len + XATTR_USER_PREFIX_LEN + 1;
624 		if (buf) {
625 			if (ulen > left) {
626 				status = -ERANGE;
627 				goto out;
628 			}
629 
630 			memcpy(buf, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
631 			memcpy(buf + XATTR_USER_PREFIX_LEN, p, len);
632 
633 			buf[ulen - 1] = 0;
634 			buf += ulen;
635 			left -= ulen;
636 		}
637 		copied += ulen;
638 	}
639 
640 	p = xdr_inline_decode(xdr, 4);
641 	if (unlikely(!p))
642 		return -EIO;
643 
644 	res->eof = be32_to_cpup(p);
645 	res->copied = copied;
646 
647 out:
648 	if (status == -ERANGE && res->xattr_len == XATTR_LIST_MAX)
649 		status = -E2BIG;
650 
651 	return status;
652 }
653 
654 /*
655  * Encode ALLOCATE request
656  */
657 static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
658 				  struct xdr_stream *xdr,
659 				  const void *data)
660 {
661 	const struct nfs42_falloc_args *args = data;
662 	struct compound_hdr hdr = {
663 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
664 	};
665 
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);
671 	encode_nops(&hdr);
672 }
673 
674 static void encode_copy_commit(struct xdr_stream *xdr,
675 			  const struct nfs42_copy_args *args,
676 			  struct compound_hdr *hdr)
677 {
678 	__be32 *p;
679 
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);
684 }
685 
686 /*
687  * Encode COPY request
688  */
689 static void nfs4_xdr_enc_copy(struct rpc_rqst *req,
690 			      struct xdr_stream *xdr,
691 			      const void *data)
692 {
693 	const struct nfs42_copy_args *args = data;
694 	struct compound_hdr hdr = {
695 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
696 	};
697 
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);
704 	if (args->sync)
705 		encode_copy_commit(xdr, args, &hdr);
706 	encode_nops(&hdr);
707 }
708 
709 /*
710  * Encode OFFLOAD_CANEL request
711  */
712 static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req,
713 					struct xdr_stream *xdr,
714 					const void *data)
715 {
716 	const struct nfs42_offload_status_args *args = data;
717 	struct compound_hdr hdr = {
718 		.minorversion = nfs4_xdr_minorversion(&args->osa_seq_args),
719 	};
720 
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);
725 	encode_nops(&hdr);
726 }
727 
728 /*
729  * Encode COPY_NOTIFY request
730  */
731 static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req,
732 				     struct xdr_stream *xdr,
733 				     const void *data)
734 {
735 	const struct nfs42_copy_notify_args *args = data;
736 	struct compound_hdr hdr = {
737 		.minorversion = nfs4_xdr_minorversion(&args->cna_seq_args),
738 	};
739 
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);
744 	encode_nops(&hdr);
745 }
746 
747 /*
748  * Encode DEALLOCATE request
749  */
750 static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
751 				    struct xdr_stream *xdr,
752 				    const void *data)
753 {
754 	const struct nfs42_falloc_args *args = data;
755 	struct compound_hdr hdr = {
756 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
757 	};
758 
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);
764 	encode_nops(&hdr);
765 }
766 
767 /*
768  * Encode READ_PLUS request
769  */
770 static void nfs4_xdr_enc_read_plus(struct rpc_rqst *req,
771 				   struct xdr_stream *xdr,
772 				   const void *data)
773 {
774 	const struct nfs_pgio_args *args = data;
775 	struct compound_hdr hdr = {
776 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
777 	};
778 
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);
783 
784 	rpc_prepare_reply_pages(req, args->pages, args->pgbase,
785 				args->count, hdr.replen);
786 	encode_nops(&hdr);
787 }
788 
789 /*
790  * Encode SEEK request
791  */
792 static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
793 			      struct xdr_stream *xdr,
794 			      const void *data)
795 {
796 	const struct nfs42_seek_args *args = data;
797 	struct compound_hdr hdr = {
798 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
799 	};
800 
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);
805 	encode_nops(&hdr);
806 }
807 
808 /*
809  * Encode LAYOUTSTATS request
810  */
811 static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req,
812 				     struct xdr_stream *xdr,
813 				     const void *data)
814 {
815 	const struct nfs42_layoutstat_args *args = data;
816 	int i;
817 
818 	struct compound_hdr hdr = {
819 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
820 	};
821 
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);
828 	encode_nops(&hdr);
829 }
830 
831 /*
832  * Encode CLONE request
833  */
834 static void nfs4_xdr_enc_clone(struct rpc_rqst *req,
835 			       struct xdr_stream *xdr,
836 			       const void *data)
837 {
838 	const struct nfs42_clone_args *args = data;
839 	struct compound_hdr hdr = {
840 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
841 	};
842 
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);
850 	encode_nops(&hdr);
851 }
852 
853 /*
854  * Encode LAYOUTERROR request
855  */
856 static void nfs4_xdr_enc_layouterror(struct rpc_rqst *req,
857 				     struct xdr_stream *xdr,
858 				     const void *data)
859 {
860 	const struct nfs42_layouterror_args *args = data;
861 	struct compound_hdr hdr = {
862 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
863 	};
864 	int i;
865 
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);
871 	encode_nops(&hdr);
872 }
873 
874 static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
875 {
876 	return decode_op_hdr(xdr, OP_ALLOCATE);
877 }
878 
879 static int decode_write_response(struct xdr_stream *xdr,
880 				 struct nfs42_write_res *res)
881 {
882 	__be32 *p;
883 	int status, count;
884 
885 	p = xdr_inline_decode(xdr, 4);
886 	if (unlikely(!p))
887 		return -EIO;
888 	count = be32_to_cpup(p);
889 	if (count > 1)
890 		return -EREMOTEIO;
891 	else if (count == 1) {
892 		status = decode_opaque_fixed(xdr, &res->stateid,
893 				NFS4_STATEID_SIZE);
894 		if (unlikely(status))
895 			return -EIO;
896 	}
897 	p = xdr_inline_decode(xdr, 8 + 4);
898 	if (unlikely(!p))
899 		return -EIO;
900 	p = xdr_decode_hyper(p, &res->count);
901 	res->verifier.committed = be32_to_cpup(p);
902 	return decode_verifier(xdr, &res->verifier.verifier);
903 }
904 
905 static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns)
906 {
907 	struct nfs42_netaddr *naddr;
908 	uint32_t dummy;
909 	char *dummy_str;
910 	__be32 *p;
911 	int status;
912 
913 	/* nl_type */
914 	p = xdr_inline_decode(xdr, 4);
915 	if (unlikely(!p))
916 		return -EIO;
917 	ns->nl4_type = be32_to_cpup(p);
918 	switch (ns->nl4_type) {
919 	case NL4_NAME:
920 	case NL4_URL:
921 		status = decode_opaque_inline(xdr, &dummy, &dummy_str);
922 		if (unlikely(status))
923 			return status;
924 		if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
925 			return -EIO;
926 		memcpy(&ns->u.nl4_str, dummy_str, dummy);
927 		ns->u.nl4_str_sz = dummy;
928 		break;
929 	case NL4_NETADDR:
930 		naddr = &ns->u.nl4_addr;
931 
932 		/* netid string */
933 		status = decode_opaque_inline(xdr, &dummy, &dummy_str);
934 		if (unlikely(status))
935 			return status;
936 		if (unlikely(dummy > RPCBIND_MAXNETIDLEN))
937 			return -EIO;
938 		naddr->netid_len = dummy;
939 		memcpy(naddr->netid, dummy_str, naddr->netid_len);
940 
941 		/* uaddr string */
942 		status = decode_opaque_inline(xdr, &dummy, &dummy_str);
943 		if (unlikely(status))
944 			return status;
945 		if (unlikely(dummy > RPCBIND_MAXUADDRLEN))
946 			return -EIO;
947 		naddr->addr_len = dummy;
948 		memcpy(naddr->addr, dummy_str, naddr->addr_len);
949 		break;
950 	default:
951 		WARN_ON_ONCE(1);
952 		return -EIO;
953 	}
954 	return 0;
955 }
956 
957 static int decode_copy_requirements(struct xdr_stream *xdr,
958 				    struct nfs42_copy_res *res) {
959 	__be32 *p;
960 
961 	p = xdr_inline_decode(xdr, 4 + 4);
962 	if (unlikely(!p))
963 		return -EIO;
964 
965 	res->consecutive = be32_to_cpup(p++);
966 	res->synchronous = be32_to_cpup(p++);
967 	return 0;
968 }
969 
970 static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res)
971 {
972 	int status;
973 
974 	status = decode_op_hdr(xdr, OP_COPY);
975 	if (status == NFS4ERR_OFFLOAD_NO_REQS) {
976 		status = decode_copy_requirements(xdr, res);
977 		if (status)
978 			return status;
979 		return NFS4ERR_OFFLOAD_NO_REQS;
980 	} else if (status)
981 		return status;
982 
983 	status = decode_write_response(xdr, &res->write_res);
984 	if (status)
985 		return status;
986 
987 	return decode_copy_requirements(xdr, res);
988 }
989 
990 static int decode_offload_cancel(struct xdr_stream *xdr,
991 				 struct nfs42_offload_status_res *res)
992 {
993 	return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);
994 }
995 
996 static int decode_copy_notify(struct xdr_stream *xdr,
997 			      struct nfs42_copy_notify_res *res)
998 {
999 	__be32 *p;
1000 	int status, count;
1001 
1002 	status = decode_op_hdr(xdr, OP_COPY_NOTIFY);
1003 	if (status)
1004 		return status;
1005 	/* cnr_lease_time */
1006 	p = xdr_inline_decode(xdr, 12);
1007 	if (unlikely(!p))
1008 		return -EIO;
1009 	p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds);
1010 	res->cnr_lease_time.nseconds = be32_to_cpup(p);
1011 
1012 	status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE);
1013 	if (unlikely(status))
1014 		return -EIO;
1015 
1016 	/* number of source addresses */
1017 	p = xdr_inline_decode(xdr, 4);
1018 	if (unlikely(!p))
1019 		return -EIO;
1020 
1021 	count = be32_to_cpup(p);
1022 	if (count > 1)
1023 		pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n",
1024 			 __func__, count);
1025 
1026 	status = decode_nl4_server(xdr, &res->cnr_src);
1027 	if (unlikely(status))
1028 		return -EIO;
1029 	return 0;
1030 }
1031 
1032 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
1033 {
1034 	return decode_op_hdr(xdr, OP_DEALLOCATE);
1035 }
1036 
1037 struct read_plus_segment {
1038 	enum data_content4 type;
1039 	uint64_t offset;
1040 	union {
1041 		struct {
1042 			uint64_t length;
1043 		} hole;
1044 
1045 		struct {
1046 			uint32_t length;
1047 			unsigned int from;
1048 		} data;
1049 	};
1050 };
1051 
1052 static inline uint64_t read_plus_segment_length(struct read_plus_segment *seg)
1053 {
1054 	return seg->type == NFS4_CONTENT_DATA ? seg->data.length : seg->hole.length;
1055 }
1056 
1057 static int decode_read_plus_segment(struct xdr_stream *xdr,
1058 				    struct read_plus_segment *seg)
1059 {
1060 	__be32 *p;
1061 
1062 	p = xdr_inline_decode(xdr, 4);
1063 	if (!p)
1064 		return -EIO;
1065 	seg->type = be32_to_cpup(p++);
1066 
1067 	p = xdr_inline_decode(xdr, seg->type == NFS4_CONTENT_DATA ? 12 : 16);
1068 	if (!p)
1069 		return -EIO;
1070 	p = xdr_decode_hyper(p, &seg->offset);
1071 
1072 	if (seg->type == NFS4_CONTENT_DATA) {
1073 		struct xdr_buf buf;
1074 		uint32_t len = be32_to_cpup(p);
1075 
1076 		seg->data.length = len;
1077 		seg->data.from = xdr_stream_pos(xdr);
1078 
1079 		if (!xdr_stream_subsegment(xdr, &buf, xdr_align_size(len)))
1080 			return -EIO;
1081 	} else if (seg->type == NFS4_CONTENT_HOLE) {
1082 		xdr_decode_hyper(p, &seg->hole.length);
1083 	} else
1084 		return -EINVAL;
1085 	return 0;
1086 }
1087 
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)
1092 {
1093 	unsigned long offset = seg->offset;
1094 	unsigned long length = read_plus_segment_length(seg);
1095 	unsigned int bufpos;
1096 
1097 	if (offset + length < args->offset)
1098 		return 0;
1099 	else if (offset > args->offset + args->count) {
1100 		res->eof = 0;
1101 		return 0;
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;
1107 		res->eof = 0;
1108 	}
1109 
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);
1113 	else
1114 		return xdr_stream_move_subsegment(xdr, seg->data.from, bufpos, length);
1115 }
1116 
1117 static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
1118 {
1119 	struct nfs_pgio_header *hdr =
1120 		container_of(res, struct nfs_pgio_header, res);
1121 	struct nfs_pgio_args *args = &hdr->args;
1122 	uint32_t segments;
1123 	struct read_plus_segment *segs;
1124 	int status, i;
1125 	char scratch_buf[16];
1126 	__be32 *p;
1127 
1128 	status = decode_op_hdr(xdr, OP_READ_PLUS);
1129 	if (status)
1130 		return status;
1131 
1132 	p = xdr_inline_decode(xdr, 4 + 4);
1133 	if (unlikely(!p))
1134 		return -EIO;
1135 
1136 	res->count = 0;
1137 	res->eof = be32_to_cpup(p++);
1138 	segments = be32_to_cpup(p++);
1139 	if (segments == 0)
1140 		return status;
1141 
1142 	segs = kmalloc_array(segments, sizeof(*segs), GFP_KERNEL);
1143 	if (!segs)
1144 		return -ENOMEM;
1145 
1146 	xdr_set_scratch_buffer(xdr, &scratch_buf, sizeof(scratch_buf));
1147 	status = -EIO;
1148 	for (i = 0; i < segments; i++) {
1149 		status = decode_read_plus_segment(xdr, &segs[i]);
1150 		if (status < 0)
1151 			goto out;
1152 	}
1153 
1154 	xdr_set_pagelen(xdr, xdr_align_size(args->count));
1155 	for (i = segments; i > 0; i--)
1156 		res->count += process_read_plus_segment(xdr, args, res, &segs[i-1]);
1157 	status = 0;
1158 
1159 out:
1160 	kfree(segs);
1161 	return status;
1162 }
1163 
1164 static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
1165 {
1166 	int status;
1167 	__be32 *p;
1168 
1169 	status = decode_op_hdr(xdr, OP_SEEK);
1170 	if (status)
1171 		return status;
1172 
1173 	p = xdr_inline_decode(xdr, 4 + 8);
1174 	if (unlikely(!p))
1175 		return -EIO;
1176 
1177 	res->sr_eof = be32_to_cpup(p++);
1178 	p = xdr_decode_hyper(p, &res->sr_offset);
1179 	return 0;
1180 }
1181 
1182 static int decode_layoutstats(struct xdr_stream *xdr)
1183 {
1184 	return decode_op_hdr(xdr, OP_LAYOUTSTATS);
1185 }
1186 
1187 static int decode_clone(struct xdr_stream *xdr)
1188 {
1189 	return decode_op_hdr(xdr, OP_CLONE);
1190 }
1191 
1192 static int decode_layouterror(struct xdr_stream *xdr)
1193 {
1194 	return decode_op_hdr(xdr, OP_LAYOUTERROR);
1195 }
1196 
1197 /*
1198  * Decode ALLOCATE request
1199  */
1200 static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
1201 				 struct xdr_stream *xdr,
1202 				 void *data)
1203 {
1204 	struct nfs42_falloc_res *res = data;
1205 	struct compound_hdr hdr;
1206 	int status;
1207 
1208 	status = decode_compound_hdr(xdr, &hdr);
1209 	if (status)
1210 		goto out;
1211 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1212 	if (status)
1213 		goto out;
1214 	status = decode_putfh(xdr);
1215 	if (status)
1216 		goto out;
1217 	status = decode_allocate(xdr, res);
1218 	if (status)
1219 		goto out;
1220 	decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
1221 out:
1222 	return status;
1223 }
1224 
1225 /*
1226  * Decode COPY response
1227  */
1228 static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp,
1229 			     struct xdr_stream *xdr,
1230 			     void *data)
1231 {
1232 	struct nfs42_copy_res *res = data;
1233 	struct compound_hdr hdr;
1234 	int status;
1235 
1236 	status = decode_compound_hdr(xdr, &hdr);
1237 	if (status)
1238 		goto out;
1239 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1240 	if (status)
1241 		goto out;
1242 	status = decode_putfh(xdr);
1243 	if (status)
1244 		goto out;
1245 	status = decode_savefh(xdr);
1246 	if (status)
1247 		goto out;
1248 	status = decode_putfh(xdr);
1249 	if (status)
1250 		goto out;
1251 	status = decode_copy(xdr, res);
1252 	if (status)
1253 		goto out;
1254 	if (res->commit_res.verf)
1255 		status = decode_commit(xdr, &res->commit_res);
1256 out:
1257 	return status;
1258 }
1259 
1260 /*
1261  * Decode OFFLOAD_CANCEL response
1262  */
1263 static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp,
1264 				       struct xdr_stream *xdr,
1265 				       void *data)
1266 {
1267 	struct nfs42_offload_status_res *res = data;
1268 	struct compound_hdr hdr;
1269 	int status;
1270 
1271 	status = decode_compound_hdr(xdr, &hdr);
1272 	if (status)
1273 		goto out;
1274 	status = decode_sequence(xdr, &res->osr_seq_res, rqstp);
1275 	if (status)
1276 		goto out;
1277 	status = decode_putfh(xdr);
1278 	if (status)
1279 		goto out;
1280 	status = decode_offload_cancel(xdr, res);
1281 
1282 out:
1283 	return status;
1284 }
1285 
1286 /*
1287  * Decode COPY_NOTIFY response
1288  */
1289 static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp,
1290 				    struct xdr_stream *xdr,
1291 				    void *data)
1292 {
1293 	struct nfs42_copy_notify_res *res = data;
1294 	struct compound_hdr hdr;
1295 	int status;
1296 
1297 	status = decode_compound_hdr(xdr, &hdr);
1298 	if (status)
1299 		goto out;
1300 	status = decode_sequence(xdr, &res->cnr_seq_res, rqstp);
1301 	if (status)
1302 		goto out;
1303 	status = decode_putfh(xdr);
1304 	if (status)
1305 		goto out;
1306 	status = decode_copy_notify(xdr, res);
1307 
1308 out:
1309 	return status;
1310 }
1311 
1312 /*
1313  * Decode DEALLOCATE request
1314  */
1315 static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
1316 				   struct xdr_stream *xdr,
1317 				   void *data)
1318 {
1319 	struct nfs42_falloc_res *res = data;
1320 	struct compound_hdr hdr;
1321 	int status;
1322 
1323 	status = decode_compound_hdr(xdr, &hdr);
1324 	if (status)
1325 		goto out;
1326 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1327 	if (status)
1328 		goto out;
1329 	status = decode_putfh(xdr);
1330 	if (status)
1331 		goto out;
1332 	status = decode_deallocate(xdr, res);
1333 	if (status)
1334 		goto out;
1335 	decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
1336 out:
1337 	return status;
1338 }
1339 
1340 /*
1341  * Decode READ_PLUS request
1342  */
1343 static int nfs4_xdr_dec_read_plus(struct rpc_rqst *rqstp,
1344 				  struct xdr_stream *xdr,
1345 				  void *data)
1346 {
1347 	struct nfs_pgio_res *res = data;
1348 	struct compound_hdr hdr;
1349 	int status;
1350 
1351 	status = decode_compound_hdr(xdr, &hdr);
1352 	if (status)
1353 		goto out;
1354 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1355 	if (status)
1356 		goto out;
1357 	status = decode_putfh(xdr);
1358 	if (status)
1359 		goto out;
1360 	status = decode_read_plus(xdr, res);
1361 	if (!status)
1362 		status = res->count;
1363 out:
1364 	return status;
1365 }
1366 
1367 /*
1368  * Decode SEEK request
1369  */
1370 static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
1371 			     struct xdr_stream *xdr,
1372 			     void *data)
1373 {
1374 	struct nfs42_seek_res *res = data;
1375 	struct compound_hdr hdr;
1376 	int status;
1377 
1378 	status = decode_compound_hdr(xdr, &hdr);
1379 	if (status)
1380 		goto out;
1381 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1382 	if (status)
1383 		goto out;
1384 	status = decode_putfh(xdr);
1385 	if (status)
1386 		goto out;
1387 	status = decode_seek(xdr, res);
1388 out:
1389 	return status;
1390 }
1391 
1392 /*
1393  * Decode LAYOUTSTATS request
1394  */
1395 static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp,
1396 				    struct xdr_stream *xdr,
1397 				    void *data)
1398 {
1399 	struct nfs42_layoutstat_res *res = data;
1400 	struct compound_hdr hdr;
1401 	int status, i;
1402 
1403 	status = decode_compound_hdr(xdr, &hdr);
1404 	if (status)
1405 		goto out;
1406 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1407 	if (status)
1408 		goto out;
1409 	status = decode_putfh(xdr);
1410 	if (status)
1411 		goto out;
1412 	WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
1413 	for (i = 0; i < res->num_dev; i++) {
1414 		status = decode_layoutstats(xdr);
1415 		if (status)
1416 			goto out;
1417 	}
1418 out:
1419 	res->rpc_status = status;
1420 	return status;
1421 }
1422 
1423 /*
1424  * Decode CLONE request
1425  */
1426 static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp,
1427 			      struct xdr_stream *xdr,
1428 			      void *data)
1429 {
1430 	struct nfs42_clone_res *res = data;
1431 	struct compound_hdr hdr;
1432 	int status;
1433 
1434 	status = decode_compound_hdr(xdr, &hdr);
1435 	if (status)
1436 		goto out;
1437 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1438 	if (status)
1439 		goto out;
1440 	status = decode_putfh(xdr);
1441 	if (status)
1442 		goto out;
1443 	status = decode_savefh(xdr);
1444 	if (status)
1445 		goto out;
1446 	status = decode_putfh(xdr);
1447 	if (status)
1448 		goto out;
1449 	status = decode_clone(xdr);
1450 	if (status)
1451 		goto out;
1452 	decode_getfattr(xdr, res->dst_fattr, res->server);
1453 out:
1454 	res->rpc_status = status;
1455 	return status;
1456 }
1457 
1458 /*
1459  * Decode LAYOUTERROR request
1460  */
1461 static int nfs4_xdr_dec_layouterror(struct rpc_rqst *rqstp,
1462 				    struct xdr_stream *xdr,
1463 				    void *data)
1464 {
1465 	struct nfs42_layouterror_res *res = data;
1466 	struct compound_hdr hdr;
1467 	int status, i;
1468 
1469 	status = decode_compound_hdr(xdr, &hdr);
1470 	if (status)
1471 		goto out;
1472 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1473 	if (status)
1474 		goto out;
1475 	status = decode_putfh(xdr);
1476 
1477 	for (i = 0; i < res->num_errors && status == 0; i++)
1478 		status = decode_layouterror(xdr);
1479 out:
1480 	res->rpc_status = status;
1481 	return status;
1482 }
1483 
1484 #ifdef CONFIG_NFS_V4_2
1485 static void nfs4_xdr_enc_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
1486 				  const void *data)
1487 {
1488 	const struct nfs42_setxattrargs *args = data;
1489 	struct compound_hdr hdr = {
1490 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1491 	};
1492 
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);
1497 	encode_nops(&hdr);
1498 }
1499 
1500 static int nfs4_xdr_dec_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
1501 				 void *data)
1502 {
1503 	struct nfs42_setxattrres *res = data;
1504 	struct compound_hdr hdr;
1505 	int status;
1506 
1507 	status = decode_compound_hdr(xdr, &hdr);
1508 	if (status)
1509 		goto out;
1510 	status = decode_sequence(xdr, &res->seq_res, req);
1511 	if (status)
1512 		goto out;
1513 	status = decode_putfh(xdr);
1514 	if (status)
1515 		goto out;
1516 
1517 	status = decode_setxattr(xdr, &res->cinfo);
1518 out:
1519 	return status;
1520 }
1521 
1522 static void nfs4_xdr_enc_getxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
1523 				  const void *data)
1524 {
1525 	const struct nfs42_getxattrargs *args = data;
1526 	struct compound_hdr hdr = {
1527 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1528 	};
1529 	uint32_t replen;
1530 
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);
1536 
1537 	rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->xattr_len,
1538 				replen);
1539 
1540 	encode_nops(&hdr);
1541 }
1542 
1543 static int nfs4_xdr_dec_getxattr(struct rpc_rqst *rqstp,
1544 				 struct xdr_stream *xdr, void *data)
1545 {
1546 	struct nfs42_getxattrres *res = data;
1547 	struct compound_hdr hdr;
1548 	int status;
1549 
1550 	status = decode_compound_hdr(xdr, &hdr);
1551 	if (status)
1552 		goto out;
1553 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1554 	if (status)
1555 		goto out;
1556 	status = decode_putfh(xdr);
1557 	if (status)
1558 		goto out;
1559 	status = decode_getxattr(xdr, res, rqstp);
1560 out:
1561 	return status;
1562 }
1563 
1564 static void nfs4_xdr_enc_listxattrs(struct rpc_rqst *req,
1565 				    struct xdr_stream *xdr, const void *data)
1566 {
1567 	const struct nfs42_listxattrsargs *args = data;
1568 	struct compound_hdr hdr = {
1569 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1570 	};
1571 	uint32_t replen;
1572 
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);
1578 
1579 	rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->count, replen);
1580 
1581 	encode_nops(&hdr);
1582 }
1583 
1584 static int nfs4_xdr_dec_listxattrs(struct rpc_rqst *rqstp,
1585 				   struct xdr_stream *xdr, void *data)
1586 {
1587 	struct nfs42_listxattrsres *res = data;
1588 	struct compound_hdr hdr;
1589 	int status;
1590 
1591 	xdr_set_scratch_page(xdr, res->scratch);
1592 
1593 	status = decode_compound_hdr(xdr, &hdr);
1594 	if (status)
1595 		goto out;
1596 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1597 	if (status)
1598 		goto out;
1599 	status = decode_putfh(xdr);
1600 	if (status)
1601 		goto out;
1602 	status = decode_listxattrs(xdr, res);
1603 out:
1604 	return status;
1605 }
1606 
1607 static void nfs4_xdr_enc_removexattr(struct rpc_rqst *req,
1608 				     struct xdr_stream *xdr, const void *data)
1609 {
1610 	const struct nfs42_removexattrargs *args = data;
1611 	struct compound_hdr hdr = {
1612 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1613 	};
1614 
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);
1619 	encode_nops(&hdr);
1620 }
1621 
1622 static int nfs4_xdr_dec_removexattr(struct rpc_rqst *req,
1623 				    struct xdr_stream *xdr, void *data)
1624 {
1625 	struct nfs42_removexattrres *res = data;
1626 	struct compound_hdr hdr;
1627 	int status;
1628 
1629 	status = decode_compound_hdr(xdr, &hdr);
1630 	if (status)
1631 		goto out;
1632 	status = decode_sequence(xdr, &res->seq_res, req);
1633 	if (status)
1634 		goto out;
1635 	status = decode_putfh(xdr);
1636 	if (status)
1637 		goto out;
1638 
1639 	status = decode_removexattr(xdr, &res->cinfo);
1640 out:
1641 	return status;
1642 }
1643 #endif
1644 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */
1645