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