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_deallocate_maxsz (op_encode_hdr_maxsz + \
30 encode_fallocate_maxsz)
31 #define decode_deallocate_maxsz (op_decode_hdr_maxsz)
32 #define encode_seek_maxsz (op_encode_hdr_maxsz + \
33 encode_stateid_maxsz + \
36 #define decode_seek_maxsz (op_decode_hdr_maxsz + \
41 #define encode_io_info_maxsz 4
42 #define encode_layoutstats_maxsz (op_decode_hdr_maxsz + \
45 encode_stateid_maxsz + \
46 encode_io_info_maxsz + \
47 encode_io_info_maxsz + \
48 1 /* opaque devaddr4 length */ + \
49 XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE))
50 #define decode_layoutstats_maxsz (op_decode_hdr_maxsz)
51 #define encode_clone_maxsz (encode_stateid_maxsz + \
52 encode_stateid_maxsz + \
53 2 /* src offset */ + \
54 2 /* dst offset */ + \
56 #define decode_clone_maxsz (op_decode_hdr_maxsz)
58 #define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \
59 encode_putfh_maxsz + \
60 encode_allocate_maxsz + \
62 #define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \
63 decode_putfh_maxsz + \
64 decode_allocate_maxsz + \
66 #define NFS4_enc_copy_sz (compound_encode_hdr_maxsz + \
67 encode_putfh_maxsz + \
68 encode_savefh_maxsz + \
69 encode_putfh_maxsz + \
72 #define NFS4_dec_copy_sz (compound_decode_hdr_maxsz + \
73 decode_putfh_maxsz + \
74 decode_savefh_maxsz + \
75 decode_putfh_maxsz + \
78 #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \
79 encode_putfh_maxsz + \
80 encode_deallocate_maxsz + \
82 #define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \
83 decode_putfh_maxsz + \
84 decode_deallocate_maxsz + \
86 #define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \
87 encode_putfh_maxsz + \
89 #define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \
90 decode_putfh_maxsz + \
92 #define NFS4_enc_layoutstats_sz (compound_encode_hdr_maxsz + \
93 encode_sequence_maxsz + \
94 encode_putfh_maxsz + \
95 PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz)
96 #define NFS4_dec_layoutstats_sz (compound_decode_hdr_maxsz + \
97 decode_sequence_maxsz + \
98 decode_putfh_maxsz + \
99 PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz)
100 #define NFS4_enc_clone_sz (compound_encode_hdr_maxsz + \
101 encode_sequence_maxsz + \
102 encode_putfh_maxsz + \
103 encode_savefh_maxsz + \
104 encode_putfh_maxsz + \
105 encode_clone_maxsz + \
106 encode_getattr_maxsz)
107 #define NFS4_dec_clone_sz (compound_decode_hdr_maxsz + \
108 decode_sequence_maxsz + \
109 decode_putfh_maxsz + \
110 decode_savefh_maxsz + \
111 decode_putfh_maxsz + \
112 decode_clone_maxsz + \
113 decode_getattr_maxsz)
115 static void encode_fallocate(struct xdr_stream
*xdr
,
116 const struct nfs42_falloc_args
*args
)
118 encode_nfs4_stateid(xdr
, &args
->falloc_stateid
);
119 encode_uint64(xdr
, args
->falloc_offset
);
120 encode_uint64(xdr
, args
->falloc_length
);
123 static void encode_allocate(struct xdr_stream
*xdr
,
124 const struct nfs42_falloc_args
*args
,
125 struct compound_hdr
*hdr
)
127 encode_op_hdr(xdr
, OP_ALLOCATE
, decode_allocate_maxsz
, hdr
);
128 encode_fallocate(xdr
, args
);
131 static void encode_copy(struct xdr_stream
*xdr
,
132 const struct nfs42_copy_args
*args
,
133 struct compound_hdr
*hdr
)
135 encode_op_hdr(xdr
, OP_COPY
, decode_copy_maxsz
, hdr
);
136 encode_nfs4_stateid(xdr
, &args
->src_stateid
);
137 encode_nfs4_stateid(xdr
, &args
->dst_stateid
);
139 encode_uint64(xdr
, args
->src_pos
);
140 encode_uint64(xdr
, args
->dst_pos
);
141 encode_uint64(xdr
, args
->count
);
143 encode_uint32(xdr
, 1); /* consecutive = true */
144 encode_uint32(xdr
, 1); /* synchronous = true */
145 encode_uint32(xdr
, 0); /* src server list */
148 static void encode_deallocate(struct xdr_stream
*xdr
,
149 const struct nfs42_falloc_args
*args
,
150 struct compound_hdr
*hdr
)
152 encode_op_hdr(xdr
, OP_DEALLOCATE
, decode_deallocate_maxsz
, hdr
);
153 encode_fallocate(xdr
, args
);
156 static void encode_seek(struct xdr_stream
*xdr
,
157 const struct nfs42_seek_args
*args
,
158 struct compound_hdr
*hdr
)
160 encode_op_hdr(xdr
, OP_SEEK
, decode_seek_maxsz
, hdr
);
161 encode_nfs4_stateid(xdr
, &args
->sa_stateid
);
162 encode_uint64(xdr
, args
->sa_offset
);
163 encode_uint32(xdr
, args
->sa_what
);
166 static void encode_layoutstats(struct xdr_stream
*xdr
,
167 const struct nfs42_layoutstat_args
*args
,
168 struct nfs42_layoutstat_devinfo
*devinfo
,
169 struct compound_hdr
*hdr
)
173 encode_op_hdr(xdr
, OP_LAYOUTSTATS
, decode_layoutstats_maxsz
, hdr
);
174 p
= reserve_space(xdr
, 8 + 8);
175 p
= xdr_encode_hyper(p
, devinfo
->offset
);
176 p
= xdr_encode_hyper(p
, devinfo
->length
);
177 encode_nfs4_stateid(xdr
, &args
->stateid
);
178 p
= reserve_space(xdr
, 4*8 + NFS4_DEVICEID4_SIZE
+ 4);
179 p
= xdr_encode_hyper(p
, devinfo
->read_count
);
180 p
= xdr_encode_hyper(p
, devinfo
->read_bytes
);
181 p
= xdr_encode_hyper(p
, devinfo
->write_count
);
182 p
= xdr_encode_hyper(p
, devinfo
->write_bytes
);
183 p
= xdr_encode_opaque_fixed(p
, devinfo
->dev_id
.data
,
184 NFS4_DEVICEID4_SIZE
);
185 /* Encode layoutupdate4 */
186 *p
++ = cpu_to_be32(devinfo
->layout_type
);
187 if (devinfo
->ld_private
.ops
)
188 devinfo
->ld_private
.ops
->encode(xdr
, args
,
189 &devinfo
->ld_private
);
191 encode_uint32(xdr
, 0);
194 static void encode_clone(struct xdr_stream
*xdr
,
195 const struct nfs42_clone_args
*args
,
196 struct compound_hdr
*hdr
)
200 encode_op_hdr(xdr
, OP_CLONE
, decode_clone_maxsz
, hdr
);
201 encode_nfs4_stateid(xdr
, &args
->src_stateid
);
202 encode_nfs4_stateid(xdr
, &args
->dst_stateid
);
203 p
= reserve_space(xdr
, 3*8);
204 p
= xdr_encode_hyper(p
, args
->src_offset
);
205 p
= xdr_encode_hyper(p
, args
->dst_offset
);
206 xdr_encode_hyper(p
, args
->count
);
210 * Encode ALLOCATE request
212 static void nfs4_xdr_enc_allocate(struct rpc_rqst
*req
,
213 struct xdr_stream
*xdr
,
216 const struct nfs42_falloc_args
*args
= data
;
217 struct compound_hdr hdr
= {
218 .minorversion
= nfs4_xdr_minorversion(&args
->seq_args
),
221 encode_compound_hdr(xdr
, req
, &hdr
);
222 encode_sequence(xdr
, &args
->seq_args
, &hdr
);
223 encode_putfh(xdr
, args
->falloc_fh
, &hdr
);
224 encode_allocate(xdr
, args
, &hdr
);
225 encode_getfattr(xdr
, args
->falloc_bitmask
, &hdr
);
229 static void encode_copy_commit(struct xdr_stream
*xdr
,
230 const struct nfs42_copy_args
*args
,
231 struct compound_hdr
*hdr
)
235 encode_op_hdr(xdr
, OP_COMMIT
, decode_commit_maxsz
, hdr
);
236 p
= reserve_space(xdr
, 12);
237 p
= xdr_encode_hyper(p
, args
->dst_pos
);
238 *p
= cpu_to_be32(args
->count
);
242 * Encode COPY request
244 static void nfs4_xdr_enc_copy(struct rpc_rqst
*req
,
245 struct xdr_stream
*xdr
,
248 const struct nfs42_copy_args
*args
= data
;
249 struct compound_hdr hdr
= {
250 .minorversion
= nfs4_xdr_minorversion(&args
->seq_args
),
253 encode_compound_hdr(xdr
, req
, &hdr
);
254 encode_sequence(xdr
, &args
->seq_args
, &hdr
);
255 encode_putfh(xdr
, args
->src_fh
, &hdr
);
256 encode_savefh(xdr
, &hdr
);
257 encode_putfh(xdr
, args
->dst_fh
, &hdr
);
258 encode_copy(xdr
, args
, &hdr
);
259 encode_copy_commit(xdr
, args
, &hdr
);
264 * Encode DEALLOCATE request
266 static void nfs4_xdr_enc_deallocate(struct rpc_rqst
*req
,
267 struct xdr_stream
*xdr
,
270 const struct nfs42_falloc_args
*args
= data
;
271 struct compound_hdr hdr
= {
272 .minorversion
= nfs4_xdr_minorversion(&args
->seq_args
),
275 encode_compound_hdr(xdr
, req
, &hdr
);
276 encode_sequence(xdr
, &args
->seq_args
, &hdr
);
277 encode_putfh(xdr
, args
->falloc_fh
, &hdr
);
278 encode_deallocate(xdr
, args
, &hdr
);
279 encode_getfattr(xdr
, args
->falloc_bitmask
, &hdr
);
284 * Encode SEEK request
286 static void nfs4_xdr_enc_seek(struct rpc_rqst
*req
,
287 struct xdr_stream
*xdr
,
290 const struct nfs42_seek_args
*args
= data
;
291 struct compound_hdr hdr
= {
292 .minorversion
= nfs4_xdr_minorversion(&args
->seq_args
),
295 encode_compound_hdr(xdr
, req
, &hdr
);
296 encode_sequence(xdr
, &args
->seq_args
, &hdr
);
297 encode_putfh(xdr
, args
->sa_fh
, &hdr
);
298 encode_seek(xdr
, args
, &hdr
);
303 * Encode LAYOUTSTATS request
305 static void nfs4_xdr_enc_layoutstats(struct rpc_rqst
*req
,
306 struct xdr_stream
*xdr
,
309 const struct nfs42_layoutstat_args
*args
= data
;
312 struct compound_hdr hdr
= {
313 .minorversion
= nfs4_xdr_minorversion(&args
->seq_args
),
316 encode_compound_hdr(xdr
, req
, &hdr
);
317 encode_sequence(xdr
, &args
->seq_args
, &hdr
);
318 encode_putfh(xdr
, args
->fh
, &hdr
);
319 WARN_ON(args
->num_dev
> PNFS_LAYOUTSTATS_MAXDEV
);
320 for (i
= 0; i
< args
->num_dev
; i
++)
321 encode_layoutstats(xdr
, args
, &args
->devinfo
[i
], &hdr
);
326 * Encode CLONE request
328 static void nfs4_xdr_enc_clone(struct rpc_rqst
*req
,
329 struct xdr_stream
*xdr
,
332 const struct nfs42_clone_args
*args
= data
;
333 struct compound_hdr hdr
= {
334 .minorversion
= nfs4_xdr_minorversion(&args
->seq_args
),
337 encode_compound_hdr(xdr
, req
, &hdr
);
338 encode_sequence(xdr
, &args
->seq_args
, &hdr
);
339 encode_putfh(xdr
, args
->src_fh
, &hdr
);
340 encode_savefh(xdr
, &hdr
);
341 encode_putfh(xdr
, args
->dst_fh
, &hdr
);
342 encode_clone(xdr
, args
, &hdr
);
343 encode_getfattr(xdr
, args
->dst_bitmask
, &hdr
);
347 static int decode_allocate(struct xdr_stream
*xdr
, struct nfs42_falloc_res
*res
)
349 return decode_op_hdr(xdr
, OP_ALLOCATE
);
352 static int decode_write_response(struct xdr_stream
*xdr
,
353 struct nfs42_write_res
*res
)
357 p
= xdr_inline_decode(xdr
, 4 + 8 + 4);
362 * We never use asynchronous mode, so warn if a server returns
365 if (unlikely(*p
!= 0)) {
366 pr_err_once("%s: server has set unrequested "
367 "asynchronous mode\n", __func__
);
371 p
= xdr_decode_hyper(p
, &res
->count
);
372 res
->verifier
.committed
= be32_to_cpup(p
);
373 return decode_verifier(xdr
, &res
->verifier
.verifier
);
376 print_overflow_msg(__func__
, xdr
);
380 static int decode_copy_requirements(struct xdr_stream
*xdr
,
381 struct nfs42_copy_res
*res
) {
384 p
= xdr_inline_decode(xdr
, 4 + 4);
388 res
->consecutive
= be32_to_cpup(p
++);
389 res
->synchronous
= be32_to_cpup(p
++);
392 print_overflow_msg(__func__
, xdr
);
396 static int decode_copy(struct xdr_stream
*xdr
, struct nfs42_copy_res
*res
)
400 status
= decode_op_hdr(xdr
, OP_COPY
);
401 if (status
== NFS4ERR_OFFLOAD_NO_REQS
) {
402 status
= decode_copy_requirements(xdr
, res
);
405 return NFS4ERR_OFFLOAD_NO_REQS
;
409 status
= decode_write_response(xdr
, &res
->write_res
);
413 return decode_copy_requirements(xdr
, res
);
416 static int decode_deallocate(struct xdr_stream
*xdr
, struct nfs42_falloc_res
*res
)
418 return decode_op_hdr(xdr
, OP_DEALLOCATE
);
421 static int decode_seek(struct xdr_stream
*xdr
, struct nfs42_seek_res
*res
)
426 status
= decode_op_hdr(xdr
, OP_SEEK
);
430 p
= xdr_inline_decode(xdr
, 4 + 8);
434 res
->sr_eof
= be32_to_cpup(p
++);
435 p
= xdr_decode_hyper(p
, &res
->sr_offset
);
439 print_overflow_msg(__func__
, xdr
);
443 static int decode_layoutstats(struct xdr_stream
*xdr
)
445 return decode_op_hdr(xdr
, OP_LAYOUTSTATS
);
448 static int decode_clone(struct xdr_stream
*xdr
)
450 return decode_op_hdr(xdr
, OP_CLONE
);
454 * Decode ALLOCATE request
456 static int nfs4_xdr_dec_allocate(struct rpc_rqst
*rqstp
,
457 struct xdr_stream
*xdr
,
460 struct nfs42_falloc_res
*res
= data
;
461 struct compound_hdr hdr
;
464 status
= decode_compound_hdr(xdr
, &hdr
);
467 status
= decode_sequence(xdr
, &res
->seq_res
, rqstp
);
470 status
= decode_putfh(xdr
);
473 status
= decode_allocate(xdr
, res
);
476 decode_getfattr(xdr
, res
->falloc_fattr
, res
->falloc_server
);
482 * Decode COPY response
484 static int nfs4_xdr_dec_copy(struct rpc_rqst
*rqstp
,
485 struct xdr_stream
*xdr
,
488 struct nfs42_copy_res
*res
= data
;
489 struct compound_hdr hdr
;
492 status
= decode_compound_hdr(xdr
, &hdr
);
495 status
= decode_sequence(xdr
, &res
->seq_res
, rqstp
);
498 status
= decode_putfh(xdr
);
501 status
= decode_savefh(xdr
);
504 status
= decode_putfh(xdr
);
507 status
= decode_copy(xdr
, res
);
510 status
= decode_commit(xdr
, &res
->commit_res
);
516 * Decode DEALLOCATE request
518 static int nfs4_xdr_dec_deallocate(struct rpc_rqst
*rqstp
,
519 struct xdr_stream
*xdr
,
522 struct nfs42_falloc_res
*res
= data
;
523 struct compound_hdr hdr
;
526 status
= decode_compound_hdr(xdr
, &hdr
);
529 status
= decode_sequence(xdr
, &res
->seq_res
, rqstp
);
532 status
= decode_putfh(xdr
);
535 status
= decode_deallocate(xdr
, res
);
538 decode_getfattr(xdr
, res
->falloc_fattr
, res
->falloc_server
);
544 * Decode SEEK request
546 static int nfs4_xdr_dec_seek(struct rpc_rqst
*rqstp
,
547 struct xdr_stream
*xdr
,
550 struct nfs42_seek_res
*res
= data
;
551 struct compound_hdr hdr
;
554 status
= decode_compound_hdr(xdr
, &hdr
);
557 status
= decode_sequence(xdr
, &res
->seq_res
, rqstp
);
560 status
= decode_putfh(xdr
);
563 status
= decode_seek(xdr
, res
);
569 * Decode LAYOUTSTATS request
571 static int nfs4_xdr_dec_layoutstats(struct rpc_rqst
*rqstp
,
572 struct xdr_stream
*xdr
,
575 struct nfs42_layoutstat_res
*res
= data
;
576 struct compound_hdr hdr
;
579 status
= decode_compound_hdr(xdr
, &hdr
);
582 status
= decode_sequence(xdr
, &res
->seq_res
, rqstp
);
585 status
= decode_putfh(xdr
);
588 WARN_ON(res
->num_dev
> PNFS_LAYOUTSTATS_MAXDEV
);
589 for (i
= 0; i
< res
->num_dev
; i
++) {
590 status
= decode_layoutstats(xdr
);
595 res
->rpc_status
= status
;
600 * Decode CLONE request
602 static int nfs4_xdr_dec_clone(struct rpc_rqst
*rqstp
,
603 struct xdr_stream
*xdr
,
606 struct nfs42_clone_res
*res
= data
;
607 struct compound_hdr hdr
;
610 status
= decode_compound_hdr(xdr
, &hdr
);
613 status
= decode_sequence(xdr
, &res
->seq_res
, rqstp
);
616 status
= decode_putfh(xdr
);
619 status
= decode_savefh(xdr
);
622 status
= decode_putfh(xdr
);
625 status
= decode_clone(xdr
);
628 status
= decode_getfattr(xdr
, res
->dst_fattr
, res
->server
);
631 res
->rpc_status
= status
;
635 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */