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