Merge tag 'memblock-v5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rppt...
[linux-2.6-microblaze.git] / fs / nfs / nfs42xdr.c
1 // SPDX-License-Identifier: GPL-2.0
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
8 #include "nfs42.h"
9
10 #define encode_fallocate_maxsz          (encode_stateid_maxsz + \
11                                          2 /* offset */ + \
12                                          2 /* length */)
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))
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                                          1 + /* One cnr_source_server */\
26                                          1 + /* nl4_type */ \
27                                          1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
28 #define decode_copy_maxsz               (op_decode_hdr_maxsz + \
29                                          NFS42_WRITE_RES_SIZE + \
30                                          1 /* cr_consecutive */ + \
31                                          1 /* cr_synchronous */)
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)
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))
45 #define encode_deallocate_maxsz         (op_encode_hdr_maxsz + \
46                                          encode_fallocate_maxsz)
47 #define decode_deallocate_maxsz         (op_decode_hdr_maxsz)
48 #define encode_read_plus_maxsz          (op_encode_hdr_maxsz + \
49                                          encode_stateid_maxsz + 3)
50 #define NFS42_READ_PLUS_SEGMENT_SIZE    (1 /* data_content4 */ + \
51                                          2 /* data_info4.di_offset */ + \
52                                          2 /* data_info4.di_length */)
53 #define decode_read_plus_maxsz          (op_decode_hdr_maxsz + \
54                                          1 /* rpr_eof */ + \
55                                          1 /* rpr_contents count */ + \
56                                          2 * NFS42_READ_PLUS_SEGMENT_SIZE)
57 #define encode_seek_maxsz               (op_encode_hdr_maxsz + \
58                                          encode_stateid_maxsz + \
59                                          2 /* offset */ + \
60                                          1 /* whence */)
61 #define decode_seek_maxsz               (op_decode_hdr_maxsz + \
62                                          1 /* eof */ + \
63                                          1 /* whence */ + \
64                                          2 /* offset */ + \
65                                          2 /* length */)
66 #define encode_io_info_maxsz            4
67 #define encode_layoutstats_maxsz        (op_decode_hdr_maxsz + \
68                                         2 /* offset */ + \
69                                         2 /* length */ + \
70                                         encode_stateid_maxsz + \
71                                         encode_io_info_maxsz + \
72                                         encode_io_info_maxsz + \
73                                         1 /* opaque devaddr4 length */ + \
74                                         XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE))
75 #define decode_layoutstats_maxsz        (op_decode_hdr_maxsz)
76 #define encode_device_error_maxsz       (XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \
77                                         1 /* status */ + 1 /* opnum */)
78 #define encode_layouterror_maxsz        (op_decode_hdr_maxsz + \
79                                         2 /* offset */ + \
80                                         2 /* length */ + \
81                                         encode_stateid_maxsz + \
82                                         1 /* Array size */ + \
83                                         encode_device_error_maxsz)
84 #define decode_layouterror_maxsz        (op_decode_hdr_maxsz)
85 #define encode_clone_maxsz              (encode_stateid_maxsz + \
86                                         encode_stateid_maxsz + \
87                                         2 /* src offset */ + \
88                                         2 /* dst offset */ + \
89                                         2 /* count */)
90 #define decode_clone_maxsz              (op_decode_hdr_maxsz)
91
92 #define NFS4_enc_allocate_sz            (compound_encode_hdr_maxsz + \
93                                          encode_sequence_maxsz + \
94                                          encode_putfh_maxsz + \
95                                          encode_allocate_maxsz + \
96                                          encode_getattr_maxsz)
97 #define NFS4_dec_allocate_sz            (compound_decode_hdr_maxsz + \
98                                          decode_sequence_maxsz + \
99                                          decode_putfh_maxsz + \
100                                          decode_allocate_maxsz + \
101                                          decode_getattr_maxsz)
102 #define NFS4_enc_copy_sz                (compound_encode_hdr_maxsz + \
103                                          encode_sequence_maxsz + \
104                                          encode_putfh_maxsz + \
105                                          encode_savefh_maxsz + \
106                                          encode_putfh_maxsz + \
107                                          encode_copy_maxsz + \
108                                          encode_commit_maxsz)
109 #define NFS4_dec_copy_sz                (compound_decode_hdr_maxsz + \
110                                          decode_sequence_maxsz + \
111                                          decode_putfh_maxsz + \
112                                          decode_savefh_maxsz + \
113                                          decode_putfh_maxsz + \
114                                          decode_copy_maxsz + \
115                                          decode_commit_maxsz)
116 #define NFS4_enc_offload_cancel_sz      (compound_encode_hdr_maxsz + \
117                                          encode_sequence_maxsz + \
118                                          encode_putfh_maxsz + \
119                                          encode_offload_cancel_maxsz)
120 #define NFS4_dec_offload_cancel_sz      (compound_decode_hdr_maxsz + \
121                                          decode_sequence_maxsz + \
122                                          decode_putfh_maxsz + \
123                                          decode_offload_cancel_maxsz)
124 #define NFS4_enc_copy_notify_sz         (compound_encode_hdr_maxsz + \
125                                          encode_putfh_maxsz + \
126                                          encode_copy_notify_maxsz)
127 #define NFS4_dec_copy_notify_sz         (compound_decode_hdr_maxsz + \
128                                          decode_putfh_maxsz + \
129                                          decode_copy_notify_maxsz)
130 #define NFS4_enc_deallocate_sz          (compound_encode_hdr_maxsz + \
131                                          encode_sequence_maxsz + \
132                                          encode_putfh_maxsz + \
133                                          encode_deallocate_maxsz + \
134                                          encode_getattr_maxsz)
135 #define NFS4_dec_deallocate_sz          (compound_decode_hdr_maxsz + \
136                                          decode_sequence_maxsz + \
137                                          decode_putfh_maxsz + \
138                                          decode_deallocate_maxsz + \
139                                          decode_getattr_maxsz)
140 #define NFS4_enc_read_plus_sz           (compound_encode_hdr_maxsz + \
141                                          encode_sequence_maxsz + \
142                                          encode_putfh_maxsz + \
143                                          encode_read_plus_maxsz)
144 #define NFS4_dec_read_plus_sz           (compound_decode_hdr_maxsz + \
145                                          decode_sequence_maxsz + \
146                                          decode_putfh_maxsz + \
147                                          decode_read_plus_maxsz)
148 #define NFS4_enc_seek_sz                (compound_encode_hdr_maxsz + \
149                                          encode_sequence_maxsz + \
150                                          encode_putfh_maxsz + \
151                                          encode_seek_maxsz)
152 #define NFS4_dec_seek_sz                (compound_decode_hdr_maxsz + \
153                                          decode_sequence_maxsz + \
154                                          decode_putfh_maxsz + \
155                                          decode_seek_maxsz)
156 #define NFS4_enc_layoutstats_sz         (compound_encode_hdr_maxsz + \
157                                          encode_sequence_maxsz + \
158                                          encode_putfh_maxsz + \
159                                          PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz)
160 #define NFS4_dec_layoutstats_sz         (compound_decode_hdr_maxsz + \
161                                          decode_sequence_maxsz + \
162                                          decode_putfh_maxsz + \
163                                          PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz)
164 #define NFS4_enc_layouterror_sz         (compound_encode_hdr_maxsz + \
165                                          encode_sequence_maxsz + \
166                                          encode_putfh_maxsz + \
167                                          NFS42_LAYOUTERROR_MAX * \
168                                          encode_layouterror_maxsz)
169 #define NFS4_dec_layouterror_sz         (compound_decode_hdr_maxsz + \
170                                          decode_sequence_maxsz + \
171                                          decode_putfh_maxsz + \
172                                          NFS42_LAYOUTERROR_MAX * \
173                                          decode_layouterror_maxsz)
174 #define NFS4_enc_clone_sz               (compound_encode_hdr_maxsz + \
175                                          encode_sequence_maxsz + \
176                                          encode_putfh_maxsz + \
177                                          encode_savefh_maxsz + \
178                                          encode_putfh_maxsz + \
179                                          encode_clone_maxsz + \
180                                          encode_getattr_maxsz)
181 #define NFS4_dec_clone_sz               (compound_decode_hdr_maxsz + \
182                                          decode_sequence_maxsz + \
183                                          decode_putfh_maxsz + \
184                                          decode_savefh_maxsz + \
185                                          decode_putfh_maxsz + \
186                                          decode_clone_maxsz + \
187                                          decode_getattr_maxsz)
188
189 /* Not limited by NFS itself, limited by the generic xattr code */
190 #define nfs4_xattr_name_maxsz   XDR_QUADLEN(XATTR_NAME_MAX)
191
192 #define encode_getxattr_maxsz   (op_encode_hdr_maxsz + 1 + \
193                                  nfs4_xattr_name_maxsz)
194 #define decode_getxattr_maxsz   (op_decode_hdr_maxsz + 1 + 1)
195 #define encode_setxattr_maxsz   (op_encode_hdr_maxsz + \
196                                  1 + nfs4_xattr_name_maxsz + 1)
197 #define decode_setxattr_maxsz   (op_decode_hdr_maxsz + decode_change_info_maxsz)
198 #define encode_listxattrs_maxsz  (op_encode_hdr_maxsz + 2 + 1)
199 #define decode_listxattrs_maxsz  (op_decode_hdr_maxsz + 2 + 1 + 1 + 1)
200 #define encode_removexattr_maxsz (op_encode_hdr_maxsz + 1 + \
201                                   nfs4_xattr_name_maxsz)
202 #define decode_removexattr_maxsz (op_decode_hdr_maxsz + \
203                                   decode_change_info_maxsz)
204
205 #define NFS4_enc_getxattr_sz    (compound_encode_hdr_maxsz + \
206                                 encode_sequence_maxsz + \
207                                 encode_putfh_maxsz + \
208                                 encode_getxattr_maxsz)
209 #define NFS4_dec_getxattr_sz    (compound_decode_hdr_maxsz + \
210                                 decode_sequence_maxsz + \
211                                 decode_putfh_maxsz + \
212                                 decode_getxattr_maxsz)
213 #define NFS4_enc_setxattr_sz    (compound_encode_hdr_maxsz + \
214                                 encode_sequence_maxsz + \
215                                 encode_putfh_maxsz + \
216                                 encode_setxattr_maxsz)
217 #define NFS4_dec_setxattr_sz    (compound_decode_hdr_maxsz + \
218                                 decode_sequence_maxsz + \
219                                 decode_putfh_maxsz + \
220                                 decode_setxattr_maxsz)
221 #define NFS4_enc_listxattrs_sz  (compound_encode_hdr_maxsz + \
222                                 encode_sequence_maxsz + \
223                                 encode_putfh_maxsz + \
224                                 encode_listxattrs_maxsz)
225 #define NFS4_dec_listxattrs_sz  (compound_decode_hdr_maxsz + \
226                                 decode_sequence_maxsz + \
227                                 decode_putfh_maxsz + \
228                                 decode_listxattrs_maxsz)
229 #define NFS4_enc_removexattr_sz (compound_encode_hdr_maxsz + \
230                                 encode_sequence_maxsz + \
231                                 encode_putfh_maxsz + \
232                                 encode_removexattr_maxsz)
233 #define NFS4_dec_removexattr_sz (compound_decode_hdr_maxsz + \
234                                 decode_sequence_maxsz + \
235                                 decode_putfh_maxsz + \
236                                 decode_removexattr_maxsz)
237
238 /*
239  * These values specify the maximum amount of data that is not
240  * associated with the extended attribute name or extended
241  * attribute list in the SETXATTR, GETXATTR and LISTXATTR
242  * respectively.
243  */
244 const u32 nfs42_maxsetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
245                                         compound_encode_hdr_maxsz +
246                                         encode_sequence_maxsz +
247                                         encode_putfh_maxsz + 1 +
248                                         nfs4_xattr_name_maxsz)
249                                         * XDR_UNIT);
250
251 const u32 nfs42_maxgetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
252                                         compound_decode_hdr_maxsz +
253                                         decode_sequence_maxsz +
254                                         decode_putfh_maxsz + 1) * XDR_UNIT);
255
256 const u32 nfs42_maxlistxattrs_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
257                                         compound_decode_hdr_maxsz +
258                                         decode_sequence_maxsz +
259                                         decode_putfh_maxsz + 3) * XDR_UNIT);
260
261 static void encode_fallocate(struct xdr_stream *xdr,
262                              const struct nfs42_falloc_args *args)
263 {
264         encode_nfs4_stateid(xdr, &args->falloc_stateid);
265         encode_uint64(xdr, args->falloc_offset);
266         encode_uint64(xdr, args->falloc_length);
267 }
268
269 static void encode_allocate(struct xdr_stream *xdr,
270                             const struct nfs42_falloc_args *args,
271                             struct compound_hdr *hdr)
272 {
273         encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
274         encode_fallocate(xdr, args);
275 }
276
277 static void encode_nl4_server(struct xdr_stream *xdr,
278                               const struct nl4_server *ns)
279 {
280         encode_uint32(xdr, ns->nl4_type);
281         switch (ns->nl4_type) {
282         case NL4_NAME:
283         case NL4_URL:
284                 encode_string(xdr, ns->u.nl4_str_sz, ns->u.nl4_str);
285                 break;
286         case NL4_NETADDR:
287                 encode_string(xdr, ns->u.nl4_addr.netid_len,
288                               ns->u.nl4_addr.netid);
289                 encode_string(xdr, ns->u.nl4_addr.addr_len,
290                               ns->u.nl4_addr.addr);
291                 break;
292         default:
293                 WARN_ON_ONCE(1);
294         }
295 }
296
297 static void encode_copy(struct xdr_stream *xdr,
298                         const struct nfs42_copy_args *args,
299                         struct compound_hdr *hdr)
300 {
301         encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr);
302         encode_nfs4_stateid(xdr, &args->src_stateid);
303         encode_nfs4_stateid(xdr, &args->dst_stateid);
304
305         encode_uint64(xdr, args->src_pos);
306         encode_uint64(xdr, args->dst_pos);
307         encode_uint64(xdr, args->count);
308
309         encode_uint32(xdr, 1); /* consecutive = true */
310         encode_uint32(xdr, args->sync);
311         if (args->cp_src == NULL) { /* intra-ssc */
312                 encode_uint32(xdr, 0); /* no src server list */
313                 return;
314         }
315         encode_uint32(xdr, 1); /* supporting 1 server */
316         encode_nl4_server(xdr, args->cp_src);
317 }
318
319 static void encode_offload_cancel(struct xdr_stream *xdr,
320                                   const struct nfs42_offload_status_args *args,
321                                   struct compound_hdr *hdr)
322 {
323         encode_op_hdr(xdr, OP_OFFLOAD_CANCEL, decode_offload_cancel_maxsz, hdr);
324         encode_nfs4_stateid(xdr, &args->osa_stateid);
325 }
326
327 static void encode_copy_notify(struct xdr_stream *xdr,
328                                const struct nfs42_copy_notify_args *args,
329                                struct compound_hdr *hdr)
330 {
331         encode_op_hdr(xdr, OP_COPY_NOTIFY, decode_copy_notify_maxsz, hdr);
332         encode_nfs4_stateid(xdr, &args->cna_src_stateid);
333         encode_nl4_server(xdr, &args->cna_dst);
334 }
335
336 static void encode_deallocate(struct xdr_stream *xdr,
337                               const struct nfs42_falloc_args *args,
338                               struct compound_hdr *hdr)
339 {
340         encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
341         encode_fallocate(xdr, args);
342 }
343
344 static void encode_read_plus(struct xdr_stream *xdr,
345                              const struct nfs_pgio_args *args,
346                              struct compound_hdr *hdr)
347 {
348         encode_op_hdr(xdr, OP_READ_PLUS, decode_read_plus_maxsz, hdr);
349         encode_nfs4_stateid(xdr, &args->stateid);
350         encode_uint64(xdr, args->offset);
351         encode_uint32(xdr, args->count);
352 }
353
354 static void encode_seek(struct xdr_stream *xdr,
355                         const struct nfs42_seek_args *args,
356                         struct compound_hdr *hdr)
357 {
358         encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr);
359         encode_nfs4_stateid(xdr, &args->sa_stateid);
360         encode_uint64(xdr, args->sa_offset);
361         encode_uint32(xdr, args->sa_what);
362 }
363
364 static void encode_layoutstats(struct xdr_stream *xdr,
365                                const struct nfs42_layoutstat_args *args,
366                                struct nfs42_layoutstat_devinfo *devinfo,
367                                struct compound_hdr *hdr)
368 {
369         __be32 *p;
370
371         encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr);
372         p = reserve_space(xdr, 8 + 8);
373         p = xdr_encode_hyper(p, devinfo->offset);
374         p = xdr_encode_hyper(p, devinfo->length);
375         encode_nfs4_stateid(xdr, &args->stateid);
376         p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4);
377         p = xdr_encode_hyper(p, devinfo->read_count);
378         p = xdr_encode_hyper(p, devinfo->read_bytes);
379         p = xdr_encode_hyper(p, devinfo->write_count);
380         p = xdr_encode_hyper(p, devinfo->write_bytes);
381         p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data,
382                         NFS4_DEVICEID4_SIZE);
383         /* Encode layoutupdate4 */
384         *p++ = cpu_to_be32(devinfo->layout_type);
385         if (devinfo->ld_private.ops)
386                 devinfo->ld_private.ops->encode(xdr, args,
387                                 &devinfo->ld_private);
388         else
389                 encode_uint32(xdr, 0);
390 }
391
392 static void encode_clone(struct xdr_stream *xdr,
393                          const struct nfs42_clone_args *args,
394                          struct compound_hdr *hdr)
395 {
396         __be32 *p;
397
398         encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr);
399         encode_nfs4_stateid(xdr, &args->src_stateid);
400         encode_nfs4_stateid(xdr, &args->dst_stateid);
401         p = reserve_space(xdr, 3*8);
402         p = xdr_encode_hyper(p, args->src_offset);
403         p = xdr_encode_hyper(p, args->dst_offset);
404         xdr_encode_hyper(p, args->count);
405 }
406
407 static void encode_device_error(struct xdr_stream *xdr,
408                                 const struct nfs42_device_error *error)
409 {
410         __be32 *p;
411
412         p = reserve_space(xdr, NFS4_DEVICEID4_SIZE + 2*4);
413         p = xdr_encode_opaque_fixed(p, error->dev_id.data,
414                         NFS4_DEVICEID4_SIZE);
415         *p++ = cpu_to_be32(error->status);
416         *p = cpu_to_be32(error->opnum);
417 }
418
419 static void encode_layouterror(struct xdr_stream *xdr,
420                                const struct nfs42_layout_error *args,
421                                struct compound_hdr *hdr)
422 {
423         __be32 *p;
424
425         encode_op_hdr(xdr, OP_LAYOUTERROR, decode_layouterror_maxsz, hdr);
426         p = reserve_space(xdr, 8 + 8);
427         p = xdr_encode_hyper(p, args->offset);
428         p = xdr_encode_hyper(p, args->length);
429         encode_nfs4_stateid(xdr, &args->stateid);
430         p = reserve_space(xdr, 4);
431         *p = cpu_to_be32(1);
432         encode_device_error(xdr, &args->errors[0]);
433 }
434
435 static void encode_setxattr(struct xdr_stream *xdr,
436                             const struct nfs42_setxattrargs *arg,
437                             struct compound_hdr *hdr)
438 {
439         __be32 *p;
440
441         BUILD_BUG_ON(XATTR_CREATE != SETXATTR4_CREATE);
442         BUILD_BUG_ON(XATTR_REPLACE != SETXATTR4_REPLACE);
443
444         encode_op_hdr(xdr, OP_SETXATTR, decode_setxattr_maxsz, hdr);
445         p = reserve_space(xdr, 4);
446         *p = cpu_to_be32(arg->xattr_flags);
447         encode_string(xdr, strlen(arg->xattr_name), arg->xattr_name);
448         p = reserve_space(xdr, 4);
449         *p = cpu_to_be32(arg->xattr_len);
450         if (arg->xattr_len)
451                 xdr_write_pages(xdr, arg->xattr_pages, 0, arg->xattr_len);
452 }
453
454 static int decode_setxattr(struct xdr_stream *xdr,
455                            struct nfs4_change_info *cinfo)
456 {
457         int status;
458
459         status = decode_op_hdr(xdr, OP_SETXATTR);
460         if (status)
461                 goto out;
462         status = decode_change_info(xdr, cinfo);
463 out:
464         return status;
465 }
466
467
468 static void encode_getxattr(struct xdr_stream *xdr, const char *name,
469                             struct compound_hdr *hdr)
470 {
471         encode_op_hdr(xdr, OP_GETXATTR, decode_getxattr_maxsz, hdr);
472         encode_string(xdr, strlen(name), name);
473 }
474
475 static int decode_getxattr(struct xdr_stream *xdr,
476                            struct nfs42_getxattrres *res,
477                            struct rpc_rqst *req)
478 {
479         int status;
480         __be32 *p;
481         u32 len, rdlen;
482
483         status = decode_op_hdr(xdr, OP_GETXATTR);
484         if (status)
485                 return status;
486
487         p = xdr_inline_decode(xdr, 4);
488         if (unlikely(!p))
489                 return -EIO;
490
491         len = be32_to_cpup(p);
492         if (len > req->rq_rcv_buf.page_len)
493                 return -ERANGE;
494
495         res->xattr_len = len;
496
497         if (len > 0) {
498                 rdlen = xdr_read_pages(xdr, len);
499                 if (rdlen < len)
500                         return -EIO;
501         }
502
503         return 0;
504 }
505
506 static void encode_removexattr(struct xdr_stream *xdr, const char *name,
507                                struct compound_hdr *hdr)
508 {
509         encode_op_hdr(xdr, OP_REMOVEXATTR, decode_removexattr_maxsz, hdr);
510         encode_string(xdr, strlen(name), name);
511 }
512
513
514 static int decode_removexattr(struct xdr_stream *xdr,
515                            struct nfs4_change_info *cinfo)
516 {
517         int status;
518
519         status = decode_op_hdr(xdr, OP_REMOVEXATTR);
520         if (status)
521                 goto out;
522
523         status = decode_change_info(xdr, cinfo);
524 out:
525         return status;
526 }
527
528 static void encode_listxattrs(struct xdr_stream *xdr,
529                              const struct nfs42_listxattrsargs *arg,
530                              struct compound_hdr *hdr)
531 {
532         __be32 *p;
533
534         encode_op_hdr(xdr, OP_LISTXATTRS, decode_listxattrs_maxsz, hdr);
535
536         p = reserve_space(xdr, 12);
537         if (unlikely(!p))
538                 return;
539
540         p = xdr_encode_hyper(p, arg->cookie);
541         /*
542          * RFC 8276 says to specify the full max length of the LISTXATTRS
543          * XDR reply. Count is set to the XDR length of the names array
544          * plus the EOF marker. So, add the cookie and the names count.
545          */
546         *p = cpu_to_be32(arg->count + 8 + 4);
547 }
548
549 static int decode_listxattrs(struct xdr_stream *xdr,
550                             struct nfs42_listxattrsres *res)
551 {
552         int status;
553         __be32 *p;
554         u32 count, len, ulen;
555         size_t left, copied;
556         char *buf;
557
558         status = decode_op_hdr(xdr, OP_LISTXATTRS);
559         if (status) {
560                 /*
561                  * Special case: for LISTXATTRS, NFS4ERR_TOOSMALL
562                  * should be translated to ERANGE.
563                  */
564                 if (status == -ETOOSMALL)
565                         status = -ERANGE;
566                 goto out;
567         }
568
569         p = xdr_inline_decode(xdr, 8);
570         if (unlikely(!p))
571                 return -EIO;
572
573         xdr_decode_hyper(p, &res->cookie);
574
575         p = xdr_inline_decode(xdr, 4);
576         if (unlikely(!p))
577                 return -EIO;
578
579         left = res->xattr_len;
580         buf = res->xattr_buf;
581
582         count = be32_to_cpup(p);
583         copied = 0;
584
585         /*
586          * We have asked for enough room to encode the maximum number
587          * of possible attribute names, so everything should fit.
588          *
589          * But, don't rely on that assumption. Just decode entries
590          * until they don't fit anymore, just in case the server did
591          * something odd.
592          */
593         while (count--) {
594                 p = xdr_inline_decode(xdr, 4);
595                 if (unlikely(!p))
596                         return -EIO;
597
598                 len = be32_to_cpup(p);
599                 if (len > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) {
600                         status = -ERANGE;
601                         goto out;
602                 }
603
604                 p = xdr_inline_decode(xdr, len);
605                 if (unlikely(!p))
606                         return -EIO;
607
608                 ulen = len + XATTR_USER_PREFIX_LEN + 1;
609                 if (buf) {
610                         if (ulen > left) {
611                                 status = -ERANGE;
612                                 goto out;
613                         }
614
615                         memcpy(buf, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
616                         memcpy(buf + XATTR_USER_PREFIX_LEN, p, len);
617
618                         buf[ulen - 1] = 0;
619                         buf += ulen;
620                         left -= ulen;
621                 }
622                 copied += ulen;
623         }
624
625         p = xdr_inline_decode(xdr, 4);
626         if (unlikely(!p))
627                 return -EIO;
628
629         res->eof = be32_to_cpup(p);
630         res->copied = copied;
631
632 out:
633         if (status == -ERANGE && res->xattr_len == XATTR_LIST_MAX)
634                 status = -E2BIG;
635
636         return status;
637 }
638
639 /*
640  * Encode ALLOCATE request
641  */
642 static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
643                                   struct xdr_stream *xdr,
644                                   const void *data)
645 {
646         const struct nfs42_falloc_args *args = data;
647         struct compound_hdr hdr = {
648                 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
649         };
650
651         encode_compound_hdr(xdr, req, &hdr);
652         encode_sequence(xdr, &args->seq_args, &hdr);
653         encode_putfh(xdr, args->falloc_fh, &hdr);
654         encode_allocate(xdr, args, &hdr);
655         encode_getfattr(xdr, args->falloc_bitmask, &hdr);
656         encode_nops(&hdr);
657 }
658
659 static void encode_copy_commit(struct xdr_stream *xdr,
660                           const struct nfs42_copy_args *args,
661                           struct compound_hdr *hdr)
662 {
663         __be32 *p;
664
665         encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr);
666         p = reserve_space(xdr, 12);
667         p = xdr_encode_hyper(p, args->dst_pos);
668         *p = cpu_to_be32(args->count);
669 }
670
671 /*
672  * Encode COPY request
673  */
674 static void nfs4_xdr_enc_copy(struct rpc_rqst *req,
675                               struct xdr_stream *xdr,
676                               const void *data)
677 {
678         const struct nfs42_copy_args *args = data;
679         struct compound_hdr hdr = {
680                 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
681         };
682
683         encode_compound_hdr(xdr, req, &hdr);
684         encode_sequence(xdr, &args->seq_args, &hdr);
685         encode_putfh(xdr, args->src_fh, &hdr);
686         encode_savefh(xdr, &hdr);
687         encode_putfh(xdr, args->dst_fh, &hdr);
688         encode_copy(xdr, args, &hdr);
689         if (args->sync)
690                 encode_copy_commit(xdr, args, &hdr);
691         encode_nops(&hdr);
692 }
693
694 /*
695  * Encode OFFLOAD_CANEL request
696  */
697 static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req,
698                                         struct xdr_stream *xdr,
699                                         const void *data)
700 {
701         const struct nfs42_offload_status_args *args = data;
702         struct compound_hdr hdr = {
703                 .minorversion = nfs4_xdr_minorversion(&args->osa_seq_args),
704         };
705
706         encode_compound_hdr(xdr, req, &hdr);
707         encode_sequence(xdr, &args->osa_seq_args, &hdr);
708         encode_putfh(xdr, args->osa_src_fh, &hdr);
709         encode_offload_cancel(xdr, args, &hdr);
710         encode_nops(&hdr);
711 }
712
713 /*
714  * Encode COPY_NOTIFY request
715  */
716 static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req,
717                                      struct xdr_stream *xdr,
718                                      const void *data)
719 {
720         const struct nfs42_copy_notify_args *args = data;
721         struct compound_hdr hdr = {
722                 .minorversion = nfs4_xdr_minorversion(&args->cna_seq_args),
723         };
724
725         encode_compound_hdr(xdr, req, &hdr);
726         encode_sequence(xdr, &args->cna_seq_args, &hdr);
727         encode_putfh(xdr, args->cna_src_fh, &hdr);
728         encode_copy_notify(xdr, args, &hdr);
729         encode_nops(&hdr);
730 }
731
732 /*
733  * Encode DEALLOCATE request
734  */
735 static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
736                                     struct xdr_stream *xdr,
737                                     const void *data)
738 {
739         const struct nfs42_falloc_args *args = data;
740         struct compound_hdr hdr = {
741                 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
742         };
743
744         encode_compound_hdr(xdr, req, &hdr);
745         encode_sequence(xdr, &args->seq_args, &hdr);
746         encode_putfh(xdr, args->falloc_fh, &hdr);
747         encode_deallocate(xdr, args, &hdr);
748         encode_getfattr(xdr, args->falloc_bitmask, &hdr);
749         encode_nops(&hdr);
750 }
751
752 /*
753  * Encode READ_PLUS request
754  */
755 static void nfs4_xdr_enc_read_plus(struct rpc_rqst *req,
756                                    struct xdr_stream *xdr,
757                                    const void *data)
758 {
759         const struct nfs_pgio_args *args = data;
760         struct compound_hdr hdr = {
761                 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
762         };
763
764         encode_compound_hdr(xdr, req, &hdr);
765         encode_sequence(xdr, &args->seq_args, &hdr);
766         encode_putfh(xdr, args->fh, &hdr);
767         encode_read_plus(xdr, args, &hdr);
768
769         rpc_prepare_reply_pages(req, args->pages, args->pgbase,
770                                 args->count, hdr.replen);
771         encode_nops(&hdr);
772 }
773
774 /*
775  * Encode SEEK request
776  */
777 static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
778                               struct xdr_stream *xdr,
779                               const void *data)
780 {
781         const struct nfs42_seek_args *args = data;
782         struct compound_hdr hdr = {
783                 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
784         };
785
786         encode_compound_hdr(xdr, req, &hdr);
787         encode_sequence(xdr, &args->seq_args, &hdr);
788         encode_putfh(xdr, args->sa_fh, &hdr);
789         encode_seek(xdr, args, &hdr);
790         encode_nops(&hdr);
791 }
792
793 /*
794  * Encode LAYOUTSTATS request
795  */
796 static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req,
797                                      struct xdr_stream *xdr,
798                                      const void *data)
799 {
800         const struct nfs42_layoutstat_args *args = data;
801         int i;
802
803         struct compound_hdr hdr = {
804                 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
805         };
806
807         encode_compound_hdr(xdr, req, &hdr);
808         encode_sequence(xdr, &args->seq_args, &hdr);
809         encode_putfh(xdr, args->fh, &hdr);
810         WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
811         for (i = 0; i < args->num_dev; i++)
812                 encode_layoutstats(xdr, args, &args->devinfo[i], &hdr);
813         encode_nops(&hdr);
814 }
815
816 /*
817  * Encode CLONE request
818  */
819 static void nfs4_xdr_enc_clone(struct rpc_rqst *req,
820                                struct xdr_stream *xdr,
821                                const void *data)
822 {
823         const struct nfs42_clone_args *args = data;
824         struct compound_hdr hdr = {
825                 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
826         };
827
828         encode_compound_hdr(xdr, req, &hdr);
829         encode_sequence(xdr, &args->seq_args, &hdr);
830         encode_putfh(xdr, args->src_fh, &hdr);
831         encode_savefh(xdr, &hdr);
832         encode_putfh(xdr, args->dst_fh, &hdr);
833         encode_clone(xdr, args, &hdr);
834         encode_getfattr(xdr, args->dst_bitmask, &hdr);
835         encode_nops(&hdr);
836 }
837
838 /*
839  * Encode LAYOUTERROR request
840  */
841 static void nfs4_xdr_enc_layouterror(struct rpc_rqst *req,
842                                      struct xdr_stream *xdr,
843                                      const void *data)
844 {
845         const struct nfs42_layouterror_args *args = data;
846         struct compound_hdr hdr = {
847                 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
848         };
849         int i;
850
851         encode_compound_hdr(xdr, req, &hdr);
852         encode_sequence(xdr, &args->seq_args, &hdr);
853         encode_putfh(xdr, NFS_FH(args->inode), &hdr);
854         for (i = 0; i < args->num_errors; i++)
855                 encode_layouterror(xdr, &args->errors[i], &hdr);
856         encode_nops(&hdr);
857 }
858
859 static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
860 {
861         return decode_op_hdr(xdr, OP_ALLOCATE);
862 }
863
864 static int decode_write_response(struct xdr_stream *xdr,
865                                  struct nfs42_write_res *res)
866 {
867         __be32 *p;
868         int status, count;
869
870         p = xdr_inline_decode(xdr, 4);
871         if (unlikely(!p))
872                 return -EIO;
873         count = be32_to_cpup(p);
874         if (count > 1)
875                 return -EREMOTEIO;
876         else if (count == 1) {
877                 status = decode_opaque_fixed(xdr, &res->stateid,
878                                 NFS4_STATEID_SIZE);
879                 if (unlikely(status))
880                         return -EIO;
881         }
882         p = xdr_inline_decode(xdr, 8 + 4);
883         if (unlikely(!p))
884                 return -EIO;
885         p = xdr_decode_hyper(p, &res->count);
886         res->verifier.committed = be32_to_cpup(p);
887         return decode_verifier(xdr, &res->verifier.verifier);
888 }
889
890 static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns)
891 {
892         struct nfs42_netaddr *naddr;
893         uint32_t dummy;
894         char *dummy_str;
895         __be32 *p;
896         int status;
897
898         /* nl_type */
899         p = xdr_inline_decode(xdr, 4);
900         if (unlikely(!p))
901                 return -EIO;
902         ns->nl4_type = be32_to_cpup(p);
903         switch (ns->nl4_type) {
904         case NL4_NAME:
905         case NL4_URL:
906                 status = decode_opaque_inline(xdr, &dummy, &dummy_str);
907                 if (unlikely(status))
908                         return status;
909                 if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
910                         return -EIO;
911                 memcpy(&ns->u.nl4_str, dummy_str, dummy);
912                 ns->u.nl4_str_sz = dummy;
913                 break;
914         case NL4_NETADDR:
915                 naddr = &ns->u.nl4_addr;
916
917                 /* netid string */
918                 status = decode_opaque_inline(xdr, &dummy, &dummy_str);
919                 if (unlikely(status))
920                         return status;
921                 if (unlikely(dummy > RPCBIND_MAXNETIDLEN))
922                         return -EIO;
923                 naddr->netid_len = dummy;
924                 memcpy(naddr->netid, dummy_str, naddr->netid_len);
925
926                 /* uaddr string */
927                 status = decode_opaque_inline(xdr, &dummy, &dummy_str);
928                 if (unlikely(status))
929                         return status;
930                 if (unlikely(dummy > RPCBIND_MAXUADDRLEN))
931                         return -EIO;
932                 naddr->addr_len = dummy;
933                 memcpy(naddr->addr, dummy_str, naddr->addr_len);
934                 break;
935         default:
936                 WARN_ON_ONCE(1);
937                 return -EIO;
938         }
939         return 0;
940 }
941
942 static int decode_copy_requirements(struct xdr_stream *xdr,
943                                     struct nfs42_copy_res *res) {
944         __be32 *p;
945
946         p = xdr_inline_decode(xdr, 4 + 4);
947         if (unlikely(!p))
948                 return -EIO;
949
950         res->consecutive = be32_to_cpup(p++);
951         res->synchronous = be32_to_cpup(p++);
952         return 0;
953 }
954
955 static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res)
956 {
957         int status;
958
959         status = decode_op_hdr(xdr, OP_COPY);
960         if (status == NFS4ERR_OFFLOAD_NO_REQS) {
961                 status = decode_copy_requirements(xdr, res);
962                 if (status)
963                         return status;
964                 return NFS4ERR_OFFLOAD_NO_REQS;
965         } else if (status)
966                 return status;
967
968         status = decode_write_response(xdr, &res->write_res);
969         if (status)
970                 return status;
971
972         return decode_copy_requirements(xdr, res);
973 }
974
975 static int decode_offload_cancel(struct xdr_stream *xdr,
976                                  struct nfs42_offload_status_res *res)
977 {
978         return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);
979 }
980
981 static int decode_copy_notify(struct xdr_stream *xdr,
982                               struct nfs42_copy_notify_res *res)
983 {
984         __be32 *p;
985         int status, count;
986
987         status = decode_op_hdr(xdr, OP_COPY_NOTIFY);
988         if (status)
989                 return status;
990         /* cnr_lease_time */
991         p = xdr_inline_decode(xdr, 12);
992         if (unlikely(!p))
993                 return -EIO;
994         p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds);
995         res->cnr_lease_time.nseconds = be32_to_cpup(p);
996
997         status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE);
998         if (unlikely(status))
999                 return -EIO;
1000
1001         /* number of source addresses */
1002         p = xdr_inline_decode(xdr, 4);
1003         if (unlikely(!p))
1004                 return -EIO;
1005
1006         count = be32_to_cpup(p);
1007         if (count > 1)
1008                 pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n",
1009                          __func__, count);
1010
1011         status = decode_nl4_server(xdr, &res->cnr_src);
1012         if (unlikely(status))
1013                 return -EIO;
1014         return 0;
1015 }
1016
1017 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
1018 {
1019         return decode_op_hdr(xdr, OP_DEALLOCATE);
1020 }
1021
1022 static int decode_read_plus_data(struct xdr_stream *xdr, struct nfs_pgio_res *res,
1023                                  uint32_t *eof)
1024 {
1025         uint32_t count, recvd;
1026         uint64_t offset;
1027         __be32 *p;
1028
1029         p = xdr_inline_decode(xdr, 8 + 4);
1030         if (unlikely(!p))
1031                 return -EIO;
1032
1033         p = xdr_decode_hyper(p, &offset);
1034         count = be32_to_cpup(p);
1035         recvd = xdr_align_data(xdr, res->count, count);
1036         res->count += recvd;
1037
1038         if (count > recvd) {
1039                 dprintk("NFS: server cheating in read reply: "
1040                                 "count %u > recvd %u\n", count, recvd);
1041                 *eof = 0;
1042                 return 1;
1043         }
1044
1045         return 0;
1046 }
1047
1048 static int decode_read_plus_hole(struct xdr_stream *xdr, struct nfs_pgio_res *res,
1049                                  uint32_t *eof)
1050 {
1051         uint64_t offset, length, recvd;
1052         __be32 *p;
1053
1054         p = xdr_inline_decode(xdr, 8 + 8);
1055         if (unlikely(!p))
1056                 return -EIO;
1057
1058         p = xdr_decode_hyper(p, &offset);
1059         p = xdr_decode_hyper(p, &length);
1060         recvd = xdr_expand_hole(xdr, res->count, length);
1061         res->count += recvd;
1062
1063         if (recvd < length) {
1064                 *eof = 0;
1065                 return 1;
1066         }
1067         return 0;
1068 }
1069
1070 static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
1071 {
1072         uint32_t eof, segments, type;
1073         int status, i;
1074         __be32 *p;
1075
1076         status = decode_op_hdr(xdr, OP_READ_PLUS);
1077         if (status)
1078                 return status;
1079
1080         p = xdr_inline_decode(xdr, 4 + 4);
1081         if (unlikely(!p))
1082                 return -EIO;
1083
1084         eof = be32_to_cpup(p++);
1085         segments = be32_to_cpup(p++);
1086         if (segments == 0)
1087                 goto out;
1088
1089         for (i = 0; i < segments; i++) {
1090                 p = xdr_inline_decode(xdr, 4);
1091                 if (unlikely(!p))
1092                         return -EIO;
1093
1094                 type = be32_to_cpup(p++);
1095                 if (type == NFS4_CONTENT_DATA)
1096                         status = decode_read_plus_data(xdr, res, &eof);
1097                 else if (type == NFS4_CONTENT_HOLE)
1098                         status = decode_read_plus_hole(xdr, res, &eof);
1099                 else
1100                         return -EINVAL;
1101
1102                 if (status < 0)
1103                         return status;
1104                 if (status > 0)
1105                         break;
1106         }
1107
1108 out:
1109         res->eof = eof;
1110         return 0;
1111 }
1112
1113 static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
1114 {
1115         int status;
1116         __be32 *p;
1117
1118         status = decode_op_hdr(xdr, OP_SEEK);
1119         if (status)
1120                 return status;
1121
1122         p = xdr_inline_decode(xdr, 4 + 8);
1123         if (unlikely(!p))
1124                 return -EIO;
1125
1126         res->sr_eof = be32_to_cpup(p++);
1127         p = xdr_decode_hyper(p, &res->sr_offset);
1128         return 0;
1129 }
1130
1131 static int decode_layoutstats(struct xdr_stream *xdr)
1132 {
1133         return decode_op_hdr(xdr, OP_LAYOUTSTATS);
1134 }
1135
1136 static int decode_clone(struct xdr_stream *xdr)
1137 {
1138         return decode_op_hdr(xdr, OP_CLONE);
1139 }
1140
1141 static int decode_layouterror(struct xdr_stream *xdr)
1142 {
1143         return decode_op_hdr(xdr, OP_LAYOUTERROR);
1144 }
1145
1146 /*
1147  * Decode ALLOCATE request
1148  */
1149 static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
1150                                  struct xdr_stream *xdr,
1151                                  void *data)
1152 {
1153         struct nfs42_falloc_res *res = data;
1154         struct compound_hdr hdr;
1155         int status;
1156
1157         status = decode_compound_hdr(xdr, &hdr);
1158         if (status)
1159                 goto out;
1160         status = decode_sequence(xdr, &res->seq_res, rqstp);
1161         if (status)
1162                 goto out;
1163         status = decode_putfh(xdr);
1164         if (status)
1165                 goto out;
1166         status = decode_allocate(xdr, res);
1167         if (status)
1168                 goto out;
1169         decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
1170 out:
1171         return status;
1172 }
1173
1174 /*
1175  * Decode COPY response
1176  */
1177 static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp,
1178                              struct xdr_stream *xdr,
1179                              void *data)
1180 {
1181         struct nfs42_copy_res *res = data;
1182         struct compound_hdr hdr;
1183         int status;
1184
1185         status = decode_compound_hdr(xdr, &hdr);
1186         if (status)
1187                 goto out;
1188         status = decode_sequence(xdr, &res->seq_res, rqstp);
1189         if (status)
1190                 goto out;
1191         status = decode_putfh(xdr);
1192         if (status)
1193                 goto out;
1194         status = decode_savefh(xdr);
1195         if (status)
1196                 goto out;
1197         status = decode_putfh(xdr);
1198         if (status)
1199                 goto out;
1200         status = decode_copy(xdr, res);
1201         if (status)
1202                 goto out;
1203         if (res->commit_res.verf)
1204                 status = decode_commit(xdr, &res->commit_res);
1205 out:
1206         return status;
1207 }
1208
1209 /*
1210  * Decode OFFLOAD_CANCEL response
1211  */
1212 static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp,
1213                                        struct xdr_stream *xdr,
1214                                        void *data)
1215 {
1216         struct nfs42_offload_status_res *res = data;
1217         struct compound_hdr hdr;
1218         int status;
1219
1220         status = decode_compound_hdr(xdr, &hdr);
1221         if (status)
1222                 goto out;
1223         status = decode_sequence(xdr, &res->osr_seq_res, rqstp);
1224         if (status)
1225                 goto out;
1226         status = decode_putfh(xdr);
1227         if (status)
1228                 goto out;
1229         status = decode_offload_cancel(xdr, res);
1230
1231 out:
1232         return status;
1233 }
1234
1235 /*
1236  * Decode COPY_NOTIFY response
1237  */
1238 static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp,
1239                                     struct xdr_stream *xdr,
1240                                     void *data)
1241 {
1242         struct nfs42_copy_notify_res *res = data;
1243         struct compound_hdr hdr;
1244         int status;
1245
1246         status = decode_compound_hdr(xdr, &hdr);
1247         if (status)
1248                 goto out;
1249         status = decode_sequence(xdr, &res->cnr_seq_res, rqstp);
1250         if (status)
1251                 goto out;
1252         status = decode_putfh(xdr);
1253         if (status)
1254                 goto out;
1255         status = decode_copy_notify(xdr, res);
1256
1257 out:
1258         return status;
1259 }
1260
1261 /*
1262  * Decode DEALLOCATE request
1263  */
1264 static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
1265                                    struct xdr_stream *xdr,
1266                                    void *data)
1267 {
1268         struct nfs42_falloc_res *res = data;
1269         struct compound_hdr hdr;
1270         int status;
1271
1272         status = decode_compound_hdr(xdr, &hdr);
1273         if (status)
1274                 goto out;
1275         status = decode_sequence(xdr, &res->seq_res, rqstp);
1276         if (status)
1277                 goto out;
1278         status = decode_putfh(xdr);
1279         if (status)
1280                 goto out;
1281         status = decode_deallocate(xdr, res);
1282         if (status)
1283                 goto out;
1284         decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
1285 out:
1286         return status;
1287 }
1288
1289 /*
1290  * Decode READ_PLUS request
1291  */
1292 static int nfs4_xdr_dec_read_plus(struct rpc_rqst *rqstp,
1293                                   struct xdr_stream *xdr,
1294                                   void *data)
1295 {
1296         struct nfs_pgio_res *res = data;
1297         struct compound_hdr hdr;
1298         int status;
1299
1300         status = decode_compound_hdr(xdr, &hdr);
1301         if (status)
1302                 goto out;
1303         status = decode_sequence(xdr, &res->seq_res, rqstp);
1304         if (status)
1305                 goto out;
1306         status = decode_putfh(xdr);
1307         if (status)
1308                 goto out;
1309         status = decode_read_plus(xdr, res);
1310         if (!status)
1311                 status = res->count;
1312 out:
1313         return status;
1314 }
1315
1316 /*
1317  * Decode SEEK request
1318  */
1319 static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
1320                              struct xdr_stream *xdr,
1321                              void *data)
1322 {
1323         struct nfs42_seek_res *res = data;
1324         struct compound_hdr hdr;
1325         int status;
1326
1327         status = decode_compound_hdr(xdr, &hdr);
1328         if (status)
1329                 goto out;
1330         status = decode_sequence(xdr, &res->seq_res, rqstp);
1331         if (status)
1332                 goto out;
1333         status = decode_putfh(xdr);
1334         if (status)
1335                 goto out;
1336         status = decode_seek(xdr, res);
1337 out:
1338         return status;
1339 }
1340
1341 /*
1342  * Decode LAYOUTSTATS request
1343  */
1344 static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp,
1345                                     struct xdr_stream *xdr,
1346                                     void *data)
1347 {
1348         struct nfs42_layoutstat_res *res = data;
1349         struct compound_hdr hdr;
1350         int status, i;
1351
1352         status = decode_compound_hdr(xdr, &hdr);
1353         if (status)
1354                 goto out;
1355         status = decode_sequence(xdr, &res->seq_res, rqstp);
1356         if (status)
1357                 goto out;
1358         status = decode_putfh(xdr);
1359         if (status)
1360                 goto out;
1361         WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
1362         for (i = 0; i < res->num_dev; i++) {
1363                 status = decode_layoutstats(xdr);
1364                 if (status)
1365                         goto out;
1366         }
1367 out:
1368         res->rpc_status = status;
1369         return status;
1370 }
1371
1372 /*
1373  * Decode CLONE request
1374  */
1375 static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp,
1376                               struct xdr_stream *xdr,
1377                               void *data)
1378 {
1379         struct nfs42_clone_res *res = data;
1380         struct compound_hdr hdr;
1381         int status;
1382
1383         status = decode_compound_hdr(xdr, &hdr);
1384         if (status)
1385                 goto out;
1386         status = decode_sequence(xdr, &res->seq_res, rqstp);
1387         if (status)
1388                 goto out;
1389         status = decode_putfh(xdr);
1390         if (status)
1391                 goto out;
1392         status = decode_savefh(xdr);
1393         if (status)
1394                 goto out;
1395         status = decode_putfh(xdr);
1396         if (status)
1397                 goto out;
1398         status = decode_clone(xdr);
1399         if (status)
1400                 goto out;
1401         status = decode_getfattr(xdr, res->dst_fattr, res->server);
1402
1403 out:
1404         res->rpc_status = status;
1405         return status;
1406 }
1407
1408 /*
1409  * Decode LAYOUTERROR request
1410  */
1411 static int nfs4_xdr_dec_layouterror(struct rpc_rqst *rqstp,
1412                                     struct xdr_stream *xdr,
1413                                     void *data)
1414 {
1415         struct nfs42_layouterror_res *res = data;
1416         struct compound_hdr hdr;
1417         int status, i;
1418
1419         status = decode_compound_hdr(xdr, &hdr);
1420         if (status)
1421                 goto out;
1422         status = decode_sequence(xdr, &res->seq_res, rqstp);
1423         if (status)
1424                 goto out;
1425         status = decode_putfh(xdr);
1426
1427         for (i = 0; i < res->num_errors && status == 0; i++)
1428                 status = decode_layouterror(xdr);
1429 out:
1430         res->rpc_status = status;
1431         return status;
1432 }
1433
1434 #ifdef CONFIG_NFS_V4_2
1435 static void nfs4_xdr_enc_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
1436                                   const void *data)
1437 {
1438         const struct nfs42_setxattrargs *args = data;
1439         struct compound_hdr hdr = {
1440                 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1441         };
1442
1443         encode_compound_hdr(xdr, req, &hdr);
1444         encode_sequence(xdr, &args->seq_args, &hdr);
1445         encode_putfh(xdr, args->fh, &hdr);
1446         encode_setxattr(xdr, args, &hdr);
1447         encode_nops(&hdr);
1448 }
1449
1450 static int nfs4_xdr_dec_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
1451                                  void *data)
1452 {
1453         struct nfs42_setxattrres *res = data;
1454         struct compound_hdr hdr;
1455         int status;
1456
1457         status = decode_compound_hdr(xdr, &hdr);
1458         if (status)
1459                 goto out;
1460         status = decode_sequence(xdr, &res->seq_res, req);
1461         if (status)
1462                 goto out;
1463         status = decode_putfh(xdr);
1464         if (status)
1465                 goto out;
1466
1467         status = decode_setxattr(xdr, &res->cinfo);
1468 out:
1469         return status;
1470 }
1471
1472 static void nfs4_xdr_enc_getxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
1473                                   const void *data)
1474 {
1475         const struct nfs42_getxattrargs *args = data;
1476         struct compound_hdr hdr = {
1477                 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1478         };
1479         size_t plen;
1480
1481         encode_compound_hdr(xdr, req, &hdr);
1482         encode_sequence(xdr, &args->seq_args, &hdr);
1483         encode_putfh(xdr, args->fh, &hdr);
1484         encode_getxattr(xdr, args->xattr_name, &hdr);
1485
1486         plen = args->xattr_len ? args->xattr_len : XATTR_SIZE_MAX;
1487
1488         rpc_prepare_reply_pages(req, args->xattr_pages, 0, plen,
1489             hdr.replen);
1490         req->rq_rcv_buf.flags |= XDRBUF_SPARSE_PAGES;
1491
1492         encode_nops(&hdr);
1493 }
1494
1495 static int nfs4_xdr_dec_getxattr(struct rpc_rqst *rqstp,
1496                                  struct xdr_stream *xdr, void *data)
1497 {
1498         struct nfs42_getxattrres *res = data;
1499         struct compound_hdr hdr;
1500         int status;
1501
1502         status = decode_compound_hdr(xdr, &hdr);
1503         if (status)
1504                 goto out;
1505         status = decode_sequence(xdr, &res->seq_res, rqstp);
1506         if (status)
1507                 goto out;
1508         status = decode_putfh(xdr);
1509         if (status)
1510                 goto out;
1511         status = decode_getxattr(xdr, res, rqstp);
1512 out:
1513         return status;
1514 }
1515
1516 static void nfs4_xdr_enc_listxattrs(struct rpc_rqst *req,
1517                                     struct xdr_stream *xdr, const void *data)
1518 {
1519         const struct nfs42_listxattrsargs *args = data;
1520         struct compound_hdr hdr = {
1521                 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1522         };
1523
1524         encode_compound_hdr(xdr, req, &hdr);
1525         encode_sequence(xdr, &args->seq_args, &hdr);
1526         encode_putfh(xdr, args->fh, &hdr);
1527         encode_listxattrs(xdr, args, &hdr);
1528
1529         rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->count,
1530             hdr.replen);
1531
1532         encode_nops(&hdr);
1533 }
1534
1535 static int nfs4_xdr_dec_listxattrs(struct rpc_rqst *rqstp,
1536                                    struct xdr_stream *xdr, void *data)
1537 {
1538         struct nfs42_listxattrsres *res = data;
1539         struct compound_hdr hdr;
1540         int status;
1541
1542         xdr_set_scratch_page(xdr, res->scratch);
1543
1544         status = decode_compound_hdr(xdr, &hdr);
1545         if (status)
1546                 goto out;
1547         status = decode_sequence(xdr, &res->seq_res, rqstp);
1548         if (status)
1549                 goto out;
1550         status = decode_putfh(xdr);
1551         if (status)
1552                 goto out;
1553         status = decode_listxattrs(xdr, res);
1554 out:
1555         return status;
1556 }
1557
1558 static void nfs4_xdr_enc_removexattr(struct rpc_rqst *req,
1559                                      struct xdr_stream *xdr, const void *data)
1560 {
1561         const struct nfs42_removexattrargs *args = data;
1562         struct compound_hdr hdr = {
1563                 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1564         };
1565
1566         encode_compound_hdr(xdr, req, &hdr);
1567         encode_sequence(xdr, &args->seq_args, &hdr);
1568         encode_putfh(xdr, args->fh, &hdr);
1569         encode_removexattr(xdr, args->xattr_name, &hdr);
1570         encode_nops(&hdr);
1571 }
1572
1573 static int nfs4_xdr_dec_removexattr(struct rpc_rqst *req,
1574                                     struct xdr_stream *xdr, void *data)
1575 {
1576         struct nfs42_removexattrres *res = data;
1577         struct compound_hdr hdr;
1578         int status;
1579
1580         status = decode_compound_hdr(xdr, &hdr);
1581         if (status)
1582                 goto out;
1583         status = decode_sequence(xdr, &res->seq_res, req);
1584         if (status)
1585                 goto out;
1586         status = decode_putfh(xdr);
1587         if (status)
1588                 goto out;
1589
1590         status = decode_removexattr(xdr, &res->cinfo);
1591 out:
1592         return status;
1593 }
1594 #endif
1595 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */