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