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