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_sequence_maxsz + \
63 encode_putfh_maxsz + \
64 encode_allocate_maxsz + \
66 #define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \
67 decode_sequence_maxsz + \
68 decode_putfh_maxsz + \
69 decode_allocate_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 + \
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 + \
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 + \
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 + \
107 #define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \
108 decode_sequence_maxsz + \
109 decode_putfh_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)
134 static void encode_fallocate(struct xdr_stream
*xdr
,
135 const struct nfs42_falloc_args
*args
)
137 encode_nfs4_stateid(xdr
, &args
->falloc_stateid
);
138 encode_uint64(xdr
, args
->falloc_offset
);
139 encode_uint64(xdr
, args
->falloc_length
);
142 static void encode_allocate(struct xdr_stream
*xdr
,
143 const struct nfs42_falloc_args
*args
,
144 struct compound_hdr
*hdr
)
146 encode_op_hdr(xdr
, OP_ALLOCATE
, decode_allocate_maxsz
, hdr
);
147 encode_fallocate(xdr
, args
);
150 static void encode_copy(struct xdr_stream
*xdr
,
151 const struct nfs42_copy_args
*args
,
152 struct compound_hdr
*hdr
)
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
);
158 encode_uint64(xdr
, args
->src_pos
);
159 encode_uint64(xdr
, args
->dst_pos
);
160 encode_uint64(xdr
, args
->count
);
162 encode_uint32(xdr
, 1); /* consecutive = true */
163 encode_uint32(xdr
, args
->sync
);
164 encode_uint32(xdr
, 0); /* src server list */
167 static void encode_offload_cancel(struct xdr_stream
*xdr
,
168 const struct nfs42_offload_status_args
*args
,
169 struct compound_hdr
*hdr
)
171 encode_op_hdr(xdr
, OP_OFFLOAD_CANCEL
, decode_offload_cancel_maxsz
, hdr
);
172 encode_nfs4_stateid(xdr
, &args
->osa_stateid
);
175 static void encode_deallocate(struct xdr_stream
*xdr
,
176 const struct nfs42_falloc_args
*args
,
177 struct compound_hdr
*hdr
)
179 encode_op_hdr(xdr
, OP_DEALLOCATE
, decode_deallocate_maxsz
, hdr
);
180 encode_fallocate(xdr
, args
);
183 static void encode_seek(struct xdr_stream
*xdr
,
184 const struct nfs42_seek_args
*args
,
185 struct compound_hdr
*hdr
)
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
);
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
)
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
);
218 encode_uint32(xdr
, 0);
221 static void encode_clone(struct xdr_stream
*xdr
,
222 const struct nfs42_clone_args
*args
,
223 struct compound_hdr
*hdr
)
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
);
237 * Encode ALLOCATE request
239 static void nfs4_xdr_enc_allocate(struct rpc_rqst
*req
,
240 struct xdr_stream
*xdr
,
243 const struct nfs42_falloc_args
*args
= data
;
244 struct compound_hdr hdr
= {
245 .minorversion
= nfs4_xdr_minorversion(&args
->seq_args
),
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
);
256 static void encode_copy_commit(struct xdr_stream
*xdr
,
257 const struct nfs42_copy_args
*args
,
258 struct compound_hdr
*hdr
)
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
);
269 * Encode COPY request
271 static void nfs4_xdr_enc_copy(struct rpc_rqst
*req
,
272 struct xdr_stream
*xdr
,
275 const struct nfs42_copy_args
*args
= data
;
276 struct compound_hdr hdr
= {
277 .minorversion
= nfs4_xdr_minorversion(&args
->seq_args
),
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
);
287 encode_copy_commit(xdr
, args
, &hdr
);
292 * Encode OFFLOAD_CANEL request
294 static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst
*req
,
295 struct xdr_stream
*xdr
,
298 const struct nfs42_offload_status_args
*args
= data
;
299 struct compound_hdr hdr
= {
300 .minorversion
= nfs4_xdr_minorversion(&args
->osa_seq_args
),
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
);
311 * Encode DEALLOCATE request
313 static void nfs4_xdr_enc_deallocate(struct rpc_rqst
*req
,
314 struct xdr_stream
*xdr
,
317 const struct nfs42_falloc_args
*args
= data
;
318 struct compound_hdr hdr
= {
319 .minorversion
= nfs4_xdr_minorversion(&args
->seq_args
),
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
);
331 * Encode SEEK request
333 static void nfs4_xdr_enc_seek(struct rpc_rqst
*req
,
334 struct xdr_stream
*xdr
,
337 const struct nfs42_seek_args
*args
= data
;
338 struct compound_hdr hdr
= {
339 .minorversion
= nfs4_xdr_minorversion(&args
->seq_args
),
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
);
350 * Encode LAYOUTSTATS request
352 static void nfs4_xdr_enc_layoutstats(struct rpc_rqst
*req
,
353 struct xdr_stream
*xdr
,
356 const struct nfs42_layoutstat_args
*args
= data
;
359 struct compound_hdr hdr
= {
360 .minorversion
= nfs4_xdr_minorversion(&args
->seq_args
),
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
);
373 * Encode CLONE request
375 static void nfs4_xdr_enc_clone(struct rpc_rqst
*req
,
376 struct xdr_stream
*xdr
,
379 const struct nfs42_clone_args
*args
= data
;
380 struct compound_hdr hdr
= {
381 .minorversion
= nfs4_xdr_minorversion(&args
->seq_args
),
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
);
394 static int decode_allocate(struct xdr_stream
*xdr
, struct nfs42_falloc_res
*res
)
396 return decode_op_hdr(xdr
, OP_ALLOCATE
);
399 static int decode_write_response(struct xdr_stream
*xdr
,
400 struct nfs42_write_res
*res
)
405 p
= xdr_inline_decode(xdr
, 4);
408 count
= be32_to_cpup(p
);
411 else if (count
== 1) {
412 status
= decode_opaque_fixed(xdr
, &res
->stateid
,
414 if (unlikely(status
))
417 p
= xdr_inline_decode(xdr
, 8 + 4);
420 p
= xdr_decode_hyper(p
, &res
->count
);
421 res
->verifier
.committed
= be32_to_cpup(p
);
422 return decode_verifier(xdr
, &res
->verifier
.verifier
);
425 print_overflow_msg(__func__
, xdr
);
429 static int decode_copy_requirements(struct xdr_stream
*xdr
,
430 struct nfs42_copy_res
*res
) {
433 p
= xdr_inline_decode(xdr
, 4 + 4);
437 res
->consecutive
= be32_to_cpup(p
++);
438 res
->synchronous
= be32_to_cpup(p
++);
441 print_overflow_msg(__func__
, xdr
);
445 static int decode_copy(struct xdr_stream
*xdr
, struct nfs42_copy_res
*res
)
449 status
= decode_op_hdr(xdr
, OP_COPY
);
450 if (status
== NFS4ERR_OFFLOAD_NO_REQS
) {
451 status
= decode_copy_requirements(xdr
, res
);
454 return NFS4ERR_OFFLOAD_NO_REQS
;
458 status
= decode_write_response(xdr
, &res
->write_res
);
462 return decode_copy_requirements(xdr
, res
);
465 static int decode_offload_cancel(struct xdr_stream
*xdr
,
466 struct nfs42_offload_status_res
*res
)
468 return decode_op_hdr(xdr
, OP_OFFLOAD_CANCEL
);
471 static int decode_deallocate(struct xdr_stream
*xdr
, struct nfs42_falloc_res
*res
)
473 return decode_op_hdr(xdr
, OP_DEALLOCATE
);
476 static int decode_seek(struct xdr_stream
*xdr
, struct nfs42_seek_res
*res
)
481 status
= decode_op_hdr(xdr
, OP_SEEK
);
485 p
= xdr_inline_decode(xdr
, 4 + 8);
489 res
->sr_eof
= be32_to_cpup(p
++);
490 p
= xdr_decode_hyper(p
, &res
->sr_offset
);
494 print_overflow_msg(__func__
, xdr
);
498 static int decode_layoutstats(struct xdr_stream
*xdr
)
500 return decode_op_hdr(xdr
, OP_LAYOUTSTATS
);
503 static int decode_clone(struct xdr_stream
*xdr
)
505 return decode_op_hdr(xdr
, OP_CLONE
);
509 * Decode ALLOCATE request
511 static int nfs4_xdr_dec_allocate(struct rpc_rqst
*rqstp
,
512 struct xdr_stream
*xdr
,
515 struct nfs42_falloc_res
*res
= data
;
516 struct compound_hdr hdr
;
519 status
= decode_compound_hdr(xdr
, &hdr
);
522 status
= decode_sequence(xdr
, &res
->seq_res
, rqstp
);
525 status
= decode_putfh(xdr
);
528 status
= decode_allocate(xdr
, res
);
531 decode_getfattr(xdr
, res
->falloc_fattr
, res
->falloc_server
);
537 * Decode COPY response
539 static int nfs4_xdr_dec_copy(struct rpc_rqst
*rqstp
,
540 struct xdr_stream
*xdr
,
543 struct nfs42_copy_res
*res
= data
;
544 struct compound_hdr hdr
;
547 status
= decode_compound_hdr(xdr
, &hdr
);
550 status
= decode_sequence(xdr
, &res
->seq_res
, rqstp
);
553 status
= decode_putfh(xdr
);
556 status
= decode_savefh(xdr
);
559 status
= decode_putfh(xdr
);
562 status
= decode_copy(xdr
, res
);
565 if (res
->commit_res
.verf
)
566 status
= decode_commit(xdr
, &res
->commit_res
);
572 * Decode OFFLOAD_CANCEL response
574 static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst
*rqstp
,
575 struct xdr_stream
*xdr
,
578 struct nfs42_offload_status_res
*res
= data
;
579 struct compound_hdr hdr
;
582 status
= decode_compound_hdr(xdr
, &hdr
);
585 status
= decode_sequence(xdr
, &res
->osr_seq_res
, rqstp
);
588 status
= decode_putfh(xdr
);
591 status
= decode_offload_cancel(xdr
, res
);
598 * Decode DEALLOCATE request
600 static int nfs4_xdr_dec_deallocate(struct rpc_rqst
*rqstp
,
601 struct xdr_stream
*xdr
,
604 struct nfs42_falloc_res
*res
= data
;
605 struct compound_hdr hdr
;
608 status
= decode_compound_hdr(xdr
, &hdr
);
611 status
= decode_sequence(xdr
, &res
->seq_res
, rqstp
);
614 status
= decode_putfh(xdr
);
617 status
= decode_deallocate(xdr
, res
);
620 decode_getfattr(xdr
, res
->falloc_fattr
, res
->falloc_server
);
626 * Decode SEEK request
628 static int nfs4_xdr_dec_seek(struct rpc_rqst
*rqstp
,
629 struct xdr_stream
*xdr
,
632 struct nfs42_seek_res
*res
= data
;
633 struct compound_hdr hdr
;
636 status
= decode_compound_hdr(xdr
, &hdr
);
639 status
= decode_sequence(xdr
, &res
->seq_res
, rqstp
);
642 status
= decode_putfh(xdr
);
645 status
= decode_seek(xdr
, res
);
651 * Decode LAYOUTSTATS request
653 static int nfs4_xdr_dec_layoutstats(struct rpc_rqst
*rqstp
,
654 struct xdr_stream
*xdr
,
657 struct nfs42_layoutstat_res
*res
= data
;
658 struct compound_hdr hdr
;
661 status
= decode_compound_hdr(xdr
, &hdr
);
664 status
= decode_sequence(xdr
, &res
->seq_res
, rqstp
);
667 status
= decode_putfh(xdr
);
670 WARN_ON(res
->num_dev
> PNFS_LAYOUTSTATS_MAXDEV
);
671 for (i
= 0; i
< res
->num_dev
; i
++) {
672 status
= decode_layoutstats(xdr
);
677 res
->rpc_status
= status
;
682 * Decode CLONE request
684 static int nfs4_xdr_dec_clone(struct rpc_rqst
*rqstp
,
685 struct xdr_stream
*xdr
,
688 struct nfs42_clone_res
*res
= data
;
689 struct compound_hdr hdr
;
692 status
= decode_compound_hdr(xdr
, &hdr
);
695 status
= decode_sequence(xdr
, &res
->seq_res
, rqstp
);
698 status
= decode_putfh(xdr
);
701 status
= decode_savefh(xdr
);
704 status
= decode_putfh(xdr
);
707 status
= decode_clone(xdr
);
710 status
= decode_getfattr(xdr
, res
->dst_fattr
, res
->server
);
713 res
->rpc_status
= status
;
717 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */