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