Merge tag 'mips_5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
[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) + \
1d38f3f0
OK
24 2 + 2 + 2 + 1 + 1 + 1 +\
25 1 + /* One cnr_source_server */\
26 1 + /* nl4_type */ \
27 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
2e72448b
AS
28#define decode_copy_maxsz (op_decode_hdr_maxsz + \
29 NFS42_WRITE_RES_SIZE + \
30 1 /* cr_consecutive */ + \
31 1 /* cr_synchronous */)
cb95deea
OK
32#define encode_offload_cancel_maxsz (op_encode_hdr_maxsz + \
33 XDR_QUADLEN(NFS4_STATEID_SIZE))
34#define decode_offload_cancel_maxsz (op_decode_hdr_maxsz)
0491567b
OK
35#define encode_copy_notify_maxsz (op_encode_hdr_maxsz + \
36 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
37 1 + /* nl4_type */ \
38 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
39#define decode_copy_notify_maxsz (op_decode_hdr_maxsz + \
40 3 + /* cnr_lease_time */\
41 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
42 1 + /* Support 1 cnr_source_server */\
43 1 + /* nl4_type */ \
44 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
624bd5b7
AS
45#define encode_deallocate_maxsz (op_encode_hdr_maxsz + \
46 encode_fallocate_maxsz)
47#define decode_deallocate_maxsz (op_decode_hdr_maxsz)
1c6dcbe5
AS
48#define encode_seek_maxsz (op_encode_hdr_maxsz + \
49 encode_stateid_maxsz + \
50 2 /* offset */ + \
51 1 /* whence */)
52#define decode_seek_maxsz (op_decode_hdr_maxsz + \
53 1 /* eof */ + \
54 1 /* whence */ + \
55 2 /* offset */ + \
56 2 /* length */)
be3a5d23
TM
57#define encode_io_info_maxsz 4
58#define encode_layoutstats_maxsz (op_decode_hdr_maxsz + \
59 2 /* offset */ + \
60 2 /* length */ + \
61 encode_stateid_maxsz + \
62 encode_io_info_maxsz + \
63 encode_io_info_maxsz + \
64 1 /* opaque devaddr4 length */ + \
65 XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE))
66#define decode_layoutstats_maxsz (op_decode_hdr_maxsz)
3eb86093
TM
67#define encode_device_error_maxsz (XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \
68 1 /* status */ + 1 /* opnum */)
69#define encode_layouterror_maxsz (op_decode_hdr_maxsz + \
70 2 /* offset */ + \
71 2 /* length */ + \
72 encode_stateid_maxsz + \
73 1 /* Array size */ + \
74 encode_device_error_maxsz)
75#define decode_layouterror_maxsz (op_decode_hdr_maxsz)
36022770
PT
76#define encode_clone_maxsz (encode_stateid_maxsz + \
77 encode_stateid_maxsz + \
78 2 /* src offset */ + \
79 2 /* dst offset */ + \
80 2 /* count */)
81#define decode_clone_maxsz (op_decode_hdr_maxsz)
1c6dcbe5 82
f4ac1674 83#define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \
1a3466ae 84 encode_sequence_maxsz + \
f4ac1674 85 encode_putfh_maxsz + \
9a51940b
AS
86 encode_allocate_maxsz + \
87 encode_getattr_maxsz)
f4ac1674 88#define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \
1a3466ae 89 decode_sequence_maxsz + \
f4ac1674 90 decode_putfh_maxsz + \
9a51940b
AS
91 decode_allocate_maxsz + \
92 decode_getattr_maxsz)
2e72448b 93#define NFS4_enc_copy_sz (compound_encode_hdr_maxsz + \
1a3466ae 94 encode_sequence_maxsz + \
2e72448b
AS
95 encode_putfh_maxsz + \
96 encode_savefh_maxsz + \
97 encode_putfh_maxsz + \
e0926934
OK
98 encode_copy_maxsz + \
99 encode_commit_maxsz)
2e72448b 100#define NFS4_dec_copy_sz (compound_decode_hdr_maxsz + \
1a3466ae 101 decode_sequence_maxsz + \
2e72448b
AS
102 decode_putfh_maxsz + \
103 decode_savefh_maxsz + \
104 decode_putfh_maxsz + \
e0926934
OK
105 decode_copy_maxsz + \
106 decode_commit_maxsz)
cb95deea 107#define NFS4_enc_offload_cancel_sz (compound_encode_hdr_maxsz + \
1a3466ae 108 encode_sequence_maxsz + \
cb95deea
OK
109 encode_putfh_maxsz + \
110 encode_offload_cancel_maxsz)
111#define NFS4_dec_offload_cancel_sz (compound_decode_hdr_maxsz + \
1a3466ae 112 decode_sequence_maxsz + \
cb95deea
OK
113 decode_putfh_maxsz + \
114 decode_offload_cancel_maxsz)
0491567b
OK
115#define NFS4_enc_copy_notify_sz (compound_encode_hdr_maxsz + \
116 encode_putfh_maxsz + \
117 encode_copy_notify_maxsz)
118#define NFS4_dec_copy_notify_sz (compound_decode_hdr_maxsz + \
119 decode_putfh_maxsz + \
120 decode_copy_notify_maxsz)
624bd5b7 121#define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \
1a3466ae 122 encode_sequence_maxsz + \
624bd5b7 123 encode_putfh_maxsz + \
9a51940b
AS
124 encode_deallocate_maxsz + \
125 encode_getattr_maxsz)
624bd5b7 126#define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \
1a3466ae 127 decode_sequence_maxsz + \
624bd5b7 128 decode_putfh_maxsz + \
9a51940b
AS
129 decode_deallocate_maxsz + \
130 decode_getattr_maxsz)
1c6dcbe5 131#define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \
1a3466ae 132 encode_sequence_maxsz + \
1c6dcbe5
AS
133 encode_putfh_maxsz + \
134 encode_seek_maxsz)
135#define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \
1a3466ae 136 decode_sequence_maxsz + \
1c6dcbe5
AS
137 decode_putfh_maxsz + \
138 decode_seek_maxsz)
be3a5d23
TM
139#define NFS4_enc_layoutstats_sz (compound_encode_hdr_maxsz + \
140 encode_sequence_maxsz + \
141 encode_putfh_maxsz + \
142 PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz)
143#define NFS4_dec_layoutstats_sz (compound_decode_hdr_maxsz + \
144 decode_sequence_maxsz + \
145 decode_putfh_maxsz + \
146 PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz)
3eb86093
TM
147#define NFS4_enc_layouterror_sz (compound_encode_hdr_maxsz + \
148 encode_sequence_maxsz + \
149 encode_putfh_maxsz + \
150 NFS42_LAYOUTERROR_MAX * \
151 encode_layouterror_maxsz)
152#define NFS4_dec_layouterror_sz (compound_decode_hdr_maxsz + \
153 decode_sequence_maxsz + \
154 decode_putfh_maxsz + \
155 NFS42_LAYOUTERROR_MAX * \
156 decode_layouterror_maxsz)
36022770
PT
157#define NFS4_enc_clone_sz (compound_encode_hdr_maxsz + \
158 encode_sequence_maxsz + \
159 encode_putfh_maxsz + \
160 encode_savefh_maxsz + \
161 encode_putfh_maxsz + \
162 encode_clone_maxsz + \
163 encode_getattr_maxsz)
164#define NFS4_dec_clone_sz (compound_decode_hdr_maxsz + \
165 decode_sequence_maxsz + \
166 decode_putfh_maxsz + \
167 decode_savefh_maxsz + \
168 decode_putfh_maxsz + \
169 decode_clone_maxsz + \
170 decode_getattr_maxsz)
1c6dcbe5 171
f4ac1674 172static void encode_fallocate(struct xdr_stream *xdr,
0096d39b 173 const struct nfs42_falloc_args *args)
f4ac1674
AS
174{
175 encode_nfs4_stateid(xdr, &args->falloc_stateid);
176 encode_uint64(xdr, args->falloc_offset);
177 encode_uint64(xdr, args->falloc_length);
178}
179
180static void encode_allocate(struct xdr_stream *xdr,
0096d39b 181 const struct nfs42_falloc_args *args,
f4ac1674
AS
182 struct compound_hdr *hdr)
183{
184 encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
185 encode_fallocate(xdr, args);
186}
187
0491567b
OK
188static void encode_nl4_server(struct xdr_stream *xdr,
189 const struct nl4_server *ns)
190{
191 encode_uint32(xdr, ns->nl4_type);
192 switch (ns->nl4_type) {
193 case NL4_NAME:
194 case NL4_URL:
195 encode_string(xdr, ns->u.nl4_str_sz, ns->u.nl4_str);
196 break;
197 case NL4_NETADDR:
198 encode_string(xdr, ns->u.nl4_addr.netid_len,
199 ns->u.nl4_addr.netid);
200 encode_string(xdr, ns->u.nl4_addr.addr_len,
201 ns->u.nl4_addr.addr);
202 break;
203 default:
204 WARN_ON_ONCE(1);
205 }
206}
207
2e72448b 208static void encode_copy(struct xdr_stream *xdr,
0096d39b 209 const struct nfs42_copy_args *args,
2e72448b
AS
210 struct compound_hdr *hdr)
211{
212 encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr);
213 encode_nfs4_stateid(xdr, &args->src_stateid);
214 encode_nfs4_stateid(xdr, &args->dst_stateid);
215
216 encode_uint64(xdr, args->src_pos);
217 encode_uint64(xdr, args->dst_pos);
218 encode_uint64(xdr, args->count);
219
220 encode_uint32(xdr, 1); /* consecutive = true */
62164f31 221 encode_uint32(xdr, args->sync);
1d38f3f0
OK
222 if (args->cp_src == NULL) { /* intra-ssc */
223 encode_uint32(xdr, 0); /* no src server list */
224 return;
225 }
226 encode_uint32(xdr, 1); /* supporting 1 server */
227 encode_nl4_server(xdr, args->cp_src);
2e72448b
AS
228}
229
cb95deea
OK
230static void encode_offload_cancel(struct xdr_stream *xdr,
231 const struct nfs42_offload_status_args *args,
232 struct compound_hdr *hdr)
233{
234 encode_op_hdr(xdr, OP_OFFLOAD_CANCEL, decode_offload_cancel_maxsz, hdr);
235 encode_nfs4_stateid(xdr, &args->osa_stateid);
236}
237
0491567b
OK
238static void encode_copy_notify(struct xdr_stream *xdr,
239 const struct nfs42_copy_notify_args *args,
240 struct compound_hdr *hdr)
241{
242 encode_op_hdr(xdr, OP_COPY_NOTIFY, decode_copy_notify_maxsz, hdr);
243 encode_nfs4_stateid(xdr, &args->cna_src_stateid);
244 encode_nl4_server(xdr, &args->cna_dst);
245}
246
624bd5b7 247static void encode_deallocate(struct xdr_stream *xdr,
0096d39b 248 const struct nfs42_falloc_args *args,
624bd5b7
AS
249 struct compound_hdr *hdr)
250{
251 encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
252 encode_fallocate(xdr, args);
253}
254
1c6dcbe5 255static void encode_seek(struct xdr_stream *xdr,
0096d39b 256 const struct nfs42_seek_args *args,
1c6dcbe5
AS
257 struct compound_hdr *hdr)
258{
259 encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr);
260 encode_nfs4_stateid(xdr, &args->sa_stateid);
261 encode_uint64(xdr, args->sa_offset);
262 encode_uint32(xdr, args->sa_what);
263}
264
be3a5d23 265static void encode_layoutstats(struct xdr_stream *xdr,
0096d39b 266 const struct nfs42_layoutstat_args *args,
be3a5d23
TM
267 struct nfs42_layoutstat_devinfo *devinfo,
268 struct compound_hdr *hdr)
269{
270 __be32 *p;
271
272 encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr);
273 p = reserve_space(xdr, 8 + 8);
274 p = xdr_encode_hyper(p, devinfo->offset);
275 p = xdr_encode_hyper(p, devinfo->length);
276 encode_nfs4_stateid(xdr, &args->stateid);
277 p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4);
278 p = xdr_encode_hyper(p, devinfo->read_count);
279 p = xdr_encode_hyper(p, devinfo->read_bytes);
280 p = xdr_encode_hyper(p, devinfo->write_count);
281 p = xdr_encode_hyper(p, devinfo->write_bytes);
282 p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data,
283 NFS4_DEVICEID4_SIZE);
284 /* Encode layoutupdate4 */
285 *p++ = cpu_to_be32(devinfo->layout_type);
422c93c8
TM
286 if (devinfo->ld_private.ops)
287 devinfo->ld_private.ops->encode(xdr, args,
288 &devinfo->ld_private);
be3a5d23
TM
289 else
290 encode_uint32(xdr, 0);
291}
292
36022770 293static void encode_clone(struct xdr_stream *xdr,
0096d39b 294 const struct nfs42_clone_args *args,
36022770
PT
295 struct compound_hdr *hdr)
296{
297 __be32 *p;
298
299 encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr);
300 encode_nfs4_stateid(xdr, &args->src_stateid);
301 encode_nfs4_stateid(xdr, &args->dst_stateid);
302 p = reserve_space(xdr, 3*8);
303 p = xdr_encode_hyper(p, args->src_offset);
304 p = xdr_encode_hyper(p, args->dst_offset);
305 xdr_encode_hyper(p, args->count);
306}
307
3eb86093
TM
308static void encode_device_error(struct xdr_stream *xdr,
309 const struct nfs42_device_error *error)
310{
311 __be32 *p;
312
313 p = reserve_space(xdr, NFS4_DEVICEID4_SIZE + 2*4);
314 p = xdr_encode_opaque_fixed(p, error->dev_id.data,
315 NFS4_DEVICEID4_SIZE);
316 *p++ = cpu_to_be32(error->status);
317 *p = cpu_to_be32(error->opnum);
318}
319
320static void encode_layouterror(struct xdr_stream *xdr,
321 const struct nfs42_layout_error *args,
322 struct compound_hdr *hdr)
323{
324 __be32 *p;
325
326 encode_op_hdr(xdr, OP_LAYOUTERROR, decode_layouterror_maxsz, hdr);
327 p = reserve_space(xdr, 8 + 8);
328 p = xdr_encode_hyper(p, args->offset);
329 p = xdr_encode_hyper(p, args->length);
330 encode_nfs4_stateid(xdr, &args->stateid);
331 p = reserve_space(xdr, 4);
332 *p = cpu_to_be32(1);
333 encode_device_error(xdr, &args->errors[0]);
334}
335
f4ac1674
AS
336/*
337 * Encode ALLOCATE request
338 */
339static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
340 struct xdr_stream *xdr,
0096d39b 341 const void *data)
f4ac1674 342{
0096d39b 343 const struct nfs42_falloc_args *args = data;
f4ac1674
AS
344 struct compound_hdr hdr = {
345 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
346 };
347
348 encode_compound_hdr(xdr, req, &hdr);
349 encode_sequence(xdr, &args->seq_args, &hdr);
350 encode_putfh(xdr, args->falloc_fh, &hdr);
351 encode_allocate(xdr, args, &hdr);
9a51940b 352 encode_getfattr(xdr, args->falloc_bitmask, &hdr);
f4ac1674
AS
353 encode_nops(&hdr);
354}
355
e0926934 356static void encode_copy_commit(struct xdr_stream *xdr,
0096d39b 357 const struct nfs42_copy_args *args,
e0926934
OK
358 struct compound_hdr *hdr)
359{
360 __be32 *p;
361
362 encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr);
363 p = reserve_space(xdr, 12);
364 p = xdr_encode_hyper(p, args->dst_pos);
365 *p = cpu_to_be32(args->count);
366}
367
2e72448b
AS
368/*
369 * Encode COPY request
370 */
371static void nfs4_xdr_enc_copy(struct rpc_rqst *req,
372 struct xdr_stream *xdr,
0096d39b 373 const void *data)
2e72448b 374{
0096d39b 375 const struct nfs42_copy_args *args = data;
2e72448b
AS
376 struct compound_hdr hdr = {
377 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
378 };
379
380 encode_compound_hdr(xdr, req, &hdr);
381 encode_sequence(xdr, &args->seq_args, &hdr);
382 encode_putfh(xdr, args->src_fh, &hdr);
383 encode_savefh(xdr, &hdr);
384 encode_putfh(xdr, args->dst_fh, &hdr);
385 encode_copy(xdr, args, &hdr);
62164f31
OK
386 if (args->sync)
387 encode_copy_commit(xdr, args, &hdr);
2e72448b
AS
388 encode_nops(&hdr);
389}
390
cb95deea
OK
391/*
392 * Encode OFFLOAD_CANEL request
393 */
394static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req,
395 struct xdr_stream *xdr,
396 const void *data)
397{
398 const struct nfs42_offload_status_args *args = data;
399 struct compound_hdr hdr = {
400 .minorversion = nfs4_xdr_minorversion(&args->osa_seq_args),
401 };
402
403 encode_compound_hdr(xdr, req, &hdr);
404 encode_sequence(xdr, &args->osa_seq_args, &hdr);
405 encode_putfh(xdr, args->osa_src_fh, &hdr);
406 encode_offload_cancel(xdr, args, &hdr);
407 encode_nops(&hdr);
408}
409
0491567b
OK
410/*
411 * Encode COPY_NOTIFY request
412 */
413static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req,
414 struct xdr_stream *xdr,
415 const void *data)
416{
417 const struct nfs42_copy_notify_args *args = data;
418 struct compound_hdr hdr = {
419 .minorversion = nfs4_xdr_minorversion(&args->cna_seq_args),
420 };
421
422 encode_compound_hdr(xdr, req, &hdr);
423 encode_sequence(xdr, &args->cna_seq_args, &hdr);
424 encode_putfh(xdr, args->cna_src_fh, &hdr);
425 encode_copy_notify(xdr, args, &hdr);
426 encode_nops(&hdr);
427}
428
624bd5b7
AS
429/*
430 * Encode DEALLOCATE request
431 */
432static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
433 struct xdr_stream *xdr,
0096d39b 434 const void *data)
624bd5b7 435{
0096d39b 436 const struct nfs42_falloc_args *args = data;
624bd5b7
AS
437 struct compound_hdr hdr = {
438 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
439 };
440
441 encode_compound_hdr(xdr, req, &hdr);
442 encode_sequence(xdr, &args->seq_args, &hdr);
443 encode_putfh(xdr, args->falloc_fh, &hdr);
444 encode_deallocate(xdr, args, &hdr);
9a51940b 445 encode_getfattr(xdr, args->falloc_bitmask, &hdr);
624bd5b7
AS
446 encode_nops(&hdr);
447}
448
1c6dcbe5
AS
449/*
450 * Encode SEEK request
451 */
452static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
453 struct xdr_stream *xdr,
0096d39b 454 const void *data)
1c6dcbe5 455{
0096d39b 456 const struct nfs42_seek_args *args = data;
1c6dcbe5
AS
457 struct compound_hdr hdr = {
458 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
459 };
460
461 encode_compound_hdr(xdr, req, &hdr);
462 encode_sequence(xdr, &args->seq_args, &hdr);
463 encode_putfh(xdr, args->sa_fh, &hdr);
464 encode_seek(xdr, args, &hdr);
465 encode_nops(&hdr);
466}
467
be3a5d23
TM
468/*
469 * Encode LAYOUTSTATS request
470 */
471static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req,
472 struct xdr_stream *xdr,
0096d39b 473 const void *data)
be3a5d23 474{
0096d39b 475 const struct nfs42_layoutstat_args *args = data;
be3a5d23
TM
476 int i;
477
478 struct compound_hdr hdr = {
479 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
480 };
481
482 encode_compound_hdr(xdr, req, &hdr);
483 encode_sequence(xdr, &args->seq_args, &hdr);
484 encode_putfh(xdr, args->fh, &hdr);
485 WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
486 for (i = 0; i < args->num_dev; i++)
487 encode_layoutstats(xdr, args, &args->devinfo[i], &hdr);
488 encode_nops(&hdr);
489}
490
36022770
PT
491/*
492 * Encode CLONE request
493 */
494static void nfs4_xdr_enc_clone(struct rpc_rqst *req,
495 struct xdr_stream *xdr,
0096d39b 496 const void *data)
36022770 497{
0096d39b 498 const struct nfs42_clone_args *args = data;
36022770
PT
499 struct compound_hdr hdr = {
500 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
501 };
502
503 encode_compound_hdr(xdr, req, &hdr);
504 encode_sequence(xdr, &args->seq_args, &hdr);
505 encode_putfh(xdr, args->src_fh, &hdr);
506 encode_savefh(xdr, &hdr);
507 encode_putfh(xdr, args->dst_fh, &hdr);
508 encode_clone(xdr, args, &hdr);
509 encode_getfattr(xdr, args->dst_bitmask, &hdr);
510 encode_nops(&hdr);
511}
512
3eb86093
TM
513/*
514 * Encode LAYOUTERROR request
515 */
516static void nfs4_xdr_enc_layouterror(struct rpc_rqst *req,
517 struct xdr_stream *xdr,
518 const void *data)
519{
520 const struct nfs42_layouterror_args *args = data;
521 struct compound_hdr hdr = {
522 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
523 };
524 int i;
525
526 encode_compound_hdr(xdr, req, &hdr);
527 encode_sequence(xdr, &args->seq_args, &hdr);
528 encode_putfh(xdr, NFS_FH(args->inode), &hdr);
529 for (i = 0; i < args->num_errors; i++)
530 encode_layouterror(xdr, &args->errors[i], &hdr);
531 encode_nops(&hdr);
532}
533
f4ac1674
AS
534static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
535{
536 return decode_op_hdr(xdr, OP_ALLOCATE);
537}
538
2e72448b
AS
539static int decode_write_response(struct xdr_stream *xdr,
540 struct nfs42_write_res *res)
541{
542 __be32 *p;
67aa7444 543 int status, count;
2e72448b 544
67aa7444 545 p = xdr_inline_decode(xdr, 4);
2e72448b 546 if (unlikely(!p))
eb72f484 547 return -EIO;
67aa7444
OK
548 count = be32_to_cpup(p);
549 if (count > 1)
6fdf339b 550 return -EREMOTEIO;
67aa7444
OK
551 else if (count == 1) {
552 status = decode_opaque_fixed(xdr, &res->stateid,
553 NFS4_STATEID_SIZE);
554 if (unlikely(status))
eb72f484 555 return -EIO;
6fdf339b 556 }
67aa7444
OK
557 p = xdr_inline_decode(xdr, 8 + 4);
558 if (unlikely(!p))
eb72f484 559 return -EIO;
2e72448b
AS
560 p = xdr_decode_hyper(p, &res->count);
561 res->verifier.committed = be32_to_cpup(p);
562 return decode_verifier(xdr, &res->verifier.verifier);
2e72448b
AS
563}
564
0491567b
OK
565static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns)
566{
567 struct nfs42_netaddr *naddr;
568 uint32_t dummy;
569 char *dummy_str;
570 __be32 *p;
571 int status;
572
573 /* nl_type */
574 p = xdr_inline_decode(xdr, 4);
575 if (unlikely(!p))
576 return -EIO;
577 ns->nl4_type = be32_to_cpup(p);
578 switch (ns->nl4_type) {
579 case NL4_NAME:
580 case NL4_URL:
581 status = decode_opaque_inline(xdr, &dummy, &dummy_str);
582 if (unlikely(status))
583 return status;
584 if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
585 return -EIO;
586 memcpy(&ns->u.nl4_str, dummy_str, dummy);
587 ns->u.nl4_str_sz = dummy;
588 break;
589 case NL4_NETADDR:
590 naddr = &ns->u.nl4_addr;
591
592 /* netid string */
593 status = decode_opaque_inline(xdr, &dummy, &dummy_str);
594 if (unlikely(status))
595 return status;
596 if (unlikely(dummy > RPCBIND_MAXNETIDLEN))
597 return -EIO;
598 naddr->netid_len = dummy;
599 memcpy(naddr->netid, dummy_str, naddr->netid_len);
600
601 /* uaddr string */
602 status = decode_opaque_inline(xdr, &dummy, &dummy_str);
603 if (unlikely(status))
604 return status;
605 if (unlikely(dummy > RPCBIND_MAXUADDRLEN))
606 return -EIO;
607 naddr->addr_len = dummy;
608 memcpy(naddr->addr, dummy_str, naddr->addr_len);
609 break;
610 default:
611 WARN_ON_ONCE(1);
612 return -EIO;
613 }
614 return 0;
615}
616
2e72448b
AS
617static int decode_copy_requirements(struct xdr_stream *xdr,
618 struct nfs42_copy_res *res) {
619 __be32 *p;
620
621 p = xdr_inline_decode(xdr, 4 + 4);
622 if (unlikely(!p))
eb72f484 623 return -EIO;
2e72448b
AS
624
625 res->consecutive = be32_to_cpup(p++);
626 res->synchronous = be32_to_cpup(p++);
627 return 0;
2e72448b
AS
628}
629
630static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res)
631{
632 int status;
633
634 status = decode_op_hdr(xdr, OP_COPY);
635 if (status == NFS4ERR_OFFLOAD_NO_REQS) {
636 status = decode_copy_requirements(xdr, res);
637 if (status)
638 return status;
639 return NFS4ERR_OFFLOAD_NO_REQS;
640 } else if (status)
641 return status;
642
643 status = decode_write_response(xdr, &res->write_res);
644 if (status)
645 return status;
646
647 return decode_copy_requirements(xdr, res);
648}
649
cb95deea
OK
650static int decode_offload_cancel(struct xdr_stream *xdr,
651 struct nfs42_offload_status_res *res)
652{
653 return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);
654}
655
0491567b
OK
656static int decode_copy_notify(struct xdr_stream *xdr,
657 struct nfs42_copy_notify_res *res)
658{
659 __be32 *p;
660 int status, count;
661
662 status = decode_op_hdr(xdr, OP_COPY_NOTIFY);
663 if (status)
664 return status;
665 /* cnr_lease_time */
666 p = xdr_inline_decode(xdr, 12);
667 if (unlikely(!p))
668 return -EIO;
669 p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds);
670 res->cnr_lease_time.nseconds = be32_to_cpup(p);
671
672 status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE);
673 if (unlikely(status))
674 return -EIO;
675
676 /* number of source addresses */
677 p = xdr_inline_decode(xdr, 4);
678 if (unlikely(!p))
679 return -EIO;
680
681 count = be32_to_cpup(p);
682 if (count > 1)
683 pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n",
684 __func__, count);
685
686 status = decode_nl4_server(xdr, &res->cnr_src);
687 if (unlikely(status))
688 return -EIO;
689 return 0;
690}
691
624bd5b7
AS
692static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
693{
694 return decode_op_hdr(xdr, OP_DEALLOCATE);
695}
696
1c6dcbe5
AS
697static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
698{
699 int status;
700 __be32 *p;
701
702 status = decode_op_hdr(xdr, OP_SEEK);
703 if (status)
704 return status;
705
706 p = xdr_inline_decode(xdr, 4 + 8);
707 if (unlikely(!p))
eb72f484 708 return -EIO;
1c6dcbe5
AS
709
710 res->sr_eof = be32_to_cpup(p++);
711 p = xdr_decode_hyper(p, &res->sr_offset);
712 return 0;
1c6dcbe5
AS
713}
714
19cf6335 715static int decode_layoutstats(struct xdr_stream *xdr)
be3a5d23 716{
da2e8127 717 return decode_op_hdr(xdr, OP_LAYOUTSTATS);
be3a5d23
TM
718}
719
36022770
PT
720static int decode_clone(struct xdr_stream *xdr)
721{
722 return decode_op_hdr(xdr, OP_CLONE);
723}
724
3eb86093
TM
725static int decode_layouterror(struct xdr_stream *xdr)
726{
727 return decode_op_hdr(xdr, OP_LAYOUTERROR);
728}
729
f4ac1674
AS
730/*
731 * Decode ALLOCATE request
732 */
733static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
734 struct xdr_stream *xdr,
18d9cff4 735 void *data)
f4ac1674 736{
18d9cff4 737 struct nfs42_falloc_res *res = data;
f4ac1674
AS
738 struct compound_hdr hdr;
739 int status;
740
741 status = decode_compound_hdr(xdr, &hdr);
742 if (status)
743 goto out;
744 status = decode_sequence(xdr, &res->seq_res, rqstp);
745 if (status)
746 goto out;
747 status = decode_putfh(xdr);
748 if (status)
749 goto out;
750 status = decode_allocate(xdr, res);
9a51940b
AS
751 if (status)
752 goto out;
753 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
f4ac1674
AS
754out:
755 return status;
756}
757
2e72448b
AS
758/*
759 * Decode COPY response
760 */
761static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp,
762 struct xdr_stream *xdr,
18d9cff4 763 void *data)
2e72448b 764{
18d9cff4 765 struct nfs42_copy_res *res = data;
2e72448b
AS
766 struct compound_hdr hdr;
767 int status;
768
769 status = decode_compound_hdr(xdr, &hdr);
770 if (status)
771 goto out;
772 status = decode_sequence(xdr, &res->seq_res, rqstp);
773 if (status)
774 goto out;
775 status = decode_putfh(xdr);
776 if (status)
777 goto out;
778 status = decode_savefh(xdr);
779 if (status)
780 goto out;
781 status = decode_putfh(xdr);
782 if (status)
783 goto out;
784 status = decode_copy(xdr, res);
e0926934
OK
785 if (status)
786 goto out;
62164f31
OK
787 if (res->commit_res.verf)
788 status = decode_commit(xdr, &res->commit_res);
2e72448b
AS
789out:
790 return status;
791}
792
cb95deea
OK
793/*
794 * Decode OFFLOAD_CANCEL response
795 */
796static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp,
797 struct xdr_stream *xdr,
798 void *data)
799{
800 struct nfs42_offload_status_res *res = data;
801 struct compound_hdr hdr;
802 int status;
803
804 status = decode_compound_hdr(xdr, &hdr);
805 if (status)
806 goto out;
807 status = decode_sequence(xdr, &res->osr_seq_res, rqstp);
808 if (status)
809 goto out;
810 status = decode_putfh(xdr);
811 if (status)
812 goto out;
813 status = decode_offload_cancel(xdr, res);
814
815out:
816 return status;
817}
818
0491567b
OK
819/*
820 * Decode COPY_NOTIFY response
821 */
822static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp,
823 struct xdr_stream *xdr,
824 void *data)
825{
826 struct nfs42_copy_notify_res *res = data;
827 struct compound_hdr hdr;
828 int status;
829
830 status = decode_compound_hdr(xdr, &hdr);
831 if (status)
832 goto out;
833 status = decode_sequence(xdr, &res->cnr_seq_res, rqstp);
834 if (status)
835 goto out;
836 status = decode_putfh(xdr);
837 if (status)
838 goto out;
839 status = decode_copy_notify(xdr, res);
840
841out:
842 return status;
843}
844
624bd5b7
AS
845/*
846 * Decode DEALLOCATE request
847 */
848static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
849 struct xdr_stream *xdr,
18d9cff4 850 void *data)
624bd5b7 851{
18d9cff4 852 struct nfs42_falloc_res *res = data;
624bd5b7
AS
853 struct compound_hdr hdr;
854 int status;
855
856 status = decode_compound_hdr(xdr, &hdr);
857 if (status)
858 goto out;
859 status = decode_sequence(xdr, &res->seq_res, rqstp);
860 if (status)
861 goto out;
862 status = decode_putfh(xdr);
863 if (status)
864 goto out;
865 status = decode_deallocate(xdr, res);
9a51940b
AS
866 if (status)
867 goto out;
868 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
624bd5b7
AS
869out:
870 return status;
871}
872
1c6dcbe5
AS
873/*
874 * Decode SEEK request
875 */
876static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
877 struct xdr_stream *xdr,
18d9cff4 878 void *data)
1c6dcbe5 879{
18d9cff4 880 struct nfs42_seek_res *res = data;
1c6dcbe5
AS
881 struct compound_hdr hdr;
882 int status;
883
884 status = decode_compound_hdr(xdr, &hdr);
885 if (status)
886 goto out;
887 status = decode_sequence(xdr, &res->seq_res, rqstp);
888 if (status)
889 goto out;
890 status = decode_putfh(xdr);
891 if (status)
892 goto out;
893 status = decode_seek(xdr, res);
894out:
895 return status;
896}
be3a5d23
TM
897
898/*
899 * Decode LAYOUTSTATS request
900 */
901static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp,
902 struct xdr_stream *xdr,
18d9cff4 903 void *data)
be3a5d23 904{
18d9cff4 905 struct nfs42_layoutstat_res *res = data;
be3a5d23
TM
906 struct compound_hdr hdr;
907 int status, i;
908
909 status = decode_compound_hdr(xdr, &hdr);
910 if (status)
911 goto out;
912 status = decode_sequence(xdr, &res->seq_res, rqstp);
913 if (status)
914 goto out;
915 status = decode_putfh(xdr);
916 if (status)
917 goto out;
918 WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
919 for (i = 0; i < res->num_dev; i++) {
19cf6335 920 status = decode_layoutstats(xdr);
be3a5d23
TM
921 if (status)
922 goto out;
923 }
924out:
925 res->rpc_status = status;
926 return status;
927}
928
36022770
PT
929/*
930 * Decode CLONE request
931 */
932static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp,
933 struct xdr_stream *xdr,
18d9cff4 934 void *data)
36022770 935{
18d9cff4 936 struct nfs42_clone_res *res = data;
36022770
PT
937 struct compound_hdr hdr;
938 int status;
939
940 status = decode_compound_hdr(xdr, &hdr);
941 if (status)
942 goto out;
943 status = decode_sequence(xdr, &res->seq_res, rqstp);
944 if (status)
945 goto out;
946 status = decode_putfh(xdr);
947 if (status)
948 goto out;
949 status = decode_savefh(xdr);
950 if (status)
951 goto out;
952 status = decode_putfh(xdr);
953 if (status)
954 goto out;
955 status = decode_clone(xdr);
956 if (status)
957 goto out;
958 status = decode_getfattr(xdr, res->dst_fattr, res->server);
959
960out:
961 res->rpc_status = status;
962 return status;
963}
964
3eb86093
TM
965/*
966 * Decode LAYOUTERROR request
967 */
968static int nfs4_xdr_dec_layouterror(struct rpc_rqst *rqstp,
969 struct xdr_stream *xdr,
970 void *data)
971{
972 struct nfs42_layouterror_res *res = data;
973 struct compound_hdr hdr;
974 int status, i;
975
976 status = decode_compound_hdr(xdr, &hdr);
977 if (status)
978 goto out;
979 status = decode_sequence(xdr, &res->seq_res, rqstp);
980 if (status)
981 goto out;
982 status = decode_putfh(xdr);
983
984 for (i = 0; i < res->num_errors && status == 0; i++)
985 status = decode_layouterror(xdr);
986out:
987 res->rpc_status = status;
988 return status;
989}
990
1c6dcbe5 991#endif /* __LINUX_FS_NFS_NFS4_2XDR_H */