2 * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>
4 #ifndef __LINUX_FS_NFS_NFS4_2XDR_H
5 #define __LINUX_FS_NFS_NFS4_2XDR_H
9 #define encode_fallocate_maxsz (encode_stateid_maxsz + \
12 #define NFS42_WRITE_RES_SIZE (1 /* wr_callback_id size */ +\
13 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
15 1 /* wr_committed */ + \
16 XDR_QUADLEN(NFS4_VERIFIER_SIZE))
17 #define encode_allocate_maxsz (op_encode_hdr_maxsz + \
18 encode_fallocate_maxsz)
19 #define decode_allocate_maxsz (op_decode_hdr_maxsz)
20 #define encode_copy_maxsz (op_encode_hdr_maxsz + \
21 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
22 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
23 2 + 2 + 2 + 1 + 1 + 1)
24 #define decode_copy_maxsz (op_decode_hdr_maxsz + \
25 NFS42_WRITE_RES_SIZE + \
26 1 /* cr_consecutive */ + \
27 1 /* cr_synchronous */)
28 #define encode_deallocate_maxsz (op_encode_hdr_maxsz + \
29 encode_fallocate_maxsz)
30 #define decode_deallocate_maxsz (op_decode_hdr_maxsz)
31 #define encode_seek_maxsz (op_encode_hdr_maxsz + \
32 encode_stateid_maxsz + \
35 #define decode_seek_maxsz (op_decode_hdr_maxsz + \
40 #define encode_io_info_maxsz 4
41 #define encode_layoutstats_maxsz (op_decode_hdr_maxsz + \
44 encode_stateid_maxsz + \
45 encode_io_info_maxsz + \
46 encode_io_info_maxsz + \
47 1 /* opaque devaddr4 length */ + \
48 XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE))
49 #define decode_layoutstats_maxsz (op_decode_hdr_maxsz)
50 #define encode_clone_maxsz (encode_stateid_maxsz + \
51 encode_stateid_maxsz + \
52 2 /* src offset */ + \
53 2 /* dst offset */ + \
55 #define decode_clone_maxsz (op_decode_hdr_maxsz)
57 #define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \
58 encode_putfh_maxsz + \
59 encode_allocate_maxsz + \
61 #define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \
62 decode_putfh_maxsz + \
63 decode_allocate_maxsz + \
65 #define NFS4_enc_copy_sz (compound_encode_hdr_maxsz + \
66 encode_putfh_maxsz + \
67 encode_savefh_maxsz + \
68 encode_putfh_maxsz + \
71 #define NFS4_dec_copy_sz (compound_decode_hdr_maxsz + \
72 decode_putfh_maxsz + \
73 decode_savefh_maxsz + \
74 decode_putfh_maxsz + \
77 #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \
78 encode_putfh_maxsz + \
79 encode_deallocate_maxsz + \
81 #define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \
82 decode_putfh_maxsz + \
83 decode_deallocate_maxsz + \
85 #define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \
86 encode_putfh_maxsz + \
88 #define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \
89 decode_putfh_maxsz + \
91 #define NFS4_enc_layoutstats_sz (compound_encode_hdr_maxsz + \
92 encode_sequence_maxsz + \
93 encode_putfh_maxsz + \
94 PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz)
95 #define NFS4_dec_layoutstats_sz (compound_decode_hdr_maxsz + \
96 decode_sequence_maxsz + \
97 decode_putfh_maxsz + \
98 PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz)
99 #define NFS4_enc_clone_sz (compound_encode_hdr_maxsz + \
100 encode_sequence_maxsz + \
101 encode_putfh_maxsz + \
102 encode_savefh_maxsz + \
103 encode_putfh_maxsz + \
104 encode_clone_maxsz + \
105 encode_getattr_maxsz)
106 #define NFS4_dec_clone_sz (compound_decode_hdr_maxsz + \
107 decode_sequence_maxsz + \
108 decode_putfh_maxsz + \
109 decode_savefh_maxsz + \
110 decode_putfh_maxsz + \
111 decode_clone_maxsz + \
112 decode_getattr_maxsz)
114 static void encode_fallocate(struct xdr_stream *xdr,
115 struct nfs42_falloc_args *args)
117 encode_nfs4_stateid(xdr, &args->falloc_stateid);
118 encode_uint64(xdr, args->falloc_offset);
119 encode_uint64(xdr, args->falloc_length);
122 static void encode_allocate(struct xdr_stream *xdr,
123 struct nfs42_falloc_args *args,
124 struct compound_hdr *hdr)
126 encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
127 encode_fallocate(xdr, args);
130 static void encode_copy(struct xdr_stream *xdr,
131 struct nfs42_copy_args *args,
132 struct compound_hdr *hdr)
134 encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr);
135 encode_nfs4_stateid(xdr, &args->src_stateid);
136 encode_nfs4_stateid(xdr, &args->dst_stateid);
138 encode_uint64(xdr, args->src_pos);
139 encode_uint64(xdr, args->dst_pos);
140 encode_uint64(xdr, args->count);
142 encode_uint32(xdr, 1); /* consecutive = true */
143 encode_uint32(xdr, 1); /* synchronous = true */
144 encode_uint32(xdr, 0); /* src server list */
147 static void encode_deallocate(struct xdr_stream *xdr,
148 struct nfs42_falloc_args *args,
149 struct compound_hdr *hdr)
151 encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
152 encode_fallocate(xdr, args);
155 static void encode_seek(struct xdr_stream *xdr,
156 struct nfs42_seek_args *args,
157 struct compound_hdr *hdr)
159 encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr);
160 encode_nfs4_stateid(xdr, &args->sa_stateid);
161 encode_uint64(xdr, args->sa_offset);
162 encode_uint32(xdr, args->sa_what);
165 static void encode_layoutstats(struct xdr_stream *xdr,
166 struct nfs42_layoutstat_args *args,
167 struct nfs42_layoutstat_devinfo *devinfo,
168 struct compound_hdr *hdr)
172 encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr);
173 p = reserve_space(xdr, 8 + 8);
174 p = xdr_encode_hyper(p, devinfo->offset);
175 p = xdr_encode_hyper(p, devinfo->length);
176 encode_nfs4_stateid(xdr, &args->stateid);
177 p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4);
178 p = xdr_encode_hyper(p, devinfo->read_count);
179 p = xdr_encode_hyper(p, devinfo->read_bytes);
180 p = xdr_encode_hyper(p, devinfo->write_count);
181 p = xdr_encode_hyper(p, devinfo->write_bytes);
182 p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data,
183 NFS4_DEVICEID4_SIZE);
184 /* Encode layoutupdate4 */
185 *p++ = cpu_to_be32(devinfo->layout_type);
186 if (devinfo->ld_private.ops)
187 devinfo->ld_private.ops->encode(xdr, args,
188 &devinfo->ld_private);
190 encode_uint32(xdr, 0);
193 static void encode_clone(struct xdr_stream *xdr,
194 struct nfs42_clone_args *args,
195 struct compound_hdr *hdr)
199 encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr);
200 encode_nfs4_stateid(xdr, &args->src_stateid);
201 encode_nfs4_stateid(xdr, &args->dst_stateid);
202 p = reserve_space(xdr, 3*8);
203 p = xdr_encode_hyper(p, args->src_offset);
204 p = xdr_encode_hyper(p, args->dst_offset);
205 xdr_encode_hyper(p, args->count);
209 * Encode ALLOCATE request
211 static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
212 struct xdr_stream *xdr,
213 struct nfs42_falloc_args *args)
215 struct compound_hdr hdr = {
216 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
219 encode_compound_hdr(xdr, req, &hdr);
220 encode_sequence(xdr, &args->seq_args, &hdr);
221 encode_putfh(xdr, args->falloc_fh, &hdr);
222 encode_allocate(xdr, args, &hdr);
223 encode_getfattr(xdr, args->falloc_bitmask, &hdr);
227 static void encode_copy_commit(struct xdr_stream *xdr,
228 struct nfs42_copy_args *args,
229 struct compound_hdr *hdr)
233 encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr);
234 p = reserve_space(xdr, 12);
235 p = xdr_encode_hyper(p, args->dst_pos);
236 *p = cpu_to_be32(args->count);
240 * Encode COPY request
242 static void nfs4_xdr_enc_copy(struct rpc_rqst *req,
243 struct xdr_stream *xdr,
244 struct nfs42_copy_args *args)
246 struct compound_hdr hdr = {
247 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
250 encode_compound_hdr(xdr, req, &hdr);
251 encode_sequence(xdr, &args->seq_args, &hdr);
252 encode_putfh(xdr, args->src_fh, &hdr);
253 encode_savefh(xdr, &hdr);
254 encode_putfh(xdr, args->dst_fh, &hdr);
255 encode_copy(xdr, args, &hdr);
256 encode_copy_commit(xdr, args, &hdr);
261 * Encode DEALLOCATE request
263 static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
264 struct xdr_stream *xdr,
265 struct nfs42_falloc_args *args)
267 struct compound_hdr hdr = {
268 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
271 encode_compound_hdr(xdr, req, &hdr);
272 encode_sequence(xdr, &args->seq_args, &hdr);
273 encode_putfh(xdr, args->falloc_fh, &hdr);
274 encode_deallocate(xdr, args, &hdr);
275 encode_getfattr(xdr, args->falloc_bitmask, &hdr);
280 * Encode SEEK request
282 static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
283 struct xdr_stream *xdr,
284 struct nfs42_seek_args *args)
286 struct compound_hdr hdr = {
287 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
290 encode_compound_hdr(xdr, req, &hdr);
291 encode_sequence(xdr, &args->seq_args, &hdr);
292 encode_putfh(xdr, args->sa_fh, &hdr);
293 encode_seek(xdr, args, &hdr);
298 * Encode LAYOUTSTATS request
300 static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req,
301 struct xdr_stream *xdr,
302 struct nfs42_layoutstat_args *args)
306 struct compound_hdr hdr = {
307 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
310 encode_compound_hdr(xdr, req, &hdr);
311 encode_sequence(xdr, &args->seq_args, &hdr);
312 encode_putfh(xdr, args->fh, &hdr);
313 WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
314 for (i = 0; i < args->num_dev; i++)
315 encode_layoutstats(xdr, args, &args->devinfo[i], &hdr);
320 * Encode CLONE request
322 static void nfs4_xdr_enc_clone(struct rpc_rqst *req,
323 struct xdr_stream *xdr,
324 struct nfs42_clone_args *args)
326 struct compound_hdr hdr = {
327 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
330 encode_compound_hdr(xdr, req, &hdr);
331 encode_sequence(xdr, &args->seq_args, &hdr);
332 encode_putfh(xdr, args->src_fh, &hdr);
333 encode_savefh(xdr, &hdr);
334 encode_putfh(xdr, args->dst_fh, &hdr);
335 encode_clone(xdr, args, &hdr);
336 encode_getfattr(xdr, args->dst_bitmask, &hdr);
340 static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
342 return decode_op_hdr(xdr, OP_ALLOCATE);
345 static int decode_write_response(struct xdr_stream *xdr,
346 struct nfs42_write_res *res)
350 p = xdr_inline_decode(xdr, 4 + 8 + 4);
355 * We never use asynchronous mode, so warn if a server returns
358 if (unlikely(*p != 0)) {
359 pr_err_once("%s: server has set unrequested "
360 "asynchronous mode\n", __func__);
364 p = xdr_decode_hyper(p, &res->count);
365 res->verifier.committed = be32_to_cpup(p);
366 return decode_verifier(xdr, &res->verifier.verifier);
369 print_overflow_msg(__func__, xdr);
373 static int decode_copy_requirements(struct xdr_stream *xdr,
374 struct nfs42_copy_res *res) {
377 p = xdr_inline_decode(xdr, 4 + 4);
381 res->consecutive = be32_to_cpup(p++);
382 res->synchronous = be32_to_cpup(p++);
385 print_overflow_msg(__func__, xdr);
389 static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res)
393 status = decode_op_hdr(xdr, OP_COPY);
394 if (status == NFS4ERR_OFFLOAD_NO_REQS) {
395 status = decode_copy_requirements(xdr, res);
398 return NFS4ERR_OFFLOAD_NO_REQS;
402 status = decode_write_response(xdr, &res->write_res);
406 return decode_copy_requirements(xdr, res);
409 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
411 return decode_op_hdr(xdr, OP_DEALLOCATE);
414 static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
419 status = decode_op_hdr(xdr, OP_SEEK);
423 p = xdr_inline_decode(xdr, 4 + 8);
427 res->sr_eof = be32_to_cpup(p++);
428 p = xdr_decode_hyper(p, &res->sr_offset);
432 print_overflow_msg(__func__, xdr);
436 static int decode_layoutstats(struct xdr_stream *xdr)
438 return decode_op_hdr(xdr, OP_LAYOUTSTATS);
441 static int decode_clone(struct xdr_stream *xdr)
443 return decode_op_hdr(xdr, OP_CLONE);
447 * Decode ALLOCATE request
449 static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
450 struct xdr_stream *xdr,
451 struct nfs42_falloc_res *res)
453 struct compound_hdr hdr;
456 status = decode_compound_hdr(xdr, &hdr);
459 status = decode_sequence(xdr, &res->seq_res, rqstp);
462 status = decode_putfh(xdr);
465 status = decode_allocate(xdr, res);
468 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
474 * Decode COPY response
476 static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp,
477 struct xdr_stream *xdr,
478 struct nfs42_copy_res *res)
480 struct compound_hdr hdr;
483 status = decode_compound_hdr(xdr, &hdr);
486 status = decode_sequence(xdr, &res->seq_res, rqstp);
489 status = decode_putfh(xdr);
492 status = decode_savefh(xdr);
495 status = decode_putfh(xdr);
498 status = decode_copy(xdr, res);
501 status = decode_commit(xdr, &res->commit_res);
507 * Decode DEALLOCATE request
509 static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
510 struct xdr_stream *xdr,
511 struct nfs42_falloc_res *res)
513 struct compound_hdr hdr;
516 status = decode_compound_hdr(xdr, &hdr);
519 status = decode_sequence(xdr, &res->seq_res, rqstp);
522 status = decode_putfh(xdr);
525 status = decode_deallocate(xdr, res);
528 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
534 * Decode SEEK request
536 static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
537 struct xdr_stream *xdr,
538 struct nfs42_seek_res *res)
540 struct compound_hdr hdr;
543 status = decode_compound_hdr(xdr, &hdr);
546 status = decode_sequence(xdr, &res->seq_res, rqstp);
549 status = decode_putfh(xdr);
552 status = decode_seek(xdr, res);
558 * Decode LAYOUTSTATS request
560 static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp,
561 struct xdr_stream *xdr,
562 struct nfs42_layoutstat_res *res)
564 struct compound_hdr hdr;
567 status = decode_compound_hdr(xdr, &hdr);
570 status = decode_sequence(xdr, &res->seq_res, rqstp);
573 status = decode_putfh(xdr);
576 WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
577 for (i = 0; i < res->num_dev; i++) {
578 status = decode_layoutstats(xdr);
583 res->rpc_status = status;
588 * Decode CLONE request
590 static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp,
591 struct xdr_stream *xdr,
592 struct nfs42_clone_res *res)
594 struct compound_hdr hdr;
597 status = decode_compound_hdr(xdr, &hdr);
600 status = decode_sequence(xdr, &res->seq_res, rqstp);
603 status = decode_putfh(xdr);
606 status = decode_savefh(xdr);
609 status = decode_putfh(xdr);
612 status = decode_clone(xdr);
615 status = decode_getfattr(xdr, res->dst_fattr, res->server);
618 res->rpc_status = status;
622 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */