1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>
4  */
5 #ifndef __LINUX_FS_NFS_NFS4_2XDR_H
6 #define __LINUX_FS_NFS_NFS4_2XDR_H
7 
8 #include "nfs42.h"
9 
10 #define encode_fallocate_maxsz		(encode_stateid_maxsz + \
11 					 2 /* offset */ + \
12 					 2 /* length */)
13 #define NFS42_WRITE_RES_SIZE		(1 /* wr_callback_id size */ +\
14 					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
15 					 2 /* wr_count */ + \
16 					 1 /* wr_committed */ + \
17 					 XDR_QUADLEN(NFS4_VERIFIER_SIZE))
18 #define encode_allocate_maxsz		(op_encode_hdr_maxsz + \
19 					 encode_fallocate_maxsz)
20 #define decode_allocate_maxsz		(op_decode_hdr_maxsz)
21 #define encode_copy_maxsz		(op_encode_hdr_maxsz +          \
22 					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
23 					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
24 					 2 + 2 + 2 + 1 + 1 + 1)
25 #define decode_copy_maxsz		(op_decode_hdr_maxsz + \
26 					 NFS42_WRITE_RES_SIZE + \
27 					 1 /* cr_consecutive */ + \
28 					 1 /* cr_synchronous */)
29 #define encode_offload_cancel_maxsz	(op_encode_hdr_maxsz + \
30 					 XDR_QUADLEN(NFS4_STATEID_SIZE))
31 #define decode_offload_cancel_maxsz	(op_decode_hdr_maxsz)
32 #define encode_deallocate_maxsz		(op_encode_hdr_maxsz + \
33 					 encode_fallocate_maxsz)
34 #define decode_deallocate_maxsz		(op_decode_hdr_maxsz)
35 #define encode_seek_maxsz		(op_encode_hdr_maxsz + \
36 					 encode_stateid_maxsz + \
37 					 2 /* offset */ + \
38 					 1 /* whence */)
39 #define decode_seek_maxsz		(op_decode_hdr_maxsz + \
40 					 1 /* eof */ + \
41 					 1 /* whence */ + \
42 					 2 /* offset */ + \
43 					 2 /* length */)
44 #define encode_io_info_maxsz		4
45 #define encode_layoutstats_maxsz	(op_decode_hdr_maxsz + \
46 					2 /* offset */ + \
47 					2 /* length */ + \
48 					encode_stateid_maxsz + \
49 					encode_io_info_maxsz + \
50 					encode_io_info_maxsz + \
51 					1 /* opaque devaddr4 length */ + \
52 					XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE))
53 #define decode_layoutstats_maxsz	(op_decode_hdr_maxsz)
54 #define encode_clone_maxsz		(encode_stateid_maxsz + \
55 					encode_stateid_maxsz + \
56 					2 /* src offset */ + \
57 					2 /* dst offset */ + \
58 					2 /* count */)
59 #define decode_clone_maxsz		(op_decode_hdr_maxsz)
60 
61 #define NFS4_enc_allocate_sz		(compound_encode_hdr_maxsz + \
62 					 encode_sequence_maxsz + \
63 					 encode_putfh_maxsz + \
64 					 encode_allocate_maxsz + \
65 					 encode_getattr_maxsz)
66 #define NFS4_dec_allocate_sz		(compound_decode_hdr_maxsz + \
67 					 decode_sequence_maxsz + \
68 					 decode_putfh_maxsz + \
69 					 decode_allocate_maxsz + \
70 					 decode_getattr_maxsz)
71 #define NFS4_enc_copy_sz		(compound_encode_hdr_maxsz + \
72 					 encode_sequence_maxsz + \
73 					 encode_putfh_maxsz + \
74 					 encode_savefh_maxsz + \
75 					 encode_putfh_maxsz + \
76 					 encode_copy_maxsz + \
77 					 encode_commit_maxsz)
78 #define NFS4_dec_copy_sz		(compound_decode_hdr_maxsz + \
79 					 decode_sequence_maxsz + \
80 					 decode_putfh_maxsz + \
81 					 decode_savefh_maxsz + \
82 					 decode_putfh_maxsz + \
83 					 decode_copy_maxsz + \
84 					 decode_commit_maxsz)
85 #define NFS4_enc_offload_cancel_sz	(compound_encode_hdr_maxsz + \
86 					 encode_sequence_maxsz + \
87 					 encode_putfh_maxsz + \
88 					 encode_offload_cancel_maxsz)
89 #define NFS4_dec_offload_cancel_sz	(compound_decode_hdr_maxsz + \
90 					 decode_sequence_maxsz + \
91 					 decode_putfh_maxsz + \
92 					 decode_offload_cancel_maxsz)
93 #define NFS4_enc_deallocate_sz		(compound_encode_hdr_maxsz + \
94 					 encode_sequence_maxsz + \
95 					 encode_putfh_maxsz + \
96 					 encode_deallocate_maxsz + \
97 					 encode_getattr_maxsz)
98 #define NFS4_dec_deallocate_sz		(compound_decode_hdr_maxsz + \
99 					 decode_sequence_maxsz + \
100 					 decode_putfh_maxsz + \
101 					 decode_deallocate_maxsz + \
102 					 decode_getattr_maxsz)
103 #define NFS4_enc_seek_sz		(compound_encode_hdr_maxsz + \
104 					 encode_sequence_maxsz + \
105 					 encode_putfh_maxsz + \
106 					 encode_seek_maxsz)
107 #define NFS4_dec_seek_sz		(compound_decode_hdr_maxsz + \
108 					 decode_sequence_maxsz + \
109 					 decode_putfh_maxsz + \
110 					 decode_seek_maxsz)
111 #define NFS4_enc_layoutstats_sz		(compound_encode_hdr_maxsz + \
112 					 encode_sequence_maxsz + \
113 					 encode_putfh_maxsz + \
114 					 PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz)
115 #define NFS4_dec_layoutstats_sz		(compound_decode_hdr_maxsz + \
116 					 decode_sequence_maxsz + \
117 					 decode_putfh_maxsz + \
118 					 PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz)
119 #define NFS4_enc_clone_sz		(compound_encode_hdr_maxsz + \
120 					 encode_sequence_maxsz + \
121 					 encode_putfh_maxsz + \
122 					 encode_savefh_maxsz + \
123 					 encode_putfh_maxsz + \
124 					 encode_clone_maxsz + \
125 					 encode_getattr_maxsz)
126 #define NFS4_dec_clone_sz		(compound_decode_hdr_maxsz + \
127 					 decode_sequence_maxsz + \
128 					 decode_putfh_maxsz + \
129 					 decode_savefh_maxsz + \
130 					 decode_putfh_maxsz + \
131 					 decode_clone_maxsz + \
132 					 decode_getattr_maxsz)
133 
encode_fallocate(struct xdr_stream * xdr,const struct nfs42_falloc_args * args)134 static void encode_fallocate(struct xdr_stream *xdr,
135 			     const struct nfs42_falloc_args *args)
136 {
137 	encode_nfs4_stateid(xdr, &args->falloc_stateid);
138 	encode_uint64(xdr, args->falloc_offset);
139 	encode_uint64(xdr, args->falloc_length);
140 }
141 
encode_allocate(struct xdr_stream * xdr,const struct nfs42_falloc_args * args,struct compound_hdr * hdr)142 static void encode_allocate(struct xdr_stream *xdr,
143 			    const struct nfs42_falloc_args *args,
144 			    struct compound_hdr *hdr)
145 {
146 	encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
147 	encode_fallocate(xdr, args);
148 }
149 
encode_copy(struct xdr_stream * xdr,const struct nfs42_copy_args * args,struct compound_hdr * hdr)150 static void encode_copy(struct xdr_stream *xdr,
151 			const struct nfs42_copy_args *args,
152 			struct compound_hdr *hdr)
153 {
154 	encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr);
155 	encode_nfs4_stateid(xdr, &args->src_stateid);
156 	encode_nfs4_stateid(xdr, &args->dst_stateid);
157 
158 	encode_uint64(xdr, args->src_pos);
159 	encode_uint64(xdr, args->dst_pos);
160 	encode_uint64(xdr, args->count);
161 
162 	encode_uint32(xdr, 1); /* consecutive = true */
163 	encode_uint32(xdr, args->sync);
164 	encode_uint32(xdr, 0); /* src server list */
165 }
166 
encode_offload_cancel(struct xdr_stream * xdr,const struct nfs42_offload_status_args * args,struct compound_hdr * hdr)167 static void encode_offload_cancel(struct xdr_stream *xdr,
168 				  const struct nfs42_offload_status_args *args,
169 				  struct compound_hdr *hdr)
170 {
171 	encode_op_hdr(xdr, OP_OFFLOAD_CANCEL, decode_offload_cancel_maxsz, hdr);
172 	encode_nfs4_stateid(xdr, &args->osa_stateid);
173 }
174 
encode_deallocate(struct xdr_stream * xdr,const struct nfs42_falloc_args * args,struct compound_hdr * hdr)175 static void encode_deallocate(struct xdr_stream *xdr,
176 			      const struct nfs42_falloc_args *args,
177 			      struct compound_hdr *hdr)
178 {
179 	encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
180 	encode_fallocate(xdr, args);
181 }
182 
encode_seek(struct xdr_stream * xdr,const struct nfs42_seek_args * args,struct compound_hdr * hdr)183 static void encode_seek(struct xdr_stream *xdr,
184 			const struct nfs42_seek_args *args,
185 			struct compound_hdr *hdr)
186 {
187 	encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr);
188 	encode_nfs4_stateid(xdr, &args->sa_stateid);
189 	encode_uint64(xdr, args->sa_offset);
190 	encode_uint32(xdr, args->sa_what);
191 }
192 
encode_layoutstats(struct xdr_stream * xdr,const struct nfs42_layoutstat_args * args,struct nfs42_layoutstat_devinfo * devinfo,struct compound_hdr * hdr)193 static void encode_layoutstats(struct xdr_stream *xdr,
194 			       const struct nfs42_layoutstat_args *args,
195 			       struct nfs42_layoutstat_devinfo *devinfo,
196 			       struct compound_hdr *hdr)
197 {
198 	__be32 *p;
199 
200 	encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr);
201 	p = reserve_space(xdr, 8 + 8);
202 	p = xdr_encode_hyper(p, devinfo->offset);
203 	p = xdr_encode_hyper(p, devinfo->length);
204 	encode_nfs4_stateid(xdr, &args->stateid);
205 	p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4);
206 	p = xdr_encode_hyper(p, devinfo->read_count);
207 	p = xdr_encode_hyper(p, devinfo->read_bytes);
208 	p = xdr_encode_hyper(p, devinfo->write_count);
209 	p = xdr_encode_hyper(p, devinfo->write_bytes);
210 	p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data,
211 			NFS4_DEVICEID4_SIZE);
212 	/* Encode layoutupdate4 */
213 	*p++ = cpu_to_be32(devinfo->layout_type);
214 	if (devinfo->ld_private.ops)
215 		devinfo->ld_private.ops->encode(xdr, args,
216 				&devinfo->ld_private);
217 	else
218 		encode_uint32(xdr, 0);
219 }
220 
encode_clone(struct xdr_stream * xdr,const struct nfs42_clone_args * args,struct compound_hdr * hdr)221 static void encode_clone(struct xdr_stream *xdr,
222 			 const struct nfs42_clone_args *args,
223 			 struct compound_hdr *hdr)
224 {
225 	__be32 *p;
226 
227 	encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr);
228 	encode_nfs4_stateid(xdr, &args->src_stateid);
229 	encode_nfs4_stateid(xdr, &args->dst_stateid);
230 	p = reserve_space(xdr, 3*8);
231 	p = xdr_encode_hyper(p, args->src_offset);
232 	p = xdr_encode_hyper(p, args->dst_offset);
233 	xdr_encode_hyper(p, args->count);
234 }
235 
236 /*
237  * Encode ALLOCATE request
238  */
nfs4_xdr_enc_allocate(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)239 static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
240 				  struct xdr_stream *xdr,
241 				  const void *data)
242 {
243 	const struct nfs42_falloc_args *args = data;
244 	struct compound_hdr hdr = {
245 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
246 	};
247 
248 	encode_compound_hdr(xdr, req, &hdr);
249 	encode_sequence(xdr, &args->seq_args, &hdr);
250 	encode_putfh(xdr, args->falloc_fh, &hdr);
251 	encode_allocate(xdr, args, &hdr);
252 	encode_getfattr(xdr, args->falloc_bitmask, &hdr);
253 	encode_nops(&hdr);
254 }
255 
encode_copy_commit(struct xdr_stream * xdr,const struct nfs42_copy_args * args,struct compound_hdr * hdr)256 static void encode_copy_commit(struct xdr_stream *xdr,
257 			  const struct nfs42_copy_args *args,
258 			  struct compound_hdr *hdr)
259 {
260 	__be32 *p;
261 
262 	encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr);
263 	p = reserve_space(xdr, 12);
264 	p = xdr_encode_hyper(p, args->dst_pos);
265 	*p = cpu_to_be32(args->count);
266 }
267 
268 /*
269  * Encode COPY request
270  */
nfs4_xdr_enc_copy(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)271 static void nfs4_xdr_enc_copy(struct rpc_rqst *req,
272 			      struct xdr_stream *xdr,
273 			      const void *data)
274 {
275 	const struct nfs42_copy_args *args = data;
276 	struct compound_hdr hdr = {
277 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
278 	};
279 
280 	encode_compound_hdr(xdr, req, &hdr);
281 	encode_sequence(xdr, &args->seq_args, &hdr);
282 	encode_putfh(xdr, args->src_fh, &hdr);
283 	encode_savefh(xdr, &hdr);
284 	encode_putfh(xdr, args->dst_fh, &hdr);
285 	encode_copy(xdr, args, &hdr);
286 	if (args->sync)
287 		encode_copy_commit(xdr, args, &hdr);
288 	encode_nops(&hdr);
289 }
290 
291 /*
292  * Encode OFFLOAD_CANEL request
293  */
nfs4_xdr_enc_offload_cancel(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)294 static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req,
295 					struct xdr_stream *xdr,
296 					const void *data)
297 {
298 	const struct nfs42_offload_status_args *args = data;
299 	struct compound_hdr hdr = {
300 		.minorversion = nfs4_xdr_minorversion(&args->osa_seq_args),
301 	};
302 
303 	encode_compound_hdr(xdr, req, &hdr);
304 	encode_sequence(xdr, &args->osa_seq_args, &hdr);
305 	encode_putfh(xdr, args->osa_src_fh, &hdr);
306 	encode_offload_cancel(xdr, args, &hdr);
307 	encode_nops(&hdr);
308 }
309 
310 /*
311  * Encode DEALLOCATE request
312  */
nfs4_xdr_enc_deallocate(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)313 static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
314 				    struct xdr_stream *xdr,
315 				    const void *data)
316 {
317 	const struct nfs42_falloc_args *args = data;
318 	struct compound_hdr hdr = {
319 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
320 	};
321 
322 	encode_compound_hdr(xdr, req, &hdr);
323 	encode_sequence(xdr, &args->seq_args, &hdr);
324 	encode_putfh(xdr, args->falloc_fh, &hdr);
325 	encode_deallocate(xdr, args, &hdr);
326 	encode_getfattr(xdr, args->falloc_bitmask, &hdr);
327 	encode_nops(&hdr);
328 }
329 
330 /*
331  * Encode SEEK request
332  */
nfs4_xdr_enc_seek(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)333 static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
334 			      struct xdr_stream *xdr,
335 			      const void *data)
336 {
337 	const struct nfs42_seek_args *args = data;
338 	struct compound_hdr hdr = {
339 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
340 	};
341 
342 	encode_compound_hdr(xdr, req, &hdr);
343 	encode_sequence(xdr, &args->seq_args, &hdr);
344 	encode_putfh(xdr, args->sa_fh, &hdr);
345 	encode_seek(xdr, args, &hdr);
346 	encode_nops(&hdr);
347 }
348 
349 /*
350  * Encode LAYOUTSTATS request
351  */
nfs4_xdr_enc_layoutstats(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)352 static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req,
353 				     struct xdr_stream *xdr,
354 				     const void *data)
355 {
356 	const struct nfs42_layoutstat_args *args = data;
357 	int i;
358 
359 	struct compound_hdr hdr = {
360 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
361 	};
362 
363 	encode_compound_hdr(xdr, req, &hdr);
364 	encode_sequence(xdr, &args->seq_args, &hdr);
365 	encode_putfh(xdr, args->fh, &hdr);
366 	WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
367 	for (i = 0; i < args->num_dev; i++)
368 		encode_layoutstats(xdr, args, &args->devinfo[i], &hdr);
369 	encode_nops(&hdr);
370 }
371 
372 /*
373  * Encode CLONE request
374  */
nfs4_xdr_enc_clone(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)375 static void nfs4_xdr_enc_clone(struct rpc_rqst *req,
376 			       struct xdr_stream *xdr,
377 			       const void *data)
378 {
379 	const struct nfs42_clone_args *args = data;
380 	struct compound_hdr hdr = {
381 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
382 	};
383 
384 	encode_compound_hdr(xdr, req, &hdr);
385 	encode_sequence(xdr, &args->seq_args, &hdr);
386 	encode_putfh(xdr, args->src_fh, &hdr);
387 	encode_savefh(xdr, &hdr);
388 	encode_putfh(xdr, args->dst_fh, &hdr);
389 	encode_clone(xdr, args, &hdr);
390 	encode_getfattr(xdr, args->dst_bitmask, &hdr);
391 	encode_nops(&hdr);
392 }
393 
decode_allocate(struct xdr_stream * xdr,struct nfs42_falloc_res * res)394 static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
395 {
396 	return decode_op_hdr(xdr, OP_ALLOCATE);
397 }
398 
decode_write_response(struct xdr_stream * xdr,struct nfs42_write_res * res)399 static int decode_write_response(struct xdr_stream *xdr,
400 				 struct nfs42_write_res *res)
401 {
402 	__be32 *p;
403 	int status, count;
404 
405 	p = xdr_inline_decode(xdr, 4);
406 	if (unlikely(!p))
407 		goto out_overflow;
408 	count = be32_to_cpup(p);
409 	if (count > 1)
410 		return -EREMOTEIO;
411 	else if (count == 1) {
412 		status = decode_opaque_fixed(xdr, &res->stateid,
413 				NFS4_STATEID_SIZE);
414 		if (unlikely(status))
415 			goto out_overflow;
416 	}
417 	p = xdr_inline_decode(xdr, 8 + 4);
418 	if (unlikely(!p))
419 		goto out_overflow;
420 	p = xdr_decode_hyper(p, &res->count);
421 	res->verifier.committed = be32_to_cpup(p);
422 	return decode_verifier(xdr, &res->verifier.verifier);
423 
424 out_overflow:
425 	print_overflow_msg(__func__, xdr);
426 	return -EIO;
427 }
428 
decode_copy_requirements(struct xdr_stream * xdr,struct nfs42_copy_res * res)429 static int decode_copy_requirements(struct xdr_stream *xdr,
430 				    struct nfs42_copy_res *res) {
431 	__be32 *p;
432 
433 	p = xdr_inline_decode(xdr, 4 + 4);
434 	if (unlikely(!p))
435 		goto out_overflow;
436 
437 	res->consecutive = be32_to_cpup(p++);
438 	res->synchronous = be32_to_cpup(p++);
439 	return 0;
440 out_overflow:
441 	print_overflow_msg(__func__, xdr);
442 	return -EIO;
443 }
444 
decode_copy(struct xdr_stream * xdr,struct nfs42_copy_res * res)445 static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res)
446 {
447 	int status;
448 
449 	status = decode_op_hdr(xdr, OP_COPY);
450 	if (status == NFS4ERR_OFFLOAD_NO_REQS) {
451 		status = decode_copy_requirements(xdr, res);
452 		if (status)
453 			return status;
454 		return NFS4ERR_OFFLOAD_NO_REQS;
455 	} else if (status)
456 		return status;
457 
458 	status = decode_write_response(xdr, &res->write_res);
459 	if (status)
460 		return status;
461 
462 	return decode_copy_requirements(xdr, res);
463 }
464 
decode_offload_cancel(struct xdr_stream * xdr,struct nfs42_offload_status_res * res)465 static int decode_offload_cancel(struct xdr_stream *xdr,
466 				 struct nfs42_offload_status_res *res)
467 {
468 	return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);
469 }
470 
decode_deallocate(struct xdr_stream * xdr,struct nfs42_falloc_res * res)471 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
472 {
473 	return decode_op_hdr(xdr, OP_DEALLOCATE);
474 }
475 
decode_seek(struct xdr_stream * xdr,struct nfs42_seek_res * res)476 static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
477 {
478 	int status;
479 	__be32 *p;
480 
481 	status = decode_op_hdr(xdr, OP_SEEK);
482 	if (status)
483 		return status;
484 
485 	p = xdr_inline_decode(xdr, 4 + 8);
486 	if (unlikely(!p))
487 		goto out_overflow;
488 
489 	res->sr_eof = be32_to_cpup(p++);
490 	p = xdr_decode_hyper(p, &res->sr_offset);
491 	return 0;
492 
493 out_overflow:
494 	print_overflow_msg(__func__, xdr);
495 	return -EIO;
496 }
497 
decode_layoutstats(struct xdr_stream * xdr)498 static int decode_layoutstats(struct xdr_stream *xdr)
499 {
500 	return decode_op_hdr(xdr, OP_LAYOUTSTATS);
501 }
502 
decode_clone(struct xdr_stream * xdr)503 static int decode_clone(struct xdr_stream *xdr)
504 {
505 	return decode_op_hdr(xdr, OP_CLONE);
506 }
507 
508 /*
509  * Decode ALLOCATE request
510  */
nfs4_xdr_dec_allocate(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)511 static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
512 				 struct xdr_stream *xdr,
513 				 void *data)
514 {
515 	struct nfs42_falloc_res *res = data;
516 	struct compound_hdr hdr;
517 	int status;
518 
519 	status = decode_compound_hdr(xdr, &hdr);
520 	if (status)
521 		goto out;
522 	status = decode_sequence(xdr, &res->seq_res, rqstp);
523 	if (status)
524 		goto out;
525 	status = decode_putfh(xdr);
526 	if (status)
527 		goto out;
528 	status = decode_allocate(xdr, res);
529 	if (status)
530 		goto out;
531 	decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
532 out:
533 	return status;
534 }
535 
536 /*
537  * Decode COPY response
538  */
nfs4_xdr_dec_copy(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)539 static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp,
540 			     struct xdr_stream *xdr,
541 			     void *data)
542 {
543 	struct nfs42_copy_res *res = data;
544 	struct compound_hdr hdr;
545 	int status;
546 
547 	status = decode_compound_hdr(xdr, &hdr);
548 	if (status)
549 		goto out;
550 	status = decode_sequence(xdr, &res->seq_res, rqstp);
551 	if (status)
552 		goto out;
553 	status = decode_putfh(xdr);
554 	if (status)
555 		goto out;
556 	status = decode_savefh(xdr);
557 	if (status)
558 		goto out;
559 	status = decode_putfh(xdr);
560 	if (status)
561 		goto out;
562 	status = decode_copy(xdr, res);
563 	if (status)
564 		goto out;
565 	if (res->commit_res.verf)
566 		status = decode_commit(xdr, &res->commit_res);
567 out:
568 	return status;
569 }
570 
571 /*
572  * Decode OFFLOAD_CANCEL response
573  */
nfs4_xdr_dec_offload_cancel(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)574 static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp,
575 				       struct xdr_stream *xdr,
576 				       void *data)
577 {
578 	struct nfs42_offload_status_res *res = data;
579 	struct compound_hdr hdr;
580 	int status;
581 
582 	status = decode_compound_hdr(xdr, &hdr);
583 	if (status)
584 		goto out;
585 	status = decode_sequence(xdr, &res->osr_seq_res, rqstp);
586 	if (status)
587 		goto out;
588 	status = decode_putfh(xdr);
589 	if (status)
590 		goto out;
591 	status = decode_offload_cancel(xdr, res);
592 
593 out:
594 	return status;
595 }
596 
597 /*
598  * Decode DEALLOCATE request
599  */
nfs4_xdr_dec_deallocate(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)600 static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
601 				   struct xdr_stream *xdr,
602 				   void *data)
603 {
604 	struct nfs42_falloc_res *res = data;
605 	struct compound_hdr hdr;
606 	int status;
607 
608 	status = decode_compound_hdr(xdr, &hdr);
609 	if (status)
610 		goto out;
611 	status = decode_sequence(xdr, &res->seq_res, rqstp);
612 	if (status)
613 		goto out;
614 	status = decode_putfh(xdr);
615 	if (status)
616 		goto out;
617 	status = decode_deallocate(xdr, res);
618 	if (status)
619 		goto out;
620 	decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
621 out:
622 	return status;
623 }
624 
625 /*
626  * Decode SEEK request
627  */
nfs4_xdr_dec_seek(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)628 static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
629 			     struct xdr_stream *xdr,
630 			     void *data)
631 {
632 	struct nfs42_seek_res *res = data;
633 	struct compound_hdr hdr;
634 	int status;
635 
636 	status = decode_compound_hdr(xdr, &hdr);
637 	if (status)
638 		goto out;
639 	status = decode_sequence(xdr, &res->seq_res, rqstp);
640 	if (status)
641 		goto out;
642 	status = decode_putfh(xdr);
643 	if (status)
644 		goto out;
645 	status = decode_seek(xdr, res);
646 out:
647 	return status;
648 }
649 
650 /*
651  * Decode LAYOUTSTATS request
652  */
nfs4_xdr_dec_layoutstats(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)653 static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp,
654 				    struct xdr_stream *xdr,
655 				    void *data)
656 {
657 	struct nfs42_layoutstat_res *res = data;
658 	struct compound_hdr hdr;
659 	int status, i;
660 
661 	status = decode_compound_hdr(xdr, &hdr);
662 	if (status)
663 		goto out;
664 	status = decode_sequence(xdr, &res->seq_res, rqstp);
665 	if (status)
666 		goto out;
667 	status = decode_putfh(xdr);
668 	if (status)
669 		goto out;
670 	WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
671 	for (i = 0; i < res->num_dev; i++) {
672 		status = decode_layoutstats(xdr);
673 		if (status)
674 			goto out;
675 	}
676 out:
677 	res->rpc_status = status;
678 	return status;
679 }
680 
681 /*
682  * Decode CLONE request
683  */
nfs4_xdr_dec_clone(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)684 static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp,
685 			      struct xdr_stream *xdr,
686 			      void *data)
687 {
688 	struct nfs42_clone_res *res = data;
689 	struct compound_hdr hdr;
690 	int status;
691 
692 	status = decode_compound_hdr(xdr, &hdr);
693 	if (status)
694 		goto out;
695 	status = decode_sequence(xdr, &res->seq_res, rqstp);
696 	if (status)
697 		goto out;
698 	status = decode_putfh(xdr);
699 	if (status)
700 		goto out;
701 	status = decode_savefh(xdr);
702 	if (status)
703 		goto out;
704 	status = decode_putfh(xdr);
705 	if (status)
706 		goto out;
707 	status = decode_clone(xdr);
708 	if (status)
709 		goto out;
710 	decode_getfattr(xdr, res->dst_fattr, res->server);
711 out:
712 	res->rpc_status = status;
713 	return status;
714 }
715 
716 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */
717