1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>
5 #ifndef __LINUX_FS_NFS_NFS4_2XDR_H
6 #define __LINUX_FS_NFS_NFS4_2XDR_H
10 #define encode_fallocate_maxsz (encode_stateid_maxsz + \
13 #define NFS42_WRITE_RES_SIZE (1 /* wr_callback_id size */ +\
14 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
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 + \
39 #define decode_seek_maxsz (op_decode_hdr_maxsz + \
44 #define encode_io_info_maxsz 4
45 #define encode_layoutstats_maxsz (op_decode_hdr_maxsz + \
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 */ + \
59 #define decode_clone_maxsz (op_decode_hdr_maxsz)
61 #define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \
62 encode_putfh_maxsz + \
63 encode_allocate_maxsz + \
65 #define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \
66 decode_putfh_maxsz + \
67 decode_allocate_maxsz + \
69 #define NFS4_enc_copy_sz (compound_encode_hdr_maxsz + \
70 encode_putfh_maxsz + \
71 encode_savefh_maxsz + \
72 encode_putfh_maxsz + \
75 #define NFS4_dec_copy_sz (compound_decode_hdr_maxsz + \
76 decode_putfh_maxsz + \
77 decode_savefh_maxsz + \
78 decode_putfh_maxsz + \
81 #define NFS4_enc_offload_cancel_sz (compound_encode_hdr_maxsz + \
82 encode_putfh_maxsz + \
83 encode_offload_cancel_maxsz)
84 #define NFS4_dec_offload_cancel_sz (compound_decode_hdr_maxsz + \
85 decode_putfh_maxsz + \
86 decode_offload_cancel_maxsz)
87 #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \
88 encode_putfh_maxsz + \
89 encode_deallocate_maxsz + \
91 #define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \
92 decode_putfh_maxsz + \
93 decode_deallocate_maxsz + \
95 #define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \
96 encode_putfh_maxsz + \
98 #define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \
99 decode_putfh_maxsz + \
101 #define NFS4_enc_layoutstats_sz (compound_encode_hdr_maxsz + \
102 encode_sequence_maxsz + \
103 encode_putfh_maxsz + \
104 PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz)
105 #define NFS4_dec_layoutstats_sz (compound_decode_hdr_maxsz + \
106 decode_sequence_maxsz + \
107 decode_putfh_maxsz + \
108 PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz)
109 #define NFS4_enc_clone_sz (compound_encode_hdr_maxsz + \
110 encode_sequence_maxsz + \
111 encode_putfh_maxsz + \
112 encode_savefh_maxsz + \
113 encode_putfh_maxsz + \
114 encode_clone_maxsz + \
115 encode_getattr_maxsz)
116 #define NFS4_dec_clone_sz (compound_decode_hdr_maxsz + \
117 decode_sequence_maxsz + \
118 decode_putfh_maxsz + \
119 decode_savefh_maxsz + \
120 decode_putfh_maxsz + \
121 decode_clone_maxsz + \
122 decode_getattr_maxsz)
124 static void encode_fallocate(struct xdr_stream
*xdr
,
125 const struct nfs42_falloc_args
*args
)
127 encode_nfs4_stateid(xdr
, &args
->falloc_stateid
);
128 encode_uint64(xdr
, args
->falloc_offset
);
129 encode_uint64(xdr
, args
->falloc_length
);
132 static void encode_allocate(struct xdr_stream
*xdr
,
133 const struct nfs42_falloc_args
*args
,
134 struct compound_hdr
*hdr
)
136 encode_op_hdr(xdr
, OP_ALLOCATE
, decode_allocate_maxsz
, hdr
);
137 encode_fallocate(xdr
, args
);
140 static void encode_copy(struct xdr_stream
*xdr
,
141 const struct nfs42_copy_args
*args
,
142 struct compound_hdr
*hdr
)
144 encode_op_hdr(xdr
, OP_COPY
, decode_copy_maxsz
, hdr
);
145 encode_nfs4_stateid(xdr
, &args
->src_stateid
);
146 encode_nfs4_stateid(xdr
, &args
->dst_stateid
);
148 encode_uint64(xdr
, args
->src_pos
);
149 encode_uint64(xdr
, args
->dst_pos
);
150 encode_uint64(xdr
, args
->count
);
152 encode_uint32(xdr
, 1); /* consecutive = true */
153 encode_uint32(xdr
, args
->sync
);
154 encode_uint32(xdr
, 0); /* src server list */
157 static void encode_offload_cancel(struct xdr_stream
*xdr
,
158 const struct nfs42_offload_status_args
*args
,
159 struct compound_hdr
*hdr
)
161 encode_op_hdr(xdr
, OP_OFFLOAD_CANCEL
, decode_offload_cancel_maxsz
, hdr
);
162 encode_nfs4_stateid(xdr
, &args
->osa_stateid
);
165 static void encode_deallocate(struct xdr_stream
*xdr
,
166 const struct nfs42_falloc_args
*args
,
167 struct compound_hdr
*hdr
)
169 encode_op_hdr(xdr
, OP_DEALLOCATE
, decode_deallocate_maxsz
, hdr
);
170 encode_fallocate(xdr
, args
);
173 static void encode_seek(struct xdr_stream
*xdr
,
174 const struct nfs42_seek_args
*args
,
175 struct compound_hdr
*hdr
)
177 encode_op_hdr(xdr
, OP_SEEK
, decode_seek_maxsz
, hdr
);
178 encode_nfs4_stateid(xdr
, &args
->sa_stateid
);
179 encode_uint64(xdr
, args
->sa_offset
);
180 encode_uint32(xdr
, args
->sa_what
);
183 static void encode_layoutstats(struct xdr_stream
*xdr
,
184 const struct nfs42_layoutstat_args
*args
,
185 struct nfs42_layoutstat_devinfo
*devinfo
,
186 struct compound_hdr
*hdr
)
190 encode_op_hdr(xdr
, OP_LAYOUTSTATS
, decode_layoutstats_maxsz
, hdr
);
191 p
= reserve_space(xdr
, 8 + 8);
192 p
= xdr_encode_hyper(p
, devinfo
->offset
);
193 p
= xdr_encode_hyper(p
, devinfo
->length
);
194 encode_nfs4_stateid(xdr
, &args
->stateid
);
195 p
= reserve_space(xdr
, 4*8 + NFS4_DEVICEID4_SIZE
+ 4);
196 p
= xdr_encode_hyper(p
, devinfo
->read_count
);
197 p
= xdr_encode_hyper(p
, devinfo
->read_bytes
);
198 p
= xdr_encode_hyper(p
, devinfo
->write_count
);
199 p
= xdr_encode_hyper(p
, devinfo
->write_bytes
);
200 p
= xdr_encode_opaque_fixed(p
, devinfo
->dev_id
.data
,
201 NFS4_DEVICEID4_SIZE
);
202 /* Encode layoutupdate4 */
203 *p
++ = cpu_to_be32(devinfo
->layout_type
);
204 if (devinfo
->ld_private
.ops
)
205 devinfo
->ld_private
.ops
->encode(xdr
, args
,
206 &devinfo
->ld_private
);
208 encode_uint32(xdr
, 0);
211 static void encode_clone(struct xdr_stream
*xdr
,
212 const struct nfs42_clone_args
*args
,
213 struct compound_hdr
*hdr
)
217 encode_op_hdr(xdr
, OP_CLONE
, decode_clone_maxsz
, hdr
);
218 encode_nfs4_stateid(xdr
, &args
->src_stateid
);
219 encode_nfs4_stateid(xdr
, &args
->dst_stateid
);
220 p
= reserve_space(xdr
, 3*8);
221 p
= xdr_encode_hyper(p
, args
->src_offset
);
222 p
= xdr_encode_hyper(p
, args
->dst_offset
);
223 xdr_encode_hyper(p
, args
->count
);
227 * Encode ALLOCATE request
229 static void nfs4_xdr_enc_allocate(struct rpc_rqst
*req
,
230 struct xdr_stream
*xdr
,
233 const struct nfs42_falloc_args
*args
= data
;
234 struct compound_hdr hdr
= {
235 .minorversion
= nfs4_xdr_minorversion(&args
->seq_args
),
238 encode_compound_hdr(xdr
, req
, &hdr
);
239 encode_sequence(xdr
, &args
->seq_args
, &hdr
);
240 encode_putfh(xdr
, args
->falloc_fh
, &hdr
);
241 encode_allocate(xdr
, args
, &hdr
);
242 encode_getfattr(xdr
, args
->falloc_bitmask
, &hdr
);
246 static void encode_copy_commit(struct xdr_stream
*xdr
,
247 const struct nfs42_copy_args
*args
,
248 struct compound_hdr
*hdr
)
252 encode_op_hdr(xdr
, OP_COMMIT
, decode_commit_maxsz
, hdr
);
253 p
= reserve_space(xdr
, 12);
254 p
= xdr_encode_hyper(p
, args
->dst_pos
);
255 *p
= cpu_to_be32(args
->count
);
259 * Encode COPY request
261 static void nfs4_xdr_enc_copy(struct rpc_rqst
*req
,
262 struct xdr_stream
*xdr
,
265 const struct nfs42_copy_args
*args
= data
;
266 struct compound_hdr hdr
= {
267 .minorversion
= nfs4_xdr_minorversion(&args
->seq_args
),
270 encode_compound_hdr(xdr
, req
, &hdr
);
271 encode_sequence(xdr
, &args
->seq_args
, &hdr
);
272 encode_putfh(xdr
, args
->src_fh
, &hdr
);
273 encode_savefh(xdr
, &hdr
);
274 encode_putfh(xdr
, args
->dst_fh
, &hdr
);
275 encode_copy(xdr
, args
, &hdr
);
277 encode_copy_commit(xdr
, args
, &hdr
);
282 * Encode OFFLOAD_CANEL request
284 static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst
*req
,
285 struct xdr_stream
*xdr
,
288 const struct nfs42_offload_status_args
*args
= data
;
289 struct compound_hdr hdr
= {
290 .minorversion
= nfs4_xdr_minorversion(&args
->osa_seq_args
),
293 encode_compound_hdr(xdr
, req
, &hdr
);
294 encode_sequence(xdr
, &args
->osa_seq_args
, &hdr
);
295 encode_putfh(xdr
, args
->osa_src_fh
, &hdr
);
296 encode_offload_cancel(xdr
, args
, &hdr
);
301 * Encode DEALLOCATE request
303 static void nfs4_xdr_enc_deallocate(struct rpc_rqst
*req
,
304 struct xdr_stream
*xdr
,
307 const struct nfs42_falloc_args
*args
= data
;
308 struct compound_hdr hdr
= {
309 .minorversion
= nfs4_xdr_minorversion(&args
->seq_args
),
312 encode_compound_hdr(xdr
, req
, &hdr
);
313 encode_sequence(xdr
, &args
->seq_args
, &hdr
);
314 encode_putfh(xdr
, args
->falloc_fh
, &hdr
);
315 encode_deallocate(xdr
, args
, &hdr
);
316 encode_getfattr(xdr
, args
->falloc_bitmask
, &hdr
);
321 * Encode SEEK request
323 static void nfs4_xdr_enc_seek(struct rpc_rqst
*req
,
324 struct xdr_stream
*xdr
,
327 const struct nfs42_seek_args
*args
= data
;
328 struct compound_hdr hdr
= {
329 .minorversion
= nfs4_xdr_minorversion(&args
->seq_args
),
332 encode_compound_hdr(xdr
, req
, &hdr
);
333 encode_sequence(xdr
, &args
->seq_args
, &hdr
);
334 encode_putfh(xdr
, args
->sa_fh
, &hdr
);
335 encode_seek(xdr
, args
, &hdr
);
340 * Encode LAYOUTSTATS request
342 static void nfs4_xdr_enc_layoutstats(struct rpc_rqst
*req
,
343 struct xdr_stream
*xdr
,
346 const struct nfs42_layoutstat_args
*args
= data
;
349 struct compound_hdr hdr
= {
350 .minorversion
= nfs4_xdr_minorversion(&args
->seq_args
),
353 encode_compound_hdr(xdr
, req
, &hdr
);
354 encode_sequence(xdr
, &args
->seq_args
, &hdr
);
355 encode_putfh(xdr
, args
->fh
, &hdr
);
356 WARN_ON(args
->num_dev
> PNFS_LAYOUTSTATS_MAXDEV
);
357 for (i
= 0; i
< args
->num_dev
; i
++)
358 encode_layoutstats(xdr
, args
, &args
->devinfo
[i
], &hdr
);
363 * Encode CLONE request
365 static void nfs4_xdr_enc_clone(struct rpc_rqst
*req
,
366 struct xdr_stream
*xdr
,
369 const struct nfs42_clone_args
*args
= data
;
370 struct compound_hdr hdr
= {
371 .minorversion
= nfs4_xdr_minorversion(&args
->seq_args
),
374 encode_compound_hdr(xdr
, req
, &hdr
);
375 encode_sequence(xdr
, &args
->seq_args
, &hdr
);
376 encode_putfh(xdr
, args
->src_fh
, &hdr
);
377 encode_savefh(xdr
, &hdr
);
378 encode_putfh(xdr
, args
->dst_fh
, &hdr
);
379 encode_clone(xdr
, args
, &hdr
);
380 encode_getfattr(xdr
, args
->dst_bitmask
, &hdr
);
384 static int decode_allocate(struct xdr_stream
*xdr
, struct nfs42_falloc_res
*res
)
386 return decode_op_hdr(xdr
, OP_ALLOCATE
);
389 static int decode_write_response(struct xdr_stream
*xdr
,
390 struct nfs42_write_res
*res
)
395 p
= xdr_inline_decode(xdr
, 4);
398 count
= be32_to_cpup(p
);
401 else if (count
== 1) {
402 status
= decode_opaque_fixed(xdr
, &res
->stateid
,
404 if (unlikely(status
))
407 p
= xdr_inline_decode(xdr
, 8 + 4);
410 p
= xdr_decode_hyper(p
, &res
->count
);
411 res
->verifier
.committed
= be32_to_cpup(p
);
412 return decode_verifier(xdr
, &res
->verifier
.verifier
);
415 print_overflow_msg(__func__
, xdr
);
419 static int decode_copy_requirements(struct xdr_stream
*xdr
,
420 struct nfs42_copy_res
*res
) {
423 p
= xdr_inline_decode(xdr
, 4 + 4);
427 res
->consecutive
= be32_to_cpup(p
++);
428 res
->synchronous
= be32_to_cpup(p
++);
431 print_overflow_msg(__func__
, xdr
);
435 static int decode_copy(struct xdr_stream
*xdr
, struct nfs42_copy_res
*res
)
439 status
= decode_op_hdr(xdr
, OP_COPY
);
440 if (status
== NFS4ERR_OFFLOAD_NO_REQS
) {
441 status
= decode_copy_requirements(xdr
, res
);
444 return NFS4ERR_OFFLOAD_NO_REQS
;
448 status
= decode_write_response(xdr
, &res
->write_res
);
452 return decode_copy_requirements(xdr
, res
);
455 static int decode_offload_cancel(struct xdr_stream
*xdr
,
456 struct nfs42_offload_status_res
*res
)
458 return decode_op_hdr(xdr
, OP_OFFLOAD_CANCEL
);
461 static int decode_deallocate(struct xdr_stream
*xdr
, struct nfs42_falloc_res
*res
)
463 return decode_op_hdr(xdr
, OP_DEALLOCATE
);
466 static int decode_seek(struct xdr_stream
*xdr
, struct nfs42_seek_res
*res
)
471 status
= decode_op_hdr(xdr
, OP_SEEK
);
475 p
= xdr_inline_decode(xdr
, 4 + 8);
479 res
->sr_eof
= be32_to_cpup(p
++);
480 p
= xdr_decode_hyper(p
, &res
->sr_offset
);
484 print_overflow_msg(__func__
, xdr
);
488 static int decode_layoutstats(struct xdr_stream
*xdr
)
490 return decode_op_hdr(xdr
, OP_LAYOUTSTATS
);
493 static int decode_clone(struct xdr_stream
*xdr
)
495 return decode_op_hdr(xdr
, OP_CLONE
);
499 * Decode ALLOCATE request
501 static int nfs4_xdr_dec_allocate(struct rpc_rqst
*rqstp
,
502 struct xdr_stream
*xdr
,
505 struct nfs42_falloc_res
*res
= data
;
506 struct compound_hdr hdr
;
509 status
= decode_compound_hdr(xdr
, &hdr
);
512 status
= decode_sequence(xdr
, &res
->seq_res
, rqstp
);
515 status
= decode_putfh(xdr
);
518 status
= decode_allocate(xdr
, res
);
521 decode_getfattr(xdr
, res
->falloc_fattr
, res
->falloc_server
);
527 * Decode COPY response
529 static int nfs4_xdr_dec_copy(struct rpc_rqst
*rqstp
,
530 struct xdr_stream
*xdr
,
533 struct nfs42_copy_res
*res
= data
;
534 struct compound_hdr hdr
;
537 status
= decode_compound_hdr(xdr
, &hdr
);
540 status
= decode_sequence(xdr
, &res
->seq_res
, rqstp
);
543 status
= decode_putfh(xdr
);
546 status
= decode_savefh(xdr
);
549 status
= decode_putfh(xdr
);
552 status
= decode_copy(xdr
, res
);
555 if (res
->commit_res
.verf
)
556 status
= decode_commit(xdr
, &res
->commit_res
);
562 * Decode OFFLOAD_CANCEL response
564 static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst
*rqstp
,
565 struct xdr_stream
*xdr
,
568 struct nfs42_offload_status_res
*res
= data
;
569 struct compound_hdr hdr
;
572 status
= decode_compound_hdr(xdr
, &hdr
);
575 status
= decode_sequence(xdr
, &res
->osr_seq_res
, rqstp
);
578 status
= decode_putfh(xdr
);
581 status
= decode_offload_cancel(xdr
, res
);
588 * Decode DEALLOCATE request
590 static int nfs4_xdr_dec_deallocate(struct rpc_rqst
*rqstp
,
591 struct xdr_stream
*xdr
,
594 struct nfs42_falloc_res
*res
= data
;
595 struct compound_hdr hdr
;
598 status
= decode_compound_hdr(xdr
, &hdr
);
601 status
= decode_sequence(xdr
, &res
->seq_res
, rqstp
);
604 status
= decode_putfh(xdr
);
607 status
= decode_deallocate(xdr
, res
);
610 decode_getfattr(xdr
, res
->falloc_fattr
, res
->falloc_server
);
616 * Decode SEEK request
618 static int nfs4_xdr_dec_seek(struct rpc_rqst
*rqstp
,
619 struct xdr_stream
*xdr
,
622 struct nfs42_seek_res
*res
= data
;
623 struct compound_hdr hdr
;
626 status
= decode_compound_hdr(xdr
, &hdr
);
629 status
= decode_sequence(xdr
, &res
->seq_res
, rqstp
);
632 status
= decode_putfh(xdr
);
635 status
= decode_seek(xdr
, res
);
641 * Decode LAYOUTSTATS request
643 static int nfs4_xdr_dec_layoutstats(struct rpc_rqst
*rqstp
,
644 struct xdr_stream
*xdr
,
647 struct nfs42_layoutstat_res
*res
= data
;
648 struct compound_hdr hdr
;
651 status
= decode_compound_hdr(xdr
, &hdr
);
654 status
= decode_sequence(xdr
, &res
->seq_res
, rqstp
);
657 status
= decode_putfh(xdr
);
660 WARN_ON(res
->num_dev
> PNFS_LAYOUTSTATS_MAXDEV
);
661 for (i
= 0; i
< res
->num_dev
; i
++) {
662 status
= decode_layoutstats(xdr
);
667 res
->rpc_status
= status
;
672 * Decode CLONE request
674 static int nfs4_xdr_dec_clone(struct rpc_rqst
*rqstp
,
675 struct xdr_stream
*xdr
,
678 struct nfs42_clone_res
*res
= data
;
679 struct compound_hdr hdr
;
682 status
= decode_compound_hdr(xdr
, &hdr
);
685 status
= decode_sequence(xdr
, &res
->seq_res
, rqstp
);
688 status
= decode_putfh(xdr
);
691 status
= decode_savefh(xdr
);
694 status
= decode_putfh(xdr
);
697 status
= decode_clone(xdr
);
700 status
= decode_getfattr(xdr
, res
->dst_fattr
, res
->server
);
703 res
->rpc_status
= status
;
707 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */