xref: /linux/fs/nfs/nfs42xdr.c (revision b85900e91c8402bedc1db14e6d293e26f25d30d4)
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 /* Not limited by NFS itself, limited by the generic xattr code */
11 #define nfs4_xattr_name_maxsz   XDR_QUADLEN(XATTR_NAME_MAX)
12 
13 #define encode_fallocate_maxsz		(encode_stateid_maxsz + \
14 					 2 /* offset */ + \
15 					 2 /* length */)
16 #define NFS42_WRITE_RES_SIZE		(1 /* wr_callback_id size */ +\
17 					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
18 					 2 /* wr_count */ + \
19 					 1 /* wr_committed */ + \
20 					 XDR_QUADLEN(NFS4_VERIFIER_SIZE))
21 #define encode_allocate_maxsz		(op_encode_hdr_maxsz + \
22 					 encode_fallocate_maxsz)
23 #define decode_allocate_maxsz		(op_decode_hdr_maxsz)
24 #define encode_copy_maxsz		(op_encode_hdr_maxsz +          \
25 					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
26 					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
27 					 2 + 2 + 2 + 1 + 1 + 1 +\
28 					 1 + /* One cnr_source_server */\
29 					 1 + /* nl4_type */ \
30 					 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
31 #define decode_copy_maxsz		(op_decode_hdr_maxsz + \
32 					 NFS42_WRITE_RES_SIZE + \
33 					 1 /* cr_consecutive */ + \
34 					 1 /* cr_synchronous */)
35 #define encode_offload_cancel_maxsz	(op_encode_hdr_maxsz + \
36 					 XDR_QUADLEN(NFS4_STATEID_SIZE))
37 #define decode_offload_cancel_maxsz	(op_decode_hdr_maxsz)
38 #define encode_offload_status_maxsz	(op_encode_hdr_maxsz + \
39 					 XDR_QUADLEN(NFS4_STATEID_SIZE))
40 #define decode_offload_status_maxsz	(op_decode_hdr_maxsz + \
41 					 2 /* osr_count */ + \
42 					 2 /* osr_complete */)
43 #define encode_copy_notify_maxsz	(op_encode_hdr_maxsz + \
44 					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
45 					 1 + /* nl4_type */ \
46 					 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
47 #define decode_copy_notify_maxsz	(op_decode_hdr_maxsz + \
48 					 3 + /* cnr_lease_time */\
49 					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
50 					 1 + /* Support 1 cnr_source_server */\
51 					 1 + /* nl4_type */ \
52 					 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
53 #define encode_deallocate_maxsz		(op_encode_hdr_maxsz + \
54 					 encode_fallocate_maxsz)
55 #define decode_deallocate_maxsz		(op_decode_hdr_maxsz)
56 #define encode_read_plus_maxsz		(op_encode_hdr_maxsz + \
57 					 encode_stateid_maxsz + 3)
58 #define NFS42_READ_PLUS_DATA_SEGMENT_SIZE \
59 					(1 /* data_content4 */ + \
60 					 2 /* data_info4.di_offset */ + \
61 					 1 /* data_info4.di_length */)
62 #define NFS42_READ_PLUS_HOLE_SEGMENT_SIZE \
63 					(1 /* data_content4 */ + \
64 					 2 /* data_info4.di_offset */ + \
65 					 2 /* data_info4.di_length */)
66 #define READ_PLUS_SEGMENT_SIZE_DIFF	(NFS42_READ_PLUS_HOLE_SEGMENT_SIZE - \
67 					 NFS42_READ_PLUS_DATA_SEGMENT_SIZE)
68 #define decode_read_plus_maxsz		(op_decode_hdr_maxsz + \
69 					 1 /* rpr_eof */ + \
70 					 1 /* rpr_contents count */ + \
71 					 NFS42_READ_PLUS_HOLE_SEGMENT_SIZE)
72 #define encode_seek_maxsz		(op_encode_hdr_maxsz + \
73 					 encode_stateid_maxsz + \
74 					 2 /* offset */ + \
75 					 1 /* whence */)
76 #define decode_seek_maxsz		(op_decode_hdr_maxsz + \
77 					 1 /* eof */ + \
78 					 1 /* whence */ + \
79 					 2 /* offset */ + \
80 					 2 /* length */)
81 #define encode_io_info_maxsz		4
82 #define encode_layoutstats_maxsz	(op_decode_hdr_maxsz + \
83 					2 /* offset */ + \
84 					2 /* length */ + \
85 					encode_stateid_maxsz + \
86 					encode_io_info_maxsz + \
87 					encode_io_info_maxsz + \
88 					1 /* opaque devaddr4 length */ + \
89 					XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE))
90 #define decode_layoutstats_maxsz	(op_decode_hdr_maxsz)
91 #define encode_device_error_maxsz	(XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \
92 					1 /* status */ + 1 /* opnum */)
93 #define encode_layouterror_maxsz	(op_decode_hdr_maxsz + \
94 					2 /* offset */ + \
95 					2 /* length */ + \
96 					encode_stateid_maxsz + \
97 					1 /* Array size */ + \
98 					encode_device_error_maxsz)
99 #define decode_layouterror_maxsz	(op_decode_hdr_maxsz)
100 #define encode_clone_maxsz		(encode_stateid_maxsz + \
101 					encode_stateid_maxsz + \
102 					2 /* src offset */ + \
103 					2 /* dst offset */ + \
104 					2 /* count */)
105 #define decode_clone_maxsz		(op_decode_hdr_maxsz)
106 #define encode_getxattr_maxsz		(op_encode_hdr_maxsz + 1 + \
107 					 nfs4_xattr_name_maxsz)
108 #define decode_getxattr_maxsz		(op_decode_hdr_maxsz + 1 + pagepad_maxsz)
109 #define encode_setxattr_maxsz		(op_encode_hdr_maxsz + \
110 					 1 + nfs4_xattr_name_maxsz + 1)
111 #define decode_setxattr_maxsz		(op_decode_hdr_maxsz + decode_change_info_maxsz)
112 #define encode_listxattrs_maxsz		(op_encode_hdr_maxsz + 2 + 1)
113 #define decode_listxattrs_maxsz		(op_decode_hdr_maxsz + 2 + 1 + 1 + 1)
114 #define encode_removexattr_maxsz	(op_encode_hdr_maxsz + 1 + \
115 					 nfs4_xattr_name_maxsz)
116 #define decode_removexattr_maxsz	(op_decode_hdr_maxsz + \
117 					 decode_change_info_maxsz)
118 
119 #define NFS4_enc_allocate_sz		(compound_encode_hdr_maxsz + \
120 					 encode_sequence_maxsz + \
121 					 encode_putfh_maxsz + \
122 					 encode_allocate_maxsz + \
123 					 encode_getattr_maxsz)
124 #define NFS4_dec_allocate_sz		(compound_decode_hdr_maxsz + \
125 					 decode_sequence_maxsz + \
126 					 decode_putfh_maxsz + \
127 					 decode_allocate_maxsz + \
128 					 decode_getattr_maxsz)
129 #define NFS4_enc_copy_sz		(compound_encode_hdr_maxsz + \
130 					 encode_sequence_maxsz + \
131 					 encode_putfh_maxsz + \
132 					 encode_savefh_maxsz + \
133 					 encode_putfh_maxsz + \
134 					 encode_copy_maxsz + \
135 					 encode_commit_maxsz)
136 #define NFS4_dec_copy_sz		(compound_decode_hdr_maxsz + \
137 					 decode_sequence_maxsz + \
138 					 decode_putfh_maxsz + \
139 					 decode_savefh_maxsz + \
140 					 decode_putfh_maxsz + \
141 					 decode_copy_maxsz + \
142 					 decode_commit_maxsz)
143 #define NFS4_enc_offload_cancel_sz	(compound_encode_hdr_maxsz + \
144 					 encode_sequence_maxsz + \
145 					 encode_putfh_maxsz + \
146 					 encode_offload_cancel_maxsz)
147 #define NFS4_dec_offload_cancel_sz	(compound_decode_hdr_maxsz + \
148 					 decode_sequence_maxsz + \
149 					 decode_putfh_maxsz + \
150 					 decode_offload_cancel_maxsz)
151 #define NFS4_enc_offload_status_sz	(compound_encode_hdr_maxsz + \
152 					 encode_sequence_maxsz + \
153 					 encode_putfh_maxsz + \
154 					 encode_offload_status_maxsz)
155 #define NFS4_dec_offload_status_sz	(compound_decode_hdr_maxsz + \
156 					 decode_sequence_maxsz + \
157 					 decode_putfh_maxsz + \
158 					 decode_offload_status_maxsz)
159 #define NFS4_enc_copy_notify_sz		(compound_encode_hdr_maxsz + \
160 					 encode_sequence_maxsz + \
161 					 encode_putfh_maxsz + \
162 					 encode_copy_notify_maxsz)
163 #define NFS4_dec_copy_notify_sz		(compound_decode_hdr_maxsz + \
164 					 decode_sequence_maxsz + \
165 					 decode_putfh_maxsz + \
166 					 decode_copy_notify_maxsz)
167 #define NFS4_enc_deallocate_sz		(compound_encode_hdr_maxsz + \
168 					 encode_sequence_maxsz + \
169 					 encode_putfh_maxsz + \
170 					 encode_deallocate_maxsz + \
171 					 encode_getattr_maxsz)
172 #define NFS4_dec_deallocate_sz		(compound_decode_hdr_maxsz + \
173 					 decode_sequence_maxsz + \
174 					 decode_putfh_maxsz + \
175 					 decode_deallocate_maxsz + \
176 					 decode_getattr_maxsz)
177 #define NFS4_enc_zero_range_sz		(compound_encode_hdr_maxsz + \
178 					 encode_sequence_maxsz + \
179 					 encode_putfh_maxsz + \
180 					 encode_deallocate_maxsz + \
181 					 encode_allocate_maxsz + \
182 					 encode_getattr_maxsz)
183 #define NFS4_dec_zero_range_sz		(compound_decode_hdr_maxsz + \
184 					 decode_sequence_maxsz + \
185 					 decode_putfh_maxsz + \
186 					 decode_deallocate_maxsz + \
187 					 decode_allocate_maxsz + \
188 					 decode_getattr_maxsz)
189 #define NFS4_enc_read_plus_sz		(compound_encode_hdr_maxsz + \
190 					 encode_sequence_maxsz + \
191 					 encode_putfh_maxsz + \
192 					 encode_read_plus_maxsz)
193 #define NFS4_dec_read_plus_sz		(compound_decode_hdr_maxsz + \
194 					 decode_sequence_maxsz + \
195 					 decode_putfh_maxsz + \
196 					 decode_read_plus_maxsz)
197 #define NFS4_enc_seek_sz		(compound_encode_hdr_maxsz + \
198 					 encode_sequence_maxsz + \
199 					 encode_putfh_maxsz + \
200 					 encode_seek_maxsz)
201 #define NFS4_dec_seek_sz		(compound_decode_hdr_maxsz + \
202 					 decode_sequence_maxsz + \
203 					 decode_putfh_maxsz + \
204 					 decode_seek_maxsz)
205 #define NFS4_enc_layoutstats_sz		(compound_encode_hdr_maxsz + \
206 					 encode_sequence_maxsz + \
207 					 encode_putfh_maxsz + \
208 					 PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz)
209 #define NFS4_dec_layoutstats_sz		(compound_decode_hdr_maxsz + \
210 					 decode_sequence_maxsz + \
211 					 decode_putfh_maxsz + \
212 					 PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz)
213 #define NFS4_enc_layouterror_sz		(compound_encode_hdr_maxsz + \
214 					 encode_sequence_maxsz + \
215 					 encode_putfh_maxsz + \
216 					 NFS42_LAYOUTERROR_MAX * \
217 					 encode_layouterror_maxsz)
218 #define NFS4_dec_layouterror_sz		(compound_decode_hdr_maxsz + \
219 					 decode_sequence_maxsz + \
220 					 decode_putfh_maxsz + \
221 					 NFS42_LAYOUTERROR_MAX * \
222 					 decode_layouterror_maxsz)
223 #define NFS4_enc_clone_sz		(compound_encode_hdr_maxsz + \
224 					 encode_sequence_maxsz + \
225 					 encode_putfh_maxsz + \
226 					 encode_savefh_maxsz + \
227 					 encode_putfh_maxsz + \
228 					 encode_clone_maxsz + \
229 					 encode_getattr_maxsz)
230 #define NFS4_dec_clone_sz		(compound_decode_hdr_maxsz + \
231 					 decode_sequence_maxsz + \
232 					 decode_putfh_maxsz + \
233 					 decode_savefh_maxsz + \
234 					 decode_putfh_maxsz + \
235 					 decode_clone_maxsz + \
236 					 decode_getattr_maxsz)
237 #define NFS4_enc_getxattr_sz		(compound_encode_hdr_maxsz + \
238 					 encode_sequence_maxsz + \
239 					 encode_putfh_maxsz + \
240 					 encode_getxattr_maxsz)
241 #define NFS4_dec_getxattr_sz		(compound_decode_hdr_maxsz + \
242 					 decode_sequence_maxsz + \
243 					 decode_putfh_maxsz + \
244 					 decode_getxattr_maxsz)
245 #define NFS4_enc_setxattr_sz		(compound_encode_hdr_maxsz + \
246 					 encode_sequence_maxsz + \
247 					 encode_putfh_maxsz + \
248 					 encode_setxattr_maxsz + \
249 					 encode_getattr_maxsz)
250 #define NFS4_dec_setxattr_sz		(compound_decode_hdr_maxsz + \
251 					 decode_sequence_maxsz + \
252 					 decode_putfh_maxsz + \
253 					 decode_setxattr_maxsz + \
254 					 decode_getattr_maxsz)
255 #define NFS4_enc_listxattrs_sz		(compound_encode_hdr_maxsz + \
256 					 encode_sequence_maxsz + \
257 					 encode_putfh_maxsz + \
258 					 encode_listxattrs_maxsz)
259 #define NFS4_dec_listxattrs_sz		(compound_decode_hdr_maxsz + \
260 					 decode_sequence_maxsz + \
261 					 decode_putfh_maxsz + \
262 					 decode_listxattrs_maxsz)
263 #define NFS4_enc_removexattr_sz		(compound_encode_hdr_maxsz + \
264 					 encode_sequence_maxsz + \
265 					 encode_putfh_maxsz + \
266 					 encode_removexattr_maxsz + \
267 					 encode_getattr_maxsz)
268 #define NFS4_dec_removexattr_sz		(compound_decode_hdr_maxsz + \
269 					 decode_sequence_maxsz + \
270 					 decode_putfh_maxsz + \
271 					 decode_removexattr_maxsz + \
272 					 decode_getattr_maxsz)
273 
274 /*
275  * These values specify the maximum amount of data that is not
276  * associated with the extended attribute name or extended
277  * attribute list in the SETXATTR, GETXATTR and LISTXATTR
278  * respectively.
279  */
280 const u32 nfs42_maxsetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
281 					compound_encode_hdr_maxsz +
282 					encode_sequence_maxsz +
283 					encode_putfh_maxsz + 1 +
284 					nfs4_xattr_name_maxsz)
285 					* XDR_UNIT);
286 
287 const u32 nfs42_maxgetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
288 					compound_decode_hdr_maxsz +
289 					decode_sequence_maxsz +
290 					decode_putfh_maxsz + 1) * XDR_UNIT);
291 
292 const u32 nfs42_maxlistxattrs_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
293 					compound_decode_hdr_maxsz +
294 					decode_sequence_maxsz +
295 					decode_putfh_maxsz + 3) * XDR_UNIT);
296 
encode_fallocate(struct xdr_stream * xdr,const struct nfs42_falloc_args * args)297 static void encode_fallocate(struct xdr_stream *xdr,
298 			     const struct nfs42_falloc_args *args)
299 {
300 	encode_nfs4_stateid(xdr, &args->falloc_stateid);
301 	encode_uint64(xdr, args->falloc_offset);
302 	encode_uint64(xdr, args->falloc_length);
303 }
304 
encode_allocate(struct xdr_stream * xdr,const struct nfs42_falloc_args * args,struct compound_hdr * hdr)305 static void encode_allocate(struct xdr_stream *xdr,
306 			    const struct nfs42_falloc_args *args,
307 			    struct compound_hdr *hdr)
308 {
309 	encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
310 	encode_fallocate(xdr, args);
311 }
312 
encode_nl4_server(struct xdr_stream * xdr,const struct nl4_server * ns)313 static void encode_nl4_server(struct xdr_stream *xdr,
314 			      const struct nl4_server *ns)
315 {
316 	encode_uint32(xdr, ns->nl4_type);
317 	switch (ns->nl4_type) {
318 	case NL4_NAME:
319 	case NL4_URL:
320 		encode_string(xdr, ns->u.nl4_str_sz, ns->u.nl4_str);
321 		break;
322 	case NL4_NETADDR:
323 		encode_string(xdr, ns->u.nl4_addr.netid_len,
324 			      ns->u.nl4_addr.netid);
325 		encode_string(xdr, ns->u.nl4_addr.addr_len,
326 			      ns->u.nl4_addr.addr);
327 		break;
328 	default:
329 		WARN_ON_ONCE(1);
330 	}
331 }
332 
encode_copy(struct xdr_stream * xdr,const struct nfs42_copy_args * args,struct compound_hdr * hdr)333 static void encode_copy(struct xdr_stream *xdr,
334 			const struct nfs42_copy_args *args,
335 			struct compound_hdr *hdr)
336 {
337 	encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr);
338 	encode_nfs4_stateid(xdr, &args->src_stateid);
339 	encode_nfs4_stateid(xdr, &args->dst_stateid);
340 
341 	encode_uint64(xdr, args->src_pos);
342 	encode_uint64(xdr, args->dst_pos);
343 	encode_uint64(xdr, args->count);
344 
345 	encode_uint32(xdr, 1); /* consecutive = true */
346 	encode_uint32(xdr, args->sync);
347 	if (args->cp_src == NULL) { /* intra-ssc */
348 		encode_uint32(xdr, 0); /* no src server list */
349 		return;
350 	}
351 	encode_uint32(xdr, 1); /* supporting 1 server */
352 	encode_nl4_server(xdr, args->cp_src);
353 }
354 
encode_copy_commit(struct xdr_stream * xdr,const struct nfs42_copy_args * args,struct compound_hdr * hdr)355 static void encode_copy_commit(struct xdr_stream *xdr,
356 			  const struct nfs42_copy_args *args,
357 			  struct compound_hdr *hdr)
358 {
359 	__be32 *p;
360 
361 	encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr);
362 	p = reserve_space(xdr, 12);
363 	p = xdr_encode_hyper(p, args->dst_pos);
364 	*p = cpu_to_be32(args->count);
365 }
366 
encode_offload_cancel(struct xdr_stream * xdr,const struct nfs42_offload_status_args * args,struct compound_hdr * hdr)367 static void encode_offload_cancel(struct xdr_stream *xdr,
368 				  const struct nfs42_offload_status_args *args,
369 				  struct compound_hdr *hdr)
370 {
371 	encode_op_hdr(xdr, OP_OFFLOAD_CANCEL, decode_offload_cancel_maxsz, hdr);
372 	encode_nfs4_stateid(xdr, &args->osa_stateid);
373 }
374 
encode_offload_status(struct xdr_stream * xdr,const struct nfs42_offload_status_args * args,struct compound_hdr * hdr)375 static void encode_offload_status(struct xdr_stream *xdr,
376 				  const struct nfs42_offload_status_args *args,
377 				  struct compound_hdr *hdr)
378 {
379 	encode_op_hdr(xdr, OP_OFFLOAD_STATUS, decode_offload_status_maxsz, hdr);
380 	encode_nfs4_stateid(xdr, &args->osa_stateid);
381 }
382 
encode_copy_notify(struct xdr_stream * xdr,const struct nfs42_copy_notify_args * args,struct compound_hdr * hdr)383 static void encode_copy_notify(struct xdr_stream *xdr,
384 			       const struct nfs42_copy_notify_args *args,
385 			       struct compound_hdr *hdr)
386 {
387 	encode_op_hdr(xdr, OP_COPY_NOTIFY, decode_copy_notify_maxsz, hdr);
388 	encode_nfs4_stateid(xdr, &args->cna_src_stateid);
389 	encode_nl4_server(xdr, &args->cna_dst);
390 }
391 
encode_deallocate(struct xdr_stream * xdr,const struct nfs42_falloc_args * args,struct compound_hdr * hdr)392 static void encode_deallocate(struct xdr_stream *xdr,
393 			      const struct nfs42_falloc_args *args,
394 			      struct compound_hdr *hdr)
395 {
396 	encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
397 	encode_fallocate(xdr, args);
398 }
399 
encode_read_plus(struct xdr_stream * xdr,const struct nfs_pgio_args * args,struct compound_hdr * hdr)400 static void encode_read_plus(struct xdr_stream *xdr,
401 			     const struct nfs_pgio_args *args,
402 			     struct compound_hdr *hdr)
403 {
404 	encode_op_hdr(xdr, OP_READ_PLUS, decode_read_plus_maxsz, hdr);
405 	encode_nfs4_stateid(xdr, &args->stateid);
406 	encode_uint64(xdr, args->offset);
407 	encode_uint32(xdr, args->count);
408 }
409 
encode_seek(struct xdr_stream * xdr,const struct nfs42_seek_args * args,struct compound_hdr * hdr)410 static void encode_seek(struct xdr_stream *xdr,
411 			const struct nfs42_seek_args *args,
412 			struct compound_hdr *hdr)
413 {
414 	encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr);
415 	encode_nfs4_stateid(xdr, &args->sa_stateid);
416 	encode_uint64(xdr, args->sa_offset);
417 	encode_uint32(xdr, args->sa_what);
418 }
419 
encode_layoutstats(struct xdr_stream * xdr,const struct nfs42_layoutstat_args * args,struct nfs42_layoutstat_devinfo * devinfo,struct compound_hdr * hdr)420 static void encode_layoutstats(struct xdr_stream *xdr,
421 			       const struct nfs42_layoutstat_args *args,
422 			       struct nfs42_layoutstat_devinfo *devinfo,
423 			       struct compound_hdr *hdr)
424 {
425 	__be32 *p;
426 
427 	encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr);
428 	p = reserve_space(xdr, 8 + 8);
429 	p = xdr_encode_hyper(p, devinfo->offset);
430 	p = xdr_encode_hyper(p, devinfo->length);
431 	encode_nfs4_stateid(xdr, &args->stateid);
432 	p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4);
433 	p = xdr_encode_hyper(p, devinfo->read_count);
434 	p = xdr_encode_hyper(p, devinfo->read_bytes);
435 	p = xdr_encode_hyper(p, devinfo->write_count);
436 	p = xdr_encode_hyper(p, devinfo->write_bytes);
437 	p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data,
438 			NFS4_DEVICEID4_SIZE);
439 	/* Encode layoutupdate4 */
440 	*p++ = cpu_to_be32(devinfo->layout_type);
441 	if (devinfo->ld_private.ops)
442 		devinfo->ld_private.ops->encode(xdr, args,
443 				&devinfo->ld_private);
444 	else
445 		encode_uint32(xdr, 0);
446 }
447 
encode_clone(struct xdr_stream * xdr,const struct nfs42_clone_args * args,struct compound_hdr * hdr)448 static void encode_clone(struct xdr_stream *xdr,
449 			 const struct nfs42_clone_args *args,
450 			 struct compound_hdr *hdr)
451 {
452 	__be32 *p;
453 
454 	encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr);
455 	encode_nfs4_stateid(xdr, &args->src_stateid);
456 	encode_nfs4_stateid(xdr, &args->dst_stateid);
457 	p = reserve_space(xdr, 3*8);
458 	p = xdr_encode_hyper(p, args->src_offset);
459 	p = xdr_encode_hyper(p, args->dst_offset);
460 	xdr_encode_hyper(p, args->count);
461 }
462 
encode_device_error(struct xdr_stream * xdr,const struct nfs42_device_error * error)463 static void encode_device_error(struct xdr_stream *xdr,
464 				const struct nfs42_device_error *error)
465 {
466 	__be32 *p;
467 
468 	p = reserve_space(xdr, NFS4_DEVICEID4_SIZE + 2*4);
469 	p = xdr_encode_opaque_fixed(p, error->dev_id.data,
470 			NFS4_DEVICEID4_SIZE);
471 	*p++ = cpu_to_be32(error->status);
472 	*p = cpu_to_be32(error->opnum);
473 }
474 
encode_layouterror(struct xdr_stream * xdr,const struct nfs42_layout_error * args,struct compound_hdr * hdr)475 static void encode_layouterror(struct xdr_stream *xdr,
476 			       const struct nfs42_layout_error *args,
477 			       struct compound_hdr *hdr)
478 {
479 	__be32 *p;
480 
481 	encode_op_hdr(xdr, OP_LAYOUTERROR, decode_layouterror_maxsz, hdr);
482 	p = reserve_space(xdr, 8 + 8);
483 	p = xdr_encode_hyper(p, args->offset);
484 	p = xdr_encode_hyper(p, args->length);
485 	encode_nfs4_stateid(xdr, &args->stateid);
486 	p = reserve_space(xdr, 4);
487 	*p = cpu_to_be32(1);
488 	encode_device_error(xdr, &args->errors[0]);
489 }
490 
encode_setxattr(struct xdr_stream * xdr,const struct nfs42_setxattrargs * arg,struct compound_hdr * hdr)491 static void encode_setxattr(struct xdr_stream *xdr,
492 			    const struct nfs42_setxattrargs *arg,
493 			    struct compound_hdr *hdr)
494 {
495 	__be32 *p;
496 
497 	BUILD_BUG_ON(XATTR_CREATE != SETXATTR4_CREATE);
498 	BUILD_BUG_ON(XATTR_REPLACE != SETXATTR4_REPLACE);
499 
500 	encode_op_hdr(xdr, OP_SETXATTR, decode_setxattr_maxsz, hdr);
501 	p = reserve_space(xdr, 4);
502 	*p = cpu_to_be32(arg->xattr_flags);
503 	encode_string(xdr, strlen(arg->xattr_name), arg->xattr_name);
504 	p = reserve_space(xdr, 4);
505 	*p = cpu_to_be32(arg->xattr_len);
506 	if (arg->xattr_len)
507 		xdr_write_pages(xdr, arg->xattr_pages, 0, arg->xattr_len);
508 }
509 
encode_getxattr(struct xdr_stream * xdr,const char * name,struct compound_hdr * hdr)510 static void encode_getxattr(struct xdr_stream *xdr, const char *name,
511 			    struct compound_hdr *hdr)
512 {
513 	encode_op_hdr(xdr, OP_GETXATTR, decode_getxattr_maxsz, hdr);
514 	encode_string(xdr, strlen(name), name);
515 }
516 
encode_removexattr(struct xdr_stream * xdr,const char * name,struct compound_hdr * hdr)517 static void encode_removexattr(struct xdr_stream *xdr, const char *name,
518 			       struct compound_hdr *hdr)
519 {
520 	encode_op_hdr(xdr, OP_REMOVEXATTR, decode_removexattr_maxsz, hdr);
521 	encode_string(xdr, strlen(name), name);
522 }
523 
encode_listxattrs(struct xdr_stream * xdr,const struct nfs42_listxattrsargs * arg,struct compound_hdr * hdr)524 static void encode_listxattrs(struct xdr_stream *xdr,
525 			     const struct nfs42_listxattrsargs *arg,
526 			     struct compound_hdr *hdr)
527 {
528 	__be32 *p;
529 
530 	encode_op_hdr(xdr, OP_LISTXATTRS, decode_listxattrs_maxsz, hdr);
531 
532 	p = reserve_space(xdr, 12);
533 	if (unlikely(!p))
534 		return;
535 
536 	p = xdr_encode_hyper(p, arg->cookie);
537 	/*
538 	 * RFC 8276 says to specify the full max length of the LISTXATTRS
539 	 * XDR reply. Count is set to the XDR length of the names array
540 	 * plus the EOF marker. So, add the cookie and the names count.
541 	 */
542 	*p = cpu_to_be32(arg->count + 8 + 4);
543 }
544 
545 /*
546  * Encode ALLOCATE request
547  */
nfs4_xdr_enc_allocate(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)548 static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
549 				  struct xdr_stream *xdr,
550 				  const void *data)
551 {
552 	const struct nfs42_falloc_args *args = data;
553 	struct compound_hdr hdr = {
554 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
555 	};
556 
557 	encode_compound_hdr(xdr, req, &hdr);
558 	encode_sequence(xdr, &args->seq_args, &hdr);
559 	encode_putfh(xdr, args->falloc_fh, &hdr);
560 	encode_allocate(xdr, args, &hdr);
561 	encode_getfattr(xdr, args->falloc_bitmask, &hdr);
562 	encode_nops(&hdr);
563 }
564 
565 /*
566  * Encode COPY request
567  */
nfs4_xdr_enc_copy(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)568 static void nfs4_xdr_enc_copy(struct rpc_rqst *req,
569 			      struct xdr_stream *xdr,
570 			      const void *data)
571 {
572 	const struct nfs42_copy_args *args = data;
573 	struct compound_hdr hdr = {
574 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
575 	};
576 
577 	encode_compound_hdr(xdr, req, &hdr);
578 	encode_sequence(xdr, &args->seq_args, &hdr);
579 	encode_putfh(xdr, args->src_fh, &hdr);
580 	encode_savefh(xdr, &hdr);
581 	encode_putfh(xdr, args->dst_fh, &hdr);
582 	encode_copy(xdr, args, &hdr);
583 	if (args->sync)
584 		encode_copy_commit(xdr, args, &hdr);
585 	encode_nops(&hdr);
586 }
587 
588 /*
589  * Encode OFFLOAD_CANCEL request
590  */
nfs4_xdr_enc_offload_cancel(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)591 static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req,
592 					struct xdr_stream *xdr,
593 					const void *data)
594 {
595 	const struct nfs42_offload_status_args *args = data;
596 	struct compound_hdr hdr = {
597 		.minorversion = nfs4_xdr_minorversion(&args->osa_seq_args),
598 	};
599 
600 	encode_compound_hdr(xdr, req, &hdr);
601 	encode_sequence(xdr, &args->osa_seq_args, &hdr);
602 	encode_putfh(xdr, args->osa_src_fh, &hdr);
603 	encode_offload_cancel(xdr, args, &hdr);
604 	encode_nops(&hdr);
605 }
606 
607 /*
608  * Encode OFFLOAD_STATUS request
609  */
nfs4_xdr_enc_offload_status(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)610 static void nfs4_xdr_enc_offload_status(struct rpc_rqst *req,
611 					struct xdr_stream *xdr,
612 					const void *data)
613 {
614 	const struct nfs42_offload_status_args *args = data;
615 	struct compound_hdr hdr = {
616 		.minorversion = nfs4_xdr_minorversion(&args->osa_seq_args),
617 	};
618 
619 	encode_compound_hdr(xdr, req, &hdr);
620 	encode_sequence(xdr, &args->osa_seq_args, &hdr);
621 	encode_putfh(xdr, args->osa_src_fh, &hdr);
622 	encode_offload_status(xdr, args, &hdr);
623 	encode_nops(&hdr);
624 }
625 
626 /*
627  * Encode COPY_NOTIFY request
628  */
nfs4_xdr_enc_copy_notify(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)629 static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req,
630 				     struct xdr_stream *xdr,
631 				     const void *data)
632 {
633 	const struct nfs42_copy_notify_args *args = data;
634 	struct compound_hdr hdr = {
635 		.minorversion = nfs4_xdr_minorversion(&args->cna_seq_args),
636 	};
637 
638 	encode_compound_hdr(xdr, req, &hdr);
639 	encode_sequence(xdr, &args->cna_seq_args, &hdr);
640 	encode_putfh(xdr, args->cna_src_fh, &hdr);
641 	encode_copy_notify(xdr, args, &hdr);
642 	encode_nops(&hdr);
643 }
644 
645 /*
646  * Encode DEALLOCATE request
647  */
nfs4_xdr_enc_deallocate(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)648 static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
649 				    struct xdr_stream *xdr,
650 				    const void *data)
651 {
652 	const struct nfs42_falloc_args *args = data;
653 	struct compound_hdr hdr = {
654 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
655 	};
656 
657 	encode_compound_hdr(xdr, req, &hdr);
658 	encode_sequence(xdr, &args->seq_args, &hdr);
659 	encode_putfh(xdr, args->falloc_fh, &hdr);
660 	encode_deallocate(xdr, args, &hdr);
661 	encode_getfattr(xdr, args->falloc_bitmask, &hdr);
662 	encode_nops(&hdr);
663 }
664 
665 /*
666  * Encode ZERO_RANGE request
667  */
nfs4_xdr_enc_zero_range(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)668 static void nfs4_xdr_enc_zero_range(struct rpc_rqst *req,
669 				    struct xdr_stream *xdr,
670 				    const void *data)
671 {
672 	const struct nfs42_falloc_args *args = data;
673 	struct compound_hdr hdr = {
674 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
675 	};
676 
677 	encode_compound_hdr(xdr, req, &hdr);
678 	encode_sequence(xdr, &args->seq_args, &hdr);
679 	encode_putfh(xdr, args->falloc_fh, &hdr);
680 	encode_deallocate(xdr, args, &hdr);
681 	encode_allocate(xdr, args, &hdr);
682 	encode_getfattr(xdr, args->falloc_bitmask, &hdr);
683 	encode_nops(&hdr);
684 }
685 
686 /*
687  * Encode READ_PLUS request
688  */
nfs4_xdr_enc_read_plus(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)689 static void nfs4_xdr_enc_read_plus(struct rpc_rqst *req,
690 				   struct xdr_stream *xdr,
691 				   const void *data)
692 {
693 	const struct nfs_pgio_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->fh, &hdr);
701 	encode_read_plus(xdr, args, &hdr);
702 
703 	rpc_prepare_reply_pages(req, args->pages, args->pgbase, args->count,
704 				hdr.replen - READ_PLUS_SEGMENT_SIZE_DIFF);
705 	encode_nops(&hdr);
706 }
707 
708 /*
709  * Encode SEEK request
710  */
nfs4_xdr_enc_seek(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)711 static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
712 			      struct xdr_stream *xdr,
713 			      const void *data)
714 {
715 	const struct nfs42_seek_args *args = data;
716 	struct compound_hdr hdr = {
717 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
718 	};
719 
720 	encode_compound_hdr(xdr, req, &hdr);
721 	encode_sequence(xdr, &args->seq_args, &hdr);
722 	encode_putfh(xdr, args->sa_fh, &hdr);
723 	encode_seek(xdr, args, &hdr);
724 	encode_nops(&hdr);
725 }
726 
727 /*
728  * Encode LAYOUTSTATS request
729  */
nfs4_xdr_enc_layoutstats(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)730 static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req,
731 				     struct xdr_stream *xdr,
732 				     const void *data)
733 {
734 	const struct nfs42_layoutstat_args *args = data;
735 	int i;
736 
737 	struct compound_hdr hdr = {
738 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
739 	};
740 
741 	encode_compound_hdr(xdr, req, &hdr);
742 	encode_sequence(xdr, &args->seq_args, &hdr);
743 	encode_putfh(xdr, args->fh, &hdr);
744 	WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
745 	for (i = 0; i < args->num_dev; i++)
746 		encode_layoutstats(xdr, args, &args->devinfo[i], &hdr);
747 	encode_nops(&hdr);
748 }
749 
750 /*
751  * Encode CLONE request
752  */
nfs4_xdr_enc_clone(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)753 static void nfs4_xdr_enc_clone(struct rpc_rqst *req,
754 			       struct xdr_stream *xdr,
755 			       const void *data)
756 {
757 	const struct nfs42_clone_args *args = data;
758 	struct compound_hdr hdr = {
759 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
760 	};
761 
762 	encode_compound_hdr(xdr, req, &hdr);
763 	encode_sequence(xdr, &args->seq_args, &hdr);
764 	encode_putfh(xdr, args->src_fh, &hdr);
765 	encode_savefh(xdr, &hdr);
766 	encode_putfh(xdr, args->dst_fh, &hdr);
767 	encode_clone(xdr, args, &hdr);
768 	encode_getfattr(xdr, args->dst_bitmask, &hdr);
769 	encode_nops(&hdr);
770 }
771 
772 /*
773  * Encode LAYOUTERROR request
774  */
nfs4_xdr_enc_layouterror(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)775 static void nfs4_xdr_enc_layouterror(struct rpc_rqst *req,
776 				     struct xdr_stream *xdr,
777 				     const void *data)
778 {
779 	const struct nfs42_layouterror_args *args = data;
780 	struct compound_hdr hdr = {
781 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
782 	};
783 	int i;
784 
785 	encode_compound_hdr(xdr, req, &hdr);
786 	encode_sequence(xdr, &args->seq_args, &hdr);
787 	encode_putfh(xdr, NFS_FH(args->inode), &hdr);
788 	for (i = 0; i < args->num_errors; i++)
789 		encode_layouterror(xdr, &args->errors[i], &hdr);
790 	encode_nops(&hdr);
791 }
792 
793 /*
794  * Encode SETXATTR request
795  */
nfs4_xdr_enc_setxattr(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)796 static void nfs4_xdr_enc_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
797 				  const void *data)
798 {
799 	const struct nfs42_setxattrargs *args = data;
800 	struct compound_hdr hdr = {
801 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
802 	};
803 
804 	encode_compound_hdr(xdr, req, &hdr);
805 	encode_sequence(xdr, &args->seq_args, &hdr);
806 	encode_putfh(xdr, args->fh, &hdr);
807 	encode_setxattr(xdr, args, &hdr);
808 	encode_getfattr(xdr, args->bitmask, &hdr);
809 	encode_nops(&hdr);
810 }
811 
812 /*
813  * Encode GETXATTR request
814  */
nfs4_xdr_enc_getxattr(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)815 static void nfs4_xdr_enc_getxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
816 				  const void *data)
817 {
818 	const struct nfs42_getxattrargs *args = data;
819 	struct compound_hdr hdr = {
820 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
821 	};
822 	uint32_t replen;
823 
824 	encode_compound_hdr(xdr, req, &hdr);
825 	encode_sequence(xdr, &args->seq_args, &hdr);
826 	encode_putfh(xdr, args->fh, &hdr);
827 	replen = hdr.replen + op_decode_hdr_maxsz + 1;
828 	encode_getxattr(xdr, args->xattr_name, &hdr);
829 
830 	rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->xattr_len,
831 				replen);
832 
833 	encode_nops(&hdr);
834 }
835 
836 /*
837  * Encode LISTXATTR request
838  */
nfs4_xdr_enc_listxattrs(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)839 static void nfs4_xdr_enc_listxattrs(struct rpc_rqst *req,
840 				    struct xdr_stream *xdr, const void *data)
841 {
842 	const struct nfs42_listxattrsargs *args = data;
843 	struct compound_hdr hdr = {
844 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
845 	};
846 	uint32_t replen;
847 
848 	encode_compound_hdr(xdr, req, &hdr);
849 	encode_sequence(xdr, &args->seq_args, &hdr);
850 	encode_putfh(xdr, args->fh, &hdr);
851 	replen = hdr.replen + op_decode_hdr_maxsz + 2 + 1;
852 	encode_listxattrs(xdr, args, &hdr);
853 
854 	rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->count, replen);
855 
856 	encode_nops(&hdr);
857 }
858 
859 /*
860  * Encode REMOVEXATTR request
861  */
nfs4_xdr_enc_removexattr(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)862 static void nfs4_xdr_enc_removexattr(struct rpc_rqst *req,
863 				     struct xdr_stream *xdr, const void *data)
864 {
865 	const struct nfs42_removexattrargs *args = data;
866 	struct compound_hdr hdr = {
867 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
868 	};
869 
870 	encode_compound_hdr(xdr, req, &hdr);
871 	encode_sequence(xdr, &args->seq_args, &hdr);
872 	encode_putfh(xdr, args->fh, &hdr);
873 	encode_removexattr(xdr, args->xattr_name, &hdr);
874 	encode_getfattr(xdr, args->bitmask, &hdr);
875 	encode_nops(&hdr);
876 }
877 
decode_allocate(struct xdr_stream * xdr,struct nfs42_falloc_res * res)878 static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
879 {
880 	return decode_op_hdr(xdr, OP_ALLOCATE);
881 }
882 
decode_write_response(struct xdr_stream * xdr,struct nfs42_write_res * res)883 static int decode_write_response(struct xdr_stream *xdr,
884 				 struct nfs42_write_res *res)
885 {
886 	__be32 *p;
887 	int status, count;
888 
889 	p = xdr_inline_decode(xdr, 4);
890 	if (unlikely(!p))
891 		return -EIO;
892 	count = be32_to_cpup(p);
893 	if (count > 1)
894 		return -EREMOTEIO;
895 	else if (count == 1) {
896 		status = decode_opaque_fixed(xdr, &res->stateid,
897 				NFS4_STATEID_SIZE);
898 		if (unlikely(status))
899 			return -EIO;
900 	}
901 	p = xdr_inline_decode(xdr, 8 + 4);
902 	if (unlikely(!p))
903 		return -EIO;
904 	p = xdr_decode_hyper(p, &res->count);
905 	res->verifier.committed = be32_to_cpup(p);
906 	return decode_verifier(xdr, &res->verifier.verifier);
907 }
908 
decode_nl4_server(struct xdr_stream * xdr,struct nl4_server * ns)909 static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns)
910 {
911 	struct nfs42_netaddr *naddr;
912 	uint32_t dummy;
913 	char *dummy_str;
914 	__be32 *p;
915 	int status;
916 
917 	/* nl_type */
918 	p = xdr_inline_decode(xdr, 4);
919 	if (unlikely(!p))
920 		return -EIO;
921 	ns->nl4_type = be32_to_cpup(p);
922 	switch (ns->nl4_type) {
923 	case NL4_NAME:
924 	case NL4_URL:
925 		status = decode_opaque_inline(xdr, &dummy, &dummy_str);
926 		if (unlikely(status))
927 			return status;
928 		if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
929 			return -EIO;
930 		memcpy(&ns->u.nl4_str, dummy_str, dummy);
931 		ns->u.nl4_str_sz = dummy;
932 		break;
933 	case NL4_NETADDR:
934 		naddr = &ns->u.nl4_addr;
935 
936 		/* netid string */
937 		status = decode_opaque_inline(xdr, &dummy, &dummy_str);
938 		if (unlikely(status))
939 			return status;
940 		if (unlikely(dummy > RPCBIND_MAXNETIDLEN))
941 			return -EIO;
942 		naddr->netid_len = dummy;
943 		memcpy(naddr->netid, dummy_str, naddr->netid_len);
944 
945 		/* uaddr string */
946 		status = decode_opaque_inline(xdr, &dummy, &dummy_str);
947 		if (unlikely(status))
948 			return status;
949 		if (unlikely(dummy > RPCBIND_MAXUADDRLEN))
950 			return -EIO;
951 		naddr->addr_len = dummy;
952 		memcpy(naddr->addr, dummy_str, naddr->addr_len);
953 		break;
954 	default:
955 		WARN_ON_ONCE(1);
956 		return -EIO;
957 	}
958 	return 0;
959 }
960 
decode_copy_requirements(struct xdr_stream * xdr,struct nfs42_copy_res * res)961 static int decode_copy_requirements(struct xdr_stream *xdr,
962 				    struct nfs42_copy_res *res) {
963 	__be32 *p;
964 
965 	p = xdr_inline_decode(xdr, 4 + 4);
966 	if (unlikely(!p))
967 		return -EIO;
968 
969 	res->consecutive = be32_to_cpup(p++);
970 	res->synchronous = be32_to_cpup(p++);
971 	return 0;
972 }
973 
decode_copy(struct xdr_stream * xdr,struct nfs42_copy_res * res)974 static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res)
975 {
976 	int status;
977 
978 	status = decode_op_hdr(xdr, OP_COPY);
979 	if (status == NFS4ERR_OFFLOAD_NO_REQS) {
980 		status = decode_copy_requirements(xdr, res);
981 		if (status)
982 			return status;
983 		return NFS4ERR_OFFLOAD_NO_REQS;
984 	} else if (status)
985 		return status;
986 
987 	status = decode_write_response(xdr, &res->write_res);
988 	if (status)
989 		return status;
990 
991 	return decode_copy_requirements(xdr, res);
992 }
993 
decode_offload_cancel(struct xdr_stream * xdr,struct nfs42_offload_status_res * res)994 static int decode_offload_cancel(struct xdr_stream *xdr,
995 				 struct nfs42_offload_status_res *res)
996 {
997 	return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);
998 }
999 
decode_offload_status(struct xdr_stream * xdr,struct nfs42_offload_status_res * res)1000 static int decode_offload_status(struct xdr_stream *xdr,
1001 				 struct nfs42_offload_status_res *res)
1002 {
1003 	ssize_t result;
1004 	int status;
1005 
1006 	status = decode_op_hdr(xdr, OP_OFFLOAD_STATUS);
1007 	if (status)
1008 		return status;
1009 	/* osr_count */
1010 	if (xdr_stream_decode_u64(xdr, &res->osr_count) < 0)
1011 		return -EIO;
1012 	/* osr_complete<1> */
1013 	result = xdr_stream_decode_uint32_array(xdr, &res->osr_complete, 1);
1014 	if (result < 0)
1015 		return -EIO;
1016 	res->complete_count = result;
1017 	return 0;
1018 }
1019 
decode_copy_notify(struct xdr_stream * xdr,struct nfs42_copy_notify_res * res)1020 static int decode_copy_notify(struct xdr_stream *xdr,
1021 			      struct nfs42_copy_notify_res *res)
1022 {
1023 	__be32 *p;
1024 	int status, count;
1025 
1026 	status = decode_op_hdr(xdr, OP_COPY_NOTIFY);
1027 	if (status)
1028 		return status;
1029 	/* cnr_lease_time */
1030 	p = xdr_inline_decode(xdr, 12);
1031 	if (unlikely(!p))
1032 		return -EIO;
1033 	p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds);
1034 	res->cnr_lease_time.nseconds = be32_to_cpup(p);
1035 
1036 	status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE);
1037 	if (unlikely(status))
1038 		return -EIO;
1039 
1040 	/* number of source addresses */
1041 	p = xdr_inline_decode(xdr, 4);
1042 	if (unlikely(!p))
1043 		return -EIO;
1044 
1045 	count = be32_to_cpup(p);
1046 	if (count > 1)
1047 		pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n",
1048 			 __func__, count);
1049 
1050 	status = decode_nl4_server(xdr, &res->cnr_src);
1051 	if (unlikely(status))
1052 		return -EIO;
1053 	return 0;
1054 }
1055 
decode_deallocate(struct xdr_stream * xdr,struct nfs42_falloc_res * res)1056 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
1057 {
1058 	return decode_op_hdr(xdr, OP_DEALLOCATE);
1059 }
1060 
1061 struct read_plus_segment {
1062 	enum data_content4 type;
1063 	uint64_t offset;
1064 	union {
1065 		struct {
1066 			uint64_t length;
1067 		} hole;
1068 
1069 		struct {
1070 			uint32_t length;
1071 			unsigned int from;
1072 		} data;
1073 	};
1074 };
1075 
read_plus_segment_length(struct read_plus_segment * seg)1076 static inline uint64_t read_plus_segment_length(struct read_plus_segment *seg)
1077 {
1078 	return seg->type == NFS4_CONTENT_DATA ? seg->data.length : seg->hole.length;
1079 }
1080 
decode_read_plus_segment(struct xdr_stream * xdr,struct read_plus_segment * seg)1081 static int decode_read_plus_segment(struct xdr_stream *xdr,
1082 				    struct read_plus_segment *seg)
1083 {
1084 	__be32 *p;
1085 
1086 	p = xdr_inline_decode(xdr, 4);
1087 	if (!p)
1088 		return -EIO;
1089 	seg->type = be32_to_cpup(p++);
1090 
1091 	p = xdr_inline_decode(xdr, seg->type == NFS4_CONTENT_DATA ? 12 : 16);
1092 	if (!p)
1093 		return -EIO;
1094 	p = xdr_decode_hyper(p, &seg->offset);
1095 
1096 	if (seg->type == NFS4_CONTENT_DATA) {
1097 		struct xdr_buf buf;
1098 		uint32_t len = be32_to_cpup(p);
1099 
1100 		seg->data.length = len;
1101 		seg->data.from = xdr_stream_pos(xdr);
1102 
1103 		if (!xdr_stream_subsegment(xdr, &buf, xdr_align_size(len)))
1104 			return -EIO;
1105 	} else if (seg->type == NFS4_CONTENT_HOLE) {
1106 		xdr_decode_hyper(p, &seg->hole.length);
1107 	} else
1108 		return -EINVAL;
1109 	return 0;
1110 }
1111 
process_read_plus_segment(struct xdr_stream * xdr,struct nfs_pgio_args * args,struct nfs_pgio_res * res,struct read_plus_segment * seg)1112 static int process_read_plus_segment(struct xdr_stream *xdr,
1113 				     struct nfs_pgio_args *args,
1114 				     struct nfs_pgio_res *res,
1115 				     struct read_plus_segment *seg)
1116 {
1117 	unsigned long offset = seg->offset;
1118 	unsigned long length = read_plus_segment_length(seg);
1119 	unsigned int bufpos;
1120 
1121 	if (offset + length < args->offset)
1122 		return 0;
1123 	else if (offset > args->offset + args->count) {
1124 		res->eof = 0;
1125 		return 0;
1126 	} else if (offset < args->offset) {
1127 		length -= (args->offset - offset);
1128 		offset = args->offset;
1129 	} else if (offset + length > args->offset + args->count) {
1130 		length = (args->offset + args->count) - offset;
1131 		res->eof = 0;
1132 	}
1133 
1134 	bufpos = xdr->buf->head[0].iov_len + (offset - args->offset);
1135 	if (seg->type == NFS4_CONTENT_HOLE)
1136 		return xdr_stream_zero(xdr, bufpos, length);
1137 	else
1138 		return xdr_stream_move_subsegment(xdr, seg->data.from, bufpos, length);
1139 }
1140 
decode_read_plus(struct xdr_stream * xdr,struct nfs_pgio_res * res)1141 static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
1142 {
1143 	struct nfs_pgio_header *hdr =
1144 		container_of(res, struct nfs_pgio_header, res);
1145 	struct nfs_pgio_args *args = &hdr->args;
1146 	uint32_t segments;
1147 	struct read_plus_segment *segs;
1148 	int status, i;
1149 	__be32 *p;
1150 
1151 	status = decode_op_hdr(xdr, OP_READ_PLUS);
1152 	if (status)
1153 		return status;
1154 
1155 	p = xdr_inline_decode(xdr, 4 + 4);
1156 	if (unlikely(!p))
1157 		return -EIO;
1158 
1159 	res->count = 0;
1160 	res->eof = be32_to_cpup(p++);
1161 	segments = be32_to_cpup(p++);
1162 	if (segments == 0)
1163 		return 0;
1164 
1165 	segs = kmalloc_objs(*segs, segments);
1166 	if (!segs)
1167 		return -ENOMEM;
1168 
1169 	for (i = 0; i < segments; i++) {
1170 		status = decode_read_plus_segment(xdr, &segs[i]);
1171 		if (status < 0)
1172 			goto out;
1173 	}
1174 
1175 	xdr_set_pagelen(xdr, xdr_align_size(args->count));
1176 	for (i = segments; i > 0; i--)
1177 		res->count += process_read_plus_segment(xdr, args, res, &segs[i-1]);
1178 	status = 0;
1179 
1180 out:
1181 	kfree(segs);
1182 	return status;
1183 }
1184 
decode_seek(struct xdr_stream * xdr,struct nfs42_seek_res * res)1185 static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
1186 {
1187 	int status;
1188 	__be32 *p;
1189 
1190 	status = decode_op_hdr(xdr, OP_SEEK);
1191 	if (status)
1192 		return status;
1193 
1194 	p = xdr_inline_decode(xdr, 4 + 8);
1195 	if (unlikely(!p))
1196 		return -EIO;
1197 
1198 	res->sr_eof = be32_to_cpup(p++);
1199 	p = xdr_decode_hyper(p, &res->sr_offset);
1200 	return 0;
1201 }
1202 
decode_layoutstats(struct xdr_stream * xdr)1203 static int decode_layoutstats(struct xdr_stream *xdr)
1204 {
1205 	return decode_op_hdr(xdr, OP_LAYOUTSTATS);
1206 }
1207 
decode_clone(struct xdr_stream * xdr)1208 static int decode_clone(struct xdr_stream *xdr)
1209 {
1210 	return decode_op_hdr(xdr, OP_CLONE);
1211 }
1212 
decode_layouterror(struct xdr_stream * xdr)1213 static int decode_layouterror(struct xdr_stream *xdr)
1214 {
1215 	return decode_op_hdr(xdr, OP_LAYOUTERROR);
1216 }
1217 
decode_setxattr(struct xdr_stream * xdr,struct nfs4_change_info * cinfo)1218 static int decode_setxattr(struct xdr_stream *xdr,
1219 			   struct nfs4_change_info *cinfo)
1220 {
1221 	int status;
1222 
1223 	status = decode_op_hdr(xdr, OP_SETXATTR);
1224 	if (status)
1225 		goto out;
1226 	status = decode_change_info(xdr, cinfo);
1227 out:
1228 	return status;
1229 }
1230 
decode_getxattr(struct xdr_stream * xdr,struct nfs42_getxattrres * res,struct rpc_rqst * req)1231 static int decode_getxattr(struct xdr_stream *xdr,
1232 			   struct nfs42_getxattrres *res,
1233 			   struct rpc_rqst *req)
1234 {
1235 	int status;
1236 	__be32 *p;
1237 	u32 len, rdlen;
1238 
1239 	status = decode_op_hdr(xdr, OP_GETXATTR);
1240 	if (status)
1241 		return status;
1242 
1243 	p = xdr_inline_decode(xdr, 4);
1244 	if (unlikely(!p))
1245 		return -EIO;
1246 
1247 	len = be32_to_cpup(p);
1248 
1249 	/*
1250 	 * Only check against the page length here. The actual
1251 	 * requested length may be smaller, but that is only
1252 	 * checked against after possibly caching a valid reply.
1253 	 */
1254 	if (len > req->rq_rcv_buf.page_len)
1255 		return -ERANGE;
1256 
1257 	res->xattr_len = len;
1258 
1259 	if (len > 0) {
1260 		rdlen = xdr_read_pages(xdr, len);
1261 		if (rdlen < len)
1262 			return -EIO;
1263 	}
1264 
1265 	return 0;
1266 }
1267 
decode_removexattr(struct xdr_stream * xdr,struct nfs4_change_info * cinfo)1268 static int decode_removexattr(struct xdr_stream *xdr,
1269 			   struct nfs4_change_info *cinfo)
1270 {
1271 	int status;
1272 
1273 	status = decode_op_hdr(xdr, OP_REMOVEXATTR);
1274 	if (status)
1275 		goto out;
1276 
1277 	status = decode_change_info(xdr, cinfo);
1278 out:
1279 	return status;
1280 }
1281 
decode_listxattrs(struct xdr_stream * xdr,struct nfs42_listxattrsres * res)1282 static int decode_listxattrs(struct xdr_stream *xdr,
1283 			    struct nfs42_listxattrsres *res)
1284 {
1285 	int status;
1286 	__be32 *p;
1287 	u32 count, len, ulen;
1288 	size_t left, copied;
1289 	char *buf;
1290 
1291 	status = decode_op_hdr(xdr, OP_LISTXATTRS);
1292 	if (status) {
1293 		/*
1294 		 * Special case: for LISTXATTRS, NFS4ERR_TOOSMALL
1295 		 * should be translated to ERANGE.
1296 		 */
1297 		if (status == -ETOOSMALL)
1298 			status = -ERANGE;
1299 		/*
1300 		 * Special case: for LISTXATTRS, NFS4ERR_NOXATTR
1301 		 * should be translated to success with zero-length reply.
1302 		 */
1303 		if (status == -ENODATA) {
1304 			res->eof = true;
1305 			status = 0;
1306 		}
1307 		goto out;
1308 	}
1309 
1310 	p = xdr_inline_decode(xdr, 8);
1311 	if (unlikely(!p))
1312 		return -EIO;
1313 
1314 	xdr_decode_hyper(p, &res->cookie);
1315 
1316 	p = xdr_inline_decode(xdr, 4);
1317 	if (unlikely(!p))
1318 		return -EIO;
1319 
1320 	left = res->xattr_len;
1321 	buf = res->xattr_buf;
1322 
1323 	count = be32_to_cpup(p);
1324 	copied = 0;
1325 
1326 	/*
1327 	 * We have asked for enough room to encode the maximum number
1328 	 * of possible attribute names, so everything should fit.
1329 	 *
1330 	 * But, don't rely on that assumption. Just decode entries
1331 	 * until they don't fit anymore, just in case the server did
1332 	 * something odd.
1333 	 */
1334 	while (count--) {
1335 		p = xdr_inline_decode(xdr, 4);
1336 		if (unlikely(!p))
1337 			return -EIO;
1338 
1339 		len = be32_to_cpup(p);
1340 		if (len > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) {
1341 			status = -ERANGE;
1342 			goto out;
1343 		}
1344 
1345 		p = xdr_inline_decode(xdr, len);
1346 		if (unlikely(!p))
1347 			return -EIO;
1348 
1349 		ulen = len + XATTR_USER_PREFIX_LEN + 1;
1350 		if (buf) {
1351 			if (ulen > left) {
1352 				status = -ERANGE;
1353 				goto out;
1354 			}
1355 
1356 			memcpy(buf, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
1357 			memcpy(buf + XATTR_USER_PREFIX_LEN, p, len);
1358 
1359 			buf[ulen - 1] = 0;
1360 			buf += ulen;
1361 			left -= ulen;
1362 		}
1363 		copied += ulen;
1364 	}
1365 
1366 	p = xdr_inline_decode(xdr, 4);
1367 	if (unlikely(!p))
1368 		return -EIO;
1369 
1370 	res->eof = be32_to_cpup(p);
1371 	res->copied = copied;
1372 
1373 out:
1374 	if (status == -ERANGE && res->xattr_len == XATTR_LIST_MAX)
1375 		status = -E2BIG;
1376 
1377 	return status;
1378 }
1379 
1380 /*
1381  * Decode ALLOCATE request
1382  */
nfs4_xdr_dec_allocate(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1383 static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
1384 				 struct xdr_stream *xdr,
1385 				 void *data)
1386 {
1387 	struct nfs42_falloc_res *res = data;
1388 	struct compound_hdr hdr;
1389 	int status;
1390 
1391 	status = decode_compound_hdr(xdr, &hdr);
1392 	if (status)
1393 		goto out;
1394 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1395 	if (status)
1396 		goto out;
1397 	status = decode_putfh(xdr);
1398 	if (status)
1399 		goto out;
1400 	status = decode_allocate(xdr, res);
1401 	if (status)
1402 		goto out;
1403 	decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
1404 out:
1405 	return status;
1406 }
1407 
1408 /*
1409  * Decode COPY response
1410  */
nfs4_xdr_dec_copy(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1411 static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp,
1412 			     struct xdr_stream *xdr,
1413 			     void *data)
1414 {
1415 	struct nfs42_copy_res *res = data;
1416 	struct compound_hdr hdr;
1417 	int status;
1418 
1419 	status = decode_compound_hdr(xdr, &hdr);
1420 	if (status)
1421 		goto out;
1422 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1423 	if (status)
1424 		goto out;
1425 	status = decode_putfh(xdr);
1426 	if (status)
1427 		goto out;
1428 	status = decode_savefh(xdr);
1429 	if (status)
1430 		goto out;
1431 	status = decode_putfh(xdr);
1432 	if (status)
1433 		goto out;
1434 	status = decode_copy(xdr, res);
1435 	if (status)
1436 		goto out;
1437 	if (res->commit_res.verf)
1438 		status = decode_commit(xdr, &res->commit_res);
1439 out:
1440 	return status;
1441 }
1442 
1443 /*
1444  * Decode OFFLOAD_CANCEL response
1445  */
nfs4_xdr_dec_offload_cancel(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1446 static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp,
1447 				       struct xdr_stream *xdr,
1448 				       void *data)
1449 {
1450 	struct nfs42_offload_status_res *res = data;
1451 	struct compound_hdr hdr;
1452 	int status;
1453 
1454 	status = decode_compound_hdr(xdr, &hdr);
1455 	if (status)
1456 		goto out;
1457 	status = decode_sequence(xdr, &res->osr_seq_res, rqstp);
1458 	if (status)
1459 		goto out;
1460 	status = decode_putfh(xdr);
1461 	if (status)
1462 		goto out;
1463 	status = decode_offload_cancel(xdr, res);
1464 
1465 out:
1466 	return status;
1467 }
1468 
1469 /*
1470  * Decode OFFLOAD_STATUS response
1471  */
nfs4_xdr_dec_offload_status(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1472 static int nfs4_xdr_dec_offload_status(struct rpc_rqst *rqstp,
1473 				       struct xdr_stream *xdr,
1474 				       void *data)
1475 {
1476 	struct nfs42_offload_status_res *res = data;
1477 	struct compound_hdr hdr;
1478 	int status;
1479 
1480 	status = decode_compound_hdr(xdr, &hdr);
1481 	if (status)
1482 		goto out;
1483 	status = decode_sequence(xdr, &res->osr_seq_res, rqstp);
1484 	if (status)
1485 		goto out;
1486 	status = decode_putfh(xdr);
1487 	if (status)
1488 		goto out;
1489 	status = decode_offload_status(xdr, res);
1490 
1491 out:
1492 	return status;
1493 }
1494 
1495 /*
1496  * Decode COPY_NOTIFY response
1497  */
nfs4_xdr_dec_copy_notify(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1498 static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp,
1499 				    struct xdr_stream *xdr,
1500 				    void *data)
1501 {
1502 	struct nfs42_copy_notify_res *res = data;
1503 	struct compound_hdr hdr;
1504 	int status;
1505 
1506 	status = decode_compound_hdr(xdr, &hdr);
1507 	if (status)
1508 		goto out;
1509 	status = decode_sequence(xdr, &res->cnr_seq_res, rqstp);
1510 	if (status)
1511 		goto out;
1512 	status = decode_putfh(xdr);
1513 	if (status)
1514 		goto out;
1515 	status = decode_copy_notify(xdr, res);
1516 
1517 out:
1518 	return status;
1519 }
1520 
1521 /*
1522  * Decode DEALLOCATE request
1523  */
nfs4_xdr_dec_deallocate(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1524 static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
1525 				   struct xdr_stream *xdr,
1526 				   void *data)
1527 {
1528 	struct nfs42_falloc_res *res = data;
1529 	struct compound_hdr hdr;
1530 	int status;
1531 
1532 	status = decode_compound_hdr(xdr, &hdr);
1533 	if (status)
1534 		goto out;
1535 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1536 	if (status)
1537 		goto out;
1538 	status = decode_putfh(xdr);
1539 	if (status)
1540 		goto out;
1541 	status = decode_deallocate(xdr, res);
1542 	if (status)
1543 		goto out;
1544 	decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
1545 out:
1546 	return status;
1547 }
1548 
1549 /*
1550  * Decode ZERO_RANGE request
1551  */
nfs4_xdr_dec_zero_range(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1552 static int nfs4_xdr_dec_zero_range(struct rpc_rqst *rqstp,
1553 				   struct xdr_stream *xdr,
1554 				   void *data)
1555 {
1556 	struct nfs42_falloc_res *res = data;
1557 	struct compound_hdr hdr;
1558 	int status;
1559 
1560 	status = decode_compound_hdr(xdr, &hdr);
1561 	if (status)
1562 		goto out;
1563 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1564 	if (status)
1565 		goto out;
1566 	status = decode_putfh(xdr);
1567 	if (status)
1568 		goto out;
1569 	status = decode_deallocate(xdr, res);
1570 	if (status)
1571 		goto out;
1572 	status = decode_allocate(xdr, res);
1573 	if (status)
1574 		goto out;
1575 	decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
1576 out:
1577 	return status;
1578 }
1579 
1580 /*
1581  * Decode READ_PLUS request
1582  */
nfs4_xdr_dec_read_plus(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1583 static int nfs4_xdr_dec_read_plus(struct rpc_rqst *rqstp,
1584 				  struct xdr_stream *xdr,
1585 				  void *data)
1586 {
1587 	struct nfs_pgio_res *res = data;
1588 	struct compound_hdr hdr;
1589 	int status;
1590 
1591 	xdr_set_scratch_buffer(xdr, res->scratch, READ_PLUS_SCRATCH_SIZE);
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_read_plus(xdr, res);
1603 	if (!status)
1604 		status = res->count;
1605 out:
1606 	return status;
1607 }
1608 
1609 /*
1610  * Decode SEEK request
1611  */
nfs4_xdr_dec_seek(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1612 static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
1613 			     struct xdr_stream *xdr,
1614 			     void *data)
1615 {
1616 	struct nfs42_seek_res *res = data;
1617 	struct compound_hdr hdr;
1618 	int status;
1619 
1620 	status = decode_compound_hdr(xdr, &hdr);
1621 	if (status)
1622 		goto out;
1623 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1624 	if (status)
1625 		goto out;
1626 	status = decode_putfh(xdr);
1627 	if (status)
1628 		goto out;
1629 	status = decode_seek(xdr, res);
1630 out:
1631 	return status;
1632 }
1633 
1634 /*
1635  * Decode LAYOUTSTATS request
1636  */
nfs4_xdr_dec_layoutstats(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1637 static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp,
1638 				    struct xdr_stream *xdr,
1639 				    void *data)
1640 {
1641 	struct nfs42_layoutstat_res *res = data;
1642 	struct compound_hdr hdr;
1643 	int status, i;
1644 
1645 	status = decode_compound_hdr(xdr, &hdr);
1646 	if (status)
1647 		goto out;
1648 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1649 	if (status)
1650 		goto out;
1651 	status = decode_putfh(xdr);
1652 	if (status)
1653 		goto out;
1654 	WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
1655 	for (i = 0; i < res->num_dev; i++) {
1656 		status = decode_layoutstats(xdr);
1657 		if (status)
1658 			goto out;
1659 	}
1660 out:
1661 	res->rpc_status = status;
1662 	return status;
1663 }
1664 
1665 /*
1666  * Decode CLONE request
1667  */
nfs4_xdr_dec_clone(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1668 static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp,
1669 			      struct xdr_stream *xdr,
1670 			      void *data)
1671 {
1672 	struct nfs42_clone_res *res = data;
1673 	struct compound_hdr hdr;
1674 	int status;
1675 
1676 	status = decode_compound_hdr(xdr, &hdr);
1677 	if (status)
1678 		goto out;
1679 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1680 	if (status)
1681 		goto out;
1682 	status = decode_putfh(xdr);
1683 	if (status)
1684 		goto out;
1685 	status = decode_savefh(xdr);
1686 	if (status)
1687 		goto out;
1688 	status = decode_putfh(xdr);
1689 	if (status)
1690 		goto out;
1691 	status = decode_clone(xdr);
1692 	if (status)
1693 		goto out;
1694 	decode_getfattr(xdr, res->dst_fattr, res->server);
1695 out:
1696 	res->rpc_status = status;
1697 	return status;
1698 }
1699 
1700 /*
1701  * Decode LAYOUTERROR request
1702  */
nfs4_xdr_dec_layouterror(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1703 static int nfs4_xdr_dec_layouterror(struct rpc_rqst *rqstp,
1704 				    struct xdr_stream *xdr,
1705 				    void *data)
1706 {
1707 	struct nfs42_layouterror_res *res = data;
1708 	struct compound_hdr hdr;
1709 	int status, i;
1710 
1711 	status = decode_compound_hdr(xdr, &hdr);
1712 	if (status)
1713 		goto out;
1714 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1715 	if (status)
1716 		goto out;
1717 	status = decode_putfh(xdr);
1718 
1719 	for (i = 0; i < res->num_errors && status == 0; i++)
1720 		status = decode_layouterror(xdr);
1721 out:
1722 	res->rpc_status = status;
1723 	return status;
1724 }
1725 
1726 /*
1727  * Decode SETXATTR request
1728  */
nfs4_xdr_dec_setxattr(struct rpc_rqst * req,struct xdr_stream * xdr,void * data)1729 static int nfs4_xdr_dec_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
1730 				 void *data)
1731 {
1732 	struct nfs42_setxattrres *res = data;
1733 	struct compound_hdr hdr;
1734 	int status;
1735 
1736 	status = decode_compound_hdr(xdr, &hdr);
1737 	if (status)
1738 		goto out;
1739 	status = decode_sequence(xdr, &res->seq_res, req);
1740 	if (status)
1741 		goto out;
1742 	status = decode_putfh(xdr);
1743 	if (status)
1744 		goto out;
1745 	status = decode_setxattr(xdr, &res->cinfo);
1746 	if (status)
1747 		goto out;
1748 	status = decode_getfattr(xdr, res->fattr, res->server);
1749 out:
1750 	return status;
1751 }
1752 
1753 /*
1754  * Decode GETXATTR request
1755  */
nfs4_xdr_dec_getxattr(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1756 static int nfs4_xdr_dec_getxattr(struct rpc_rqst *rqstp,
1757 				 struct xdr_stream *xdr, void *data)
1758 {
1759 	struct nfs42_getxattrres *res = data;
1760 	struct compound_hdr hdr;
1761 	int status;
1762 
1763 	status = decode_compound_hdr(xdr, &hdr);
1764 	if (status)
1765 		goto out;
1766 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1767 	if (status)
1768 		goto out;
1769 	status = decode_putfh(xdr);
1770 	if (status)
1771 		goto out;
1772 	status = decode_getxattr(xdr, res, rqstp);
1773 out:
1774 	return status;
1775 }
1776 
1777 /*
1778  * Decode LISTXATTR request
1779  */
nfs4_xdr_dec_listxattrs(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1780 static int nfs4_xdr_dec_listxattrs(struct rpc_rqst *rqstp,
1781 				   struct xdr_stream *xdr, void *data)
1782 {
1783 	struct nfs42_listxattrsres *res = data;
1784 	struct compound_hdr hdr;
1785 	int status;
1786 
1787 	xdr_set_scratch_folio(xdr, res->scratch);
1788 
1789 	status = decode_compound_hdr(xdr, &hdr);
1790 	if (status)
1791 		goto out;
1792 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1793 	if (status)
1794 		goto out;
1795 	status = decode_putfh(xdr);
1796 	if (status)
1797 		goto out;
1798 	status = decode_listxattrs(xdr, res);
1799 out:
1800 	return status;
1801 }
1802 
1803 /*
1804  * Decode REMOVEXATTR request
1805  */
nfs4_xdr_dec_removexattr(struct rpc_rqst * req,struct xdr_stream * xdr,void * data)1806 static int nfs4_xdr_dec_removexattr(struct rpc_rqst *req,
1807 				    struct xdr_stream *xdr, void *data)
1808 {
1809 	struct nfs42_removexattrres *res = data;
1810 	struct compound_hdr hdr;
1811 	int status;
1812 
1813 	status = decode_compound_hdr(xdr, &hdr);
1814 	if (status)
1815 		goto out;
1816 	status = decode_sequence(xdr, &res->seq_res, req);
1817 	if (status)
1818 		goto out;
1819 	status = decode_putfh(xdr);
1820 	if (status)
1821 		goto out;
1822 
1823 	status = decode_removexattr(xdr, &res->cinfo);
1824 	if (status)
1825 		goto out;
1826 	status = decode_getfattr(xdr, res->fattr, res->server);
1827 out:
1828 	return status;
1829 }
1830 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */
1831