]> Git Repo - J-linux.git/blob - fs/nfs/nfs3xdr.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / fs / nfs / nfs3xdr.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * linux/fs/nfs/nfs3xdr.c
4  *
5  * XDR functions to encode/decode NFSv3 RPC arguments and results.
6  *
7  * Copyright (C) 1996, 1997 Olaf Kirch
8  */
9
10 #include <linux/param.h>
11 #include <linux/time.h>
12 #include <linux/mm.h>
13 #include <linux/errno.h>
14 #include <linux/string.h>
15 #include <linux/in.h>
16 #include <linux/pagemap.h>
17 #include <linux/proc_fs.h>
18 #include <linux/kdev_t.h>
19 #include <linux/sunrpc/clnt.h>
20 #include <linux/nfs.h>
21 #include <linux/nfs3.h>
22 #include <linux/nfs_fs.h>
23 #include <linux/nfsacl.h>
24 #include <linux/nfs_common.h>
25
26 #include "nfstrace.h"
27 #include "internal.h"
28
29 #define NFSDBG_FACILITY         NFSDBG_XDR
30
31 /*
32  * Declare the space requirements for NFS arguments and replies as
33  * number of 32bit-words
34  */
35 #define NFS3_pagepad_sz         (1) /* Page padding */
36 #define NFS3_fhandle_sz         (1+16)
37 #define NFS3_fh_sz              (NFS3_fhandle_sz)       /* shorthand */
38 #define NFS3_post_op_fh_sz      (1+NFS3_fh_sz)
39 #define NFS3_sattr_sz           (15)
40 #define NFS3_filename_sz        (1+(NFS3_MAXNAMLEN>>2))
41 #define NFS3_path_sz            (1+(NFS3_MAXPATHLEN>>2))
42 #define NFS3_fattr_sz           (21)
43 #define NFS3_cookieverf_sz      (NFS3_COOKIEVERFSIZE>>2)
44 #define NFS3_wcc_attr_sz        (6)
45 #define NFS3_pre_op_attr_sz     (1+NFS3_wcc_attr_sz)
46 #define NFS3_post_op_attr_sz    (1+NFS3_fattr_sz)
47 #define NFS3_wcc_data_sz        (NFS3_pre_op_attr_sz+NFS3_post_op_attr_sz)
48 #define NFS3_diropargs_sz       (NFS3_fh_sz+NFS3_filename_sz)
49
50 #define NFS3_getattrargs_sz     (NFS3_fh_sz)
51 #define NFS3_setattrargs_sz     (NFS3_fh_sz+NFS3_sattr_sz+3)
52 #define NFS3_lookupargs_sz      (NFS3_fh_sz+NFS3_filename_sz)
53 #define NFS3_accessargs_sz      (NFS3_fh_sz+1)
54 #define NFS3_readlinkargs_sz    (NFS3_fh_sz)
55 #define NFS3_readargs_sz        (NFS3_fh_sz+3)
56 #define NFS3_writeargs_sz       (NFS3_fh_sz+5)
57 #define NFS3_createargs_sz      (NFS3_diropargs_sz+NFS3_sattr_sz)
58 #define NFS3_mkdirargs_sz       (NFS3_diropargs_sz+NFS3_sattr_sz)
59 #define NFS3_symlinkargs_sz     (NFS3_diropargs_sz+1+NFS3_sattr_sz)
60 #define NFS3_mknodargs_sz       (NFS3_diropargs_sz+2+NFS3_sattr_sz)
61 #define NFS3_removeargs_sz      (NFS3_fh_sz+NFS3_filename_sz)
62 #define NFS3_renameargs_sz      (NFS3_diropargs_sz+NFS3_diropargs_sz)
63 #define NFS3_linkargs_sz                (NFS3_fh_sz+NFS3_diropargs_sz)
64 #define NFS3_readdirargs_sz     (NFS3_fh_sz+NFS3_cookieverf_sz+3)
65 #define NFS3_readdirplusargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+4)
66 #define NFS3_commitargs_sz      (NFS3_fh_sz+3)
67
68 #define NFS3_getattrres_sz      (1+NFS3_fattr_sz)
69 #define NFS3_setattrres_sz      (1+NFS3_wcc_data_sz)
70 #define NFS3_removeres_sz       (NFS3_setattrres_sz)
71 #define NFS3_lookupres_sz       (1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz))
72 #define NFS3_accessres_sz       (1+NFS3_post_op_attr_sz+1)
73 #define NFS3_readlinkres_sz     (1+NFS3_post_op_attr_sz+1+NFS3_pagepad_sz)
74 #define NFS3_readres_sz         (1+NFS3_post_op_attr_sz+3+NFS3_pagepad_sz)
75 #define NFS3_writeres_sz        (1+NFS3_wcc_data_sz+4)
76 #define NFS3_createres_sz       (1+NFS3_post_op_fh_sz+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
77 #define NFS3_renameres_sz       (1+(2 * NFS3_wcc_data_sz))
78 #define NFS3_linkres_sz         (1+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
79 #define NFS3_readdirres_sz      (1+NFS3_post_op_attr_sz+2+NFS3_pagepad_sz)
80 #define NFS3_fsstatres_sz       (1+NFS3_post_op_attr_sz+13)
81 #define NFS3_fsinfores_sz       (1+NFS3_post_op_attr_sz+12)
82 #define NFS3_pathconfres_sz     (1+NFS3_post_op_attr_sz+6)
83 #define NFS3_commitres_sz       (1+NFS3_wcc_data_sz+2)
84
85 #define ACL3_getaclargs_sz      (NFS3_fh_sz+1)
86 #define ACL3_setaclargs_sz      (NFS3_fh_sz+1+ \
87                                 XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
88 #define ACL3_getaclres_sz       (1+NFS3_post_op_attr_sz+1+ \
89                                 XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)+\
90                                 NFS3_pagepad_sz)
91 #define ACL3_setaclres_sz       (1+NFS3_post_op_attr_sz)
92
93 /*
94  * Map file type to S_IFMT bits
95  */
96 static const umode_t nfs_type2fmt[] = {
97         [NF3BAD] = 0,
98         [NF3REG] = S_IFREG,
99         [NF3DIR] = S_IFDIR,
100         [NF3BLK] = S_IFBLK,
101         [NF3CHR] = S_IFCHR,
102         [NF3LNK] = S_IFLNK,
103         [NF3SOCK] = S_IFSOCK,
104         [NF3FIFO] = S_IFIFO,
105 };
106
107 static struct user_namespace *rpc_userns(const struct rpc_clnt *clnt)
108 {
109         if (clnt && clnt->cl_cred)
110                 return clnt->cl_cred->user_ns;
111         return &init_user_ns;
112 }
113
114 static struct user_namespace *rpc_rqst_userns(const struct rpc_rqst *rqstp)
115 {
116         if (rqstp->rq_task)
117                 return rpc_userns(rqstp->rq_task->tk_client);
118         return &init_user_ns;
119 }
120
121 /*
122  * Encode/decode NFSv3 basic data types
123  *
124  * Basic NFSv3 data types are defined in section 2.5 of RFC 1813:
125  * "NFS Version 3 Protocol Specification".
126  *
127  * Not all basic data types have their own encoding and decoding
128  * functions.  For run-time efficiency, some data types are encoded
129  * or decoded inline.
130  */
131
132 static void encode_uint32(struct xdr_stream *xdr, u32 value)
133 {
134         __be32 *p = xdr_reserve_space(xdr, 4);
135         *p = cpu_to_be32(value);
136 }
137
138 static int decode_uint32(struct xdr_stream *xdr, u32 *value)
139 {
140         __be32 *p;
141
142         p = xdr_inline_decode(xdr, 4);
143         if (unlikely(!p))
144                 return -EIO;
145         *value = be32_to_cpup(p);
146         return 0;
147 }
148
149 static int decode_uint64(struct xdr_stream *xdr, u64 *value)
150 {
151         __be32 *p;
152
153         p = xdr_inline_decode(xdr, 8);
154         if (unlikely(!p))
155                 return -EIO;
156         xdr_decode_hyper(p, value);
157         return 0;
158 }
159
160 /*
161  * fileid3
162  *
163  *      typedef uint64 fileid3;
164  */
165 static __be32 *xdr_decode_fileid3(__be32 *p, u64 *fileid)
166 {
167         return xdr_decode_hyper(p, fileid);
168 }
169
170 static int decode_fileid3(struct xdr_stream *xdr, u64 *fileid)
171 {
172         return decode_uint64(xdr, fileid);
173 }
174
175 /*
176  * filename3
177  *
178  *      typedef string filename3<>;
179  */
180 static void encode_filename3(struct xdr_stream *xdr,
181                              const char *name, u32 length)
182 {
183         __be32 *p;
184
185         WARN_ON_ONCE(length > NFS3_MAXNAMLEN);
186         p = xdr_reserve_space(xdr, 4 + length);
187         xdr_encode_opaque(p, name, length);
188 }
189
190 static int decode_inline_filename3(struct xdr_stream *xdr,
191                                    const char **name, u32 *length)
192 {
193         __be32 *p;
194         u32 count;
195
196         p = xdr_inline_decode(xdr, 4);
197         if (unlikely(!p))
198                 return -EIO;
199         count = be32_to_cpup(p);
200         if (count > NFS3_MAXNAMLEN)
201                 goto out_nametoolong;
202         p = xdr_inline_decode(xdr, count);
203         if (unlikely(!p))
204                 return -EIO;
205         *name = (const char *)p;
206         *length = count;
207         return 0;
208
209 out_nametoolong:
210         dprintk("NFS: returned filename too long: %u\n", count);
211         return -ENAMETOOLONG;
212 }
213
214 /*
215  * nfspath3
216  *
217  *      typedef string nfspath3<>;
218  */
219 static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages,
220                             const u32 length)
221 {
222         encode_uint32(xdr, length);
223         xdr_write_pages(xdr, pages, 0, length);
224 }
225
226 static int decode_nfspath3(struct xdr_stream *xdr)
227 {
228         u32 recvd, count;
229         __be32 *p;
230
231         p = xdr_inline_decode(xdr, 4);
232         if (unlikely(!p))
233                 return -EIO;
234         count = be32_to_cpup(p);
235         if (unlikely(count >= xdr->buf->page_len || count > NFS3_MAXPATHLEN))
236                 goto out_nametoolong;
237         recvd = xdr_read_pages(xdr, count);
238         if (unlikely(count > recvd))
239                 goto out_cheating;
240         xdr_terminate_string(xdr->buf, count);
241         return 0;
242
243 out_nametoolong:
244         dprintk("NFS: returned pathname too long: %u\n", count);
245         return -ENAMETOOLONG;
246 out_cheating:
247         dprintk("NFS: server cheating in pathname result: "
248                 "count %u > recvd %u\n", count, recvd);
249         return -EIO;
250 }
251
252 /*
253  * cookie3
254  *
255  *      typedef uint64 cookie3
256  */
257 static __be32 *xdr_encode_cookie3(__be32 *p, u64 cookie)
258 {
259         return xdr_encode_hyper(p, cookie);
260 }
261
262 static int decode_cookie3(struct xdr_stream *xdr, u64 *cookie)
263 {
264         return decode_uint64(xdr, cookie);
265 }
266
267 /*
268  * cookieverf3
269  *
270  *      typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
271  */
272 static __be32 *xdr_encode_cookieverf3(__be32 *p, const __be32 *verifier)
273 {
274         memcpy(p, verifier, NFS3_COOKIEVERFSIZE);
275         return p + XDR_QUADLEN(NFS3_COOKIEVERFSIZE);
276 }
277
278 static int decode_cookieverf3(struct xdr_stream *xdr, __be32 *verifier)
279 {
280         __be32 *p;
281
282         p = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE);
283         if (unlikely(!p))
284                 return -EIO;
285         memcpy(verifier, p, NFS3_COOKIEVERFSIZE);
286         return 0;
287 }
288
289 /*
290  * createverf3
291  *
292  *      typedef opaque createverf3[NFS3_CREATEVERFSIZE];
293  */
294 static void encode_createverf3(struct xdr_stream *xdr, const __be32 *verifier)
295 {
296         __be32 *p;
297
298         p = xdr_reserve_space(xdr, NFS3_CREATEVERFSIZE);
299         memcpy(p, verifier, NFS3_CREATEVERFSIZE);
300 }
301
302 static int decode_writeverf3(struct xdr_stream *xdr, struct nfs_write_verifier *verifier)
303 {
304         __be32 *p;
305
306         p = xdr_inline_decode(xdr, NFS3_WRITEVERFSIZE);
307         if (unlikely(!p))
308                 return -EIO;
309         memcpy(verifier->data, p, NFS3_WRITEVERFSIZE);
310         return 0;
311 }
312
313 /*
314  * size3
315  *
316  *      typedef uint64 size3;
317  */
318 static __be32 *xdr_decode_size3(__be32 *p, u64 *size)
319 {
320         return xdr_decode_hyper(p, size);
321 }
322
323 /*
324  * nfsstat3
325  *
326  *      enum nfsstat3 {
327  *              NFS3_OK = 0,
328  *              ...
329  *      }
330  */
331 #define NFS3_OK         NFS_OK
332
333 static int decode_nfsstat3(struct xdr_stream *xdr, enum nfs_stat *status)
334 {
335         __be32 *p;
336
337         p = xdr_inline_decode(xdr, 4);
338         if (unlikely(!p))
339                 return -EIO;
340         if (unlikely(*p != cpu_to_be32(NFS3_OK)))
341                 goto out_status;
342         *status = 0;
343         return 0;
344 out_status:
345         *status = be32_to_cpup(p);
346         trace_nfs_xdr_status(xdr, (int)*status);
347         return 0;
348 }
349
350 /*
351  * ftype3
352  *
353  *      enum ftype3 {
354  *              NF3REG  = 1,
355  *              NF3DIR  = 2,
356  *              NF3BLK  = 3,
357  *              NF3CHR  = 4,
358  *              NF3LNK  = 5,
359  *              NF3SOCK = 6,
360  *              NF3FIFO = 7
361  *      };
362  */
363 static void encode_ftype3(struct xdr_stream *xdr, const u32 type)
364 {
365         encode_uint32(xdr, type);
366 }
367
368 static __be32 *xdr_decode_ftype3(__be32 *p, umode_t *mode)
369 {
370         u32 type;
371
372         type = be32_to_cpup(p++);
373         if (type > NF3FIFO)
374                 type = NF3NON;
375         *mode = nfs_type2fmt[type];
376         return p;
377 }
378
379 /*
380  * specdata3
381  *
382  *     struct specdata3 {
383  *             uint32  specdata1;
384  *             uint32  specdata2;
385  *     };
386  */
387 static void encode_specdata3(struct xdr_stream *xdr, const dev_t rdev)
388 {
389         __be32 *p;
390
391         p = xdr_reserve_space(xdr, 8);
392         *p++ = cpu_to_be32(MAJOR(rdev));
393         *p = cpu_to_be32(MINOR(rdev));
394 }
395
396 static __be32 *xdr_decode_specdata3(__be32 *p, dev_t *rdev)
397 {
398         unsigned int major, minor;
399
400         major = be32_to_cpup(p++);
401         minor = be32_to_cpup(p++);
402         *rdev = MKDEV(major, minor);
403         if (MAJOR(*rdev) != major || MINOR(*rdev) != minor)
404                 *rdev = 0;
405         return p;
406 }
407
408 /*
409  * nfs_fh3
410  *
411  *      struct nfs_fh3 {
412  *              opaque       data<NFS3_FHSIZE>;
413  *      };
414  */
415 static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh)
416 {
417         __be32 *p;
418
419         WARN_ON_ONCE(fh->size > NFS3_FHSIZE);
420         p = xdr_reserve_space(xdr, 4 + fh->size);
421         xdr_encode_opaque(p, fh->data, fh->size);
422 }
423
424 static int decode_nfs_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
425 {
426         u32 length;
427         __be32 *p;
428
429         p = xdr_inline_decode(xdr, 4);
430         if (unlikely(!p))
431                 return -EIO;
432         length = be32_to_cpup(p++);
433         if (unlikely(length > NFS3_FHSIZE || length == 0))
434                 goto out_toobig;
435         p = xdr_inline_decode(xdr, length);
436         if (unlikely(!p))
437                 return -EIO;
438         fh->size = length;
439         memcpy(fh->data, p, length);
440         return 0;
441 out_toobig:
442         trace_nfs_xdr_bad_filehandle(xdr, NFSERR_BADHANDLE);
443         return -E2BIG;
444 }
445
446 static void zero_nfs_fh3(struct nfs_fh *fh)
447 {
448         memset(fh, 0, sizeof(*fh));
449 }
450
451 /*
452  * nfstime3
453  *
454  *      struct nfstime3 {
455  *              uint32  seconds;
456  *              uint32  nseconds;
457  *      };
458  */
459 static __be32 *xdr_encode_nfstime3(__be32 *p, const struct timespec64 *timep)
460 {
461         *p++ = cpu_to_be32((u32)timep->tv_sec);
462         *p++ = cpu_to_be32(timep->tv_nsec);
463         return p;
464 }
465
466 static __be32 *xdr_decode_nfstime3(__be32 *p, struct timespec64 *timep)
467 {
468         timep->tv_sec = be32_to_cpup(p++);
469         timep->tv_nsec = be32_to_cpup(p++);
470         return p;
471 }
472
473 /*
474  * sattr3
475  *
476  *      enum time_how {
477  *              DONT_CHANGE             = 0,
478  *              SET_TO_SERVER_TIME      = 1,
479  *              SET_TO_CLIENT_TIME      = 2
480  *      };
481  *
482  *      union set_mode3 switch (bool set_it) {
483  *      case TRUE:
484  *              mode3   mode;
485  *      default:
486  *              void;
487  *      };
488  *
489  *      union set_uid3 switch (bool set_it) {
490  *      case TRUE:
491  *              uid3    uid;
492  *      default:
493  *              void;
494  *      };
495  *
496  *      union set_gid3 switch (bool set_it) {
497  *      case TRUE:
498  *              gid3    gid;
499  *      default:
500  *              void;
501  *      };
502  *
503  *      union set_size3 switch (bool set_it) {
504  *      case TRUE:
505  *              size3   size;
506  *      default:
507  *              void;
508  *      };
509  *
510  *      union set_atime switch (time_how set_it) {
511  *      case SET_TO_CLIENT_TIME:
512  *              nfstime3        atime;
513  *      default:
514  *              void;
515  *      };
516  *
517  *      union set_mtime switch (time_how set_it) {
518  *      case SET_TO_CLIENT_TIME:
519  *              nfstime3  mtime;
520  *      default:
521  *              void;
522  *      };
523  *
524  *      struct sattr3 {
525  *              set_mode3       mode;
526  *              set_uid3        uid;
527  *              set_gid3        gid;
528  *              set_size3       size;
529  *              set_atime       atime;
530  *              set_mtime       mtime;
531  *      };
532  */
533 static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr,
534                 struct user_namespace *userns)
535 {
536         u32 nbytes;
537         __be32 *p;
538
539         /*
540          * In order to make only a single xdr_reserve_space() call,
541          * pre-compute the total number of bytes to be reserved.
542          * Six boolean values, one for each set_foo field, are always
543          * present in the encoded result, so start there.
544          */
545         nbytes = 6 * 4;
546         if (attr->ia_valid & ATTR_MODE)
547                 nbytes += 4;
548         if (attr->ia_valid & ATTR_UID)
549                 nbytes += 4;
550         if (attr->ia_valid & ATTR_GID)
551                 nbytes += 4;
552         if (attr->ia_valid & ATTR_SIZE)
553                 nbytes += 8;
554         if (attr->ia_valid & ATTR_ATIME_SET)
555                 nbytes += 8;
556         if (attr->ia_valid & ATTR_MTIME_SET)
557                 nbytes += 8;
558         p = xdr_reserve_space(xdr, nbytes);
559
560         if (attr->ia_valid & ATTR_MODE) {
561                 *p++ = xdr_one;
562                 *p++ = cpu_to_be32(attr->ia_mode & S_IALLUGO);
563         } else
564                 *p++ = xdr_zero;
565
566         if (attr->ia_valid & ATTR_UID) {
567                 *p++ = xdr_one;
568                 *p++ = cpu_to_be32(from_kuid_munged(userns, attr->ia_uid));
569         } else
570                 *p++ = xdr_zero;
571
572         if (attr->ia_valid & ATTR_GID) {
573                 *p++ = xdr_one;
574                 *p++ = cpu_to_be32(from_kgid_munged(userns, attr->ia_gid));
575         } else
576                 *p++ = xdr_zero;
577
578         if (attr->ia_valid & ATTR_SIZE) {
579                 *p++ = xdr_one;
580                 p = xdr_encode_hyper(p, (u64)attr->ia_size);
581         } else
582                 *p++ = xdr_zero;
583
584         if (attr->ia_valid & ATTR_ATIME_SET) {
585                 *p++ = xdr_two;
586                 p = xdr_encode_nfstime3(p, &attr->ia_atime);
587         } else if (attr->ia_valid & ATTR_ATIME) {
588                 *p++ = xdr_one;
589         } else
590                 *p++ = xdr_zero;
591
592         if (attr->ia_valid & ATTR_MTIME_SET) {
593                 *p++ = xdr_two;
594                 xdr_encode_nfstime3(p, &attr->ia_mtime);
595         } else if (attr->ia_valid & ATTR_MTIME) {
596                 *p = xdr_one;
597         } else
598                 *p = xdr_zero;
599 }
600
601 /*
602  * fattr3
603  *
604  *      struct fattr3 {
605  *              ftype3          type;
606  *              mode3           mode;
607  *              uint32          nlink;
608  *              uid3            uid;
609  *              gid3            gid;
610  *              size3           size;
611  *              size3           used;
612  *              specdata3       rdev;
613  *              uint64          fsid;
614  *              fileid3         fileid;
615  *              nfstime3        atime;
616  *              nfstime3        mtime;
617  *              nfstime3        ctime;
618  *      };
619  */
620 static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr,
621                 struct user_namespace *userns)
622 {
623         umode_t fmode;
624         __be32 *p;
625
626         p = xdr_inline_decode(xdr, NFS3_fattr_sz << 2);
627         if (unlikely(!p))
628                 return -EIO;
629
630         p = xdr_decode_ftype3(p, &fmode);
631
632         fattr->mode = (be32_to_cpup(p++) & ~S_IFMT) | fmode;
633         fattr->nlink = be32_to_cpup(p++);
634         fattr->uid = make_kuid(userns, be32_to_cpup(p++));
635         if (!uid_valid(fattr->uid))
636                 goto out_uid;
637         fattr->gid = make_kgid(userns, be32_to_cpup(p++));
638         if (!gid_valid(fattr->gid))
639                 goto out_gid;
640
641         p = xdr_decode_size3(p, &fattr->size);
642         p = xdr_decode_size3(p, &fattr->du.nfs3.used);
643         p = xdr_decode_specdata3(p, &fattr->rdev);
644
645         p = xdr_decode_hyper(p, &fattr->fsid.major);
646         fattr->fsid.minor = 0;
647
648         p = xdr_decode_fileid3(p, &fattr->fileid);
649         p = xdr_decode_nfstime3(p, &fattr->atime);
650         p = xdr_decode_nfstime3(p, &fattr->mtime);
651         xdr_decode_nfstime3(p, &fattr->ctime);
652         fattr->change_attr = nfs_timespec_to_change_attr(&fattr->ctime);
653
654         fattr->valid |= NFS_ATTR_FATTR_V3;
655         return 0;
656 out_uid:
657         dprintk("NFS: returned invalid uid\n");
658         return -EINVAL;
659 out_gid:
660         dprintk("NFS: returned invalid gid\n");
661         return -EINVAL;
662 }
663
664 /*
665  * post_op_attr
666  *
667  *      union post_op_attr switch (bool attributes_follow) {
668  *      case TRUE:
669  *              fattr3  attributes;
670  *      case FALSE:
671  *              void;
672  *      };
673  */
674 static int decode_post_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
675                 struct user_namespace *userns)
676 {
677         __be32 *p;
678
679         p = xdr_inline_decode(xdr, 4);
680         if (unlikely(!p))
681                 return -EIO;
682         if (*p != xdr_zero)
683                 return decode_fattr3(xdr, fattr, userns);
684         return 0;
685 }
686
687 /*
688  * wcc_attr
689  *      struct wcc_attr {
690  *              size3           size;
691  *              nfstime3        mtime;
692  *              nfstime3        ctime;
693  *      };
694  */
695 static int decode_wcc_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
696 {
697         __be32 *p;
698
699         p = xdr_inline_decode(xdr, NFS3_wcc_attr_sz << 2);
700         if (unlikely(!p))
701                 return -EIO;
702
703         fattr->valid |= NFS_ATTR_FATTR_PRESIZE
704                 | NFS_ATTR_FATTR_PRECHANGE
705                 | NFS_ATTR_FATTR_PREMTIME
706                 | NFS_ATTR_FATTR_PRECTIME;
707
708         p = xdr_decode_size3(p, &fattr->pre_size);
709         p = xdr_decode_nfstime3(p, &fattr->pre_mtime);
710         xdr_decode_nfstime3(p, &fattr->pre_ctime);
711         fattr->pre_change_attr = nfs_timespec_to_change_attr(&fattr->pre_ctime);
712
713         return 0;
714 }
715
716 /*
717  * pre_op_attr
718  *      union pre_op_attr switch (bool attributes_follow) {
719  *      case TRUE:
720  *              wcc_attr        attributes;
721  *      case FALSE:
722  *              void;
723  *      };
724  *
725  * wcc_data
726  *
727  *      struct wcc_data {
728  *              pre_op_attr     before;
729  *              post_op_attr    after;
730  *      };
731  */
732 static int decode_pre_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
733 {
734         __be32 *p;
735
736         p = xdr_inline_decode(xdr, 4);
737         if (unlikely(!p))
738                 return -EIO;
739         if (*p != xdr_zero)
740                 return decode_wcc_attr(xdr, fattr);
741         return 0;
742 }
743
744 static int decode_wcc_data(struct xdr_stream *xdr, struct nfs_fattr *fattr,
745                 struct user_namespace *userns)
746 {
747         int error;
748
749         error = decode_pre_op_attr(xdr, fattr);
750         if (unlikely(error))
751                 goto out;
752         error = decode_post_op_attr(xdr, fattr, userns);
753 out:
754         return error;
755 }
756
757 /*
758  * post_op_fh3
759  *
760  *      union post_op_fh3 switch (bool handle_follows) {
761  *      case TRUE:
762  *              nfs_fh3  handle;
763  *      case FALSE:
764  *              void;
765  *      };
766  */
767 static int decode_post_op_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
768 {
769         __be32 *p = xdr_inline_decode(xdr, 4);
770         if (unlikely(!p))
771                 return -EIO;
772         if (*p != xdr_zero)
773                 return decode_nfs_fh3(xdr, fh);
774         zero_nfs_fh3(fh);
775         return 0;
776 }
777
778 /*
779  * diropargs3
780  *
781  *      struct diropargs3 {
782  *              nfs_fh3         dir;
783  *              filename3       name;
784  *      };
785  */
786 static void encode_diropargs3(struct xdr_stream *xdr, const struct nfs_fh *fh,
787                               const char *name, u32 length)
788 {
789         encode_nfs_fh3(xdr, fh);
790         encode_filename3(xdr, name, length);
791 }
792
793
794 /*
795  * NFSv3 XDR encode functions
796  *
797  * NFSv3 argument types are defined in section 3.3 of RFC 1813:
798  * "NFS Version 3 Protocol Specification".
799  */
800
801 /*
802  * 3.3.1  GETATTR3args
803  *
804  *      struct GETATTR3args {
805  *              nfs_fh3  object;
806  *      };
807  */
808 static void nfs3_xdr_enc_getattr3args(struct rpc_rqst *req,
809                                       struct xdr_stream *xdr,
810                                       const void *data)
811 {
812         const struct nfs_fh *fh = data;
813
814         encode_nfs_fh3(xdr, fh);
815 }
816
817 /*
818  * 3.3.2  SETATTR3args
819  *
820  *      union sattrguard3 switch (bool check) {
821  *      case TRUE:
822  *              nfstime3  obj_ctime;
823  *      case FALSE:
824  *              void;
825  *      };
826  *
827  *      struct SETATTR3args {
828  *              nfs_fh3         object;
829  *              sattr3          new_attributes;
830  *              sattrguard3     guard;
831  *      };
832  */
833 static void encode_sattrguard3(struct xdr_stream *xdr,
834                                const struct nfs3_sattrargs *args)
835 {
836         __be32 *p;
837
838         if (args->guard) {
839                 p = xdr_reserve_space(xdr, 4 + 8);
840                 *p++ = xdr_one;
841                 xdr_encode_nfstime3(p, &args->guardtime);
842         } else {
843                 p = xdr_reserve_space(xdr, 4);
844                 *p = xdr_zero;
845         }
846 }
847
848 static void nfs3_xdr_enc_setattr3args(struct rpc_rqst *req,
849                                       struct xdr_stream *xdr,
850                                       const void *data)
851 {
852         const struct nfs3_sattrargs *args = data;
853         encode_nfs_fh3(xdr, args->fh);
854         encode_sattr3(xdr, args->sattr, rpc_rqst_userns(req));
855         encode_sattrguard3(xdr, args);
856 }
857
858 /*
859  * 3.3.3  LOOKUP3args
860  *
861  *      struct LOOKUP3args {
862  *              diropargs3  what;
863  *      };
864  */
865 static void nfs3_xdr_enc_lookup3args(struct rpc_rqst *req,
866                                      struct xdr_stream *xdr,
867                                      const void *data)
868 {
869         const struct nfs3_diropargs *args = data;
870
871         encode_diropargs3(xdr, args->fh, args->name, args->len);
872 }
873
874 /*
875  * 3.3.4  ACCESS3args
876  *
877  *      struct ACCESS3args {
878  *              nfs_fh3         object;
879  *              uint32          access;
880  *      };
881  */
882 static void encode_access3args(struct xdr_stream *xdr,
883                                const struct nfs3_accessargs *args)
884 {
885         encode_nfs_fh3(xdr, args->fh);
886         encode_uint32(xdr, args->access);
887 }
888
889 static void nfs3_xdr_enc_access3args(struct rpc_rqst *req,
890                                      struct xdr_stream *xdr,
891                                      const void *data)
892 {
893         const struct nfs3_accessargs *args = data;
894
895         encode_access3args(xdr, args);
896 }
897
898 /*
899  * 3.3.5  READLINK3args
900  *
901  *      struct READLINK3args {
902  *              nfs_fh3 symlink;
903  *      };
904  */
905 static void nfs3_xdr_enc_readlink3args(struct rpc_rqst *req,
906                                        struct xdr_stream *xdr,
907                                        const void *data)
908 {
909         const struct nfs3_readlinkargs *args = data;
910
911         encode_nfs_fh3(xdr, args->fh);
912         rpc_prepare_reply_pages(req, args->pages, args->pgbase, args->pglen,
913                                 NFS3_readlinkres_sz - NFS3_pagepad_sz);
914 }
915
916 /*
917  * 3.3.6  READ3args
918  *
919  *      struct READ3args {
920  *              nfs_fh3         file;
921  *              offset3         offset;
922  *              count3          count;
923  *      };
924  */
925 static void encode_read3args(struct xdr_stream *xdr,
926                              const struct nfs_pgio_args *args)
927 {
928         __be32 *p;
929
930         encode_nfs_fh3(xdr, args->fh);
931
932         p = xdr_reserve_space(xdr, 8 + 4);
933         p = xdr_encode_hyper(p, args->offset);
934         *p = cpu_to_be32(args->count);
935 }
936
937 static void nfs3_xdr_enc_read3args(struct rpc_rqst *req,
938                                    struct xdr_stream *xdr,
939                                    const void *data)
940 {
941         const struct nfs_pgio_args *args = data;
942         unsigned int replen = args->replen ? args->replen :
943                                              NFS3_readres_sz - NFS3_pagepad_sz;
944
945         encode_read3args(xdr, args);
946         rpc_prepare_reply_pages(req, args->pages, args->pgbase,
947                                 args->count, replen);
948         req->rq_rcv_buf.flags |= XDRBUF_READ;
949 }
950
951 /*
952  * 3.3.7  WRITE3args
953  *
954  *      enum stable_how {
955  *              UNSTABLE  = 0,
956  *              DATA_SYNC = 1,
957  *              FILE_SYNC = 2
958  *      };
959  *
960  *      struct WRITE3args {
961  *              nfs_fh3         file;
962  *              offset3         offset;
963  *              count3          count;
964  *              stable_how      stable;
965  *              opaque          data<>;
966  *      };
967  */
968 static void encode_write3args(struct xdr_stream *xdr,
969                               const struct nfs_pgio_args *args)
970 {
971         __be32 *p;
972
973         encode_nfs_fh3(xdr, args->fh);
974
975         p = xdr_reserve_space(xdr, 8 + 4 + 4 + 4);
976         p = xdr_encode_hyper(p, args->offset);
977         *p++ = cpu_to_be32(args->count);
978         *p++ = cpu_to_be32(args->stable);
979         *p = cpu_to_be32(args->count);
980         xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
981 }
982
983 static void nfs3_xdr_enc_write3args(struct rpc_rqst *req,
984                                     struct xdr_stream *xdr,
985                                     const void *data)
986 {
987         const struct nfs_pgio_args *args = data;
988
989         encode_write3args(xdr, args);
990         xdr->buf->flags |= XDRBUF_WRITE;
991 }
992
993 /*
994  * 3.3.8  CREATE3args
995  *
996  *      enum createmode3 {
997  *              UNCHECKED = 0,
998  *              GUARDED   = 1,
999  *              EXCLUSIVE = 2
1000  *      };
1001  *
1002  *      union createhow3 switch (createmode3 mode) {
1003  *      case UNCHECKED:
1004  *      case GUARDED:
1005  *              sattr3       obj_attributes;
1006  *      case EXCLUSIVE:
1007  *              createverf3  verf;
1008  *      };
1009  *
1010  *      struct CREATE3args {
1011  *              diropargs3      where;
1012  *              createhow3      how;
1013  *      };
1014  */
1015 static void encode_createhow3(struct xdr_stream *xdr,
1016                               const struct nfs3_createargs *args,
1017                               struct user_namespace *userns)
1018 {
1019         encode_uint32(xdr, args->createmode);
1020         switch (args->createmode) {
1021         case NFS3_CREATE_UNCHECKED:
1022         case NFS3_CREATE_GUARDED:
1023                 encode_sattr3(xdr, args->sattr, userns);
1024                 break;
1025         case NFS3_CREATE_EXCLUSIVE:
1026                 encode_createverf3(xdr, args->verifier);
1027                 break;
1028         default:
1029                 BUG();
1030         }
1031 }
1032
1033 static void nfs3_xdr_enc_create3args(struct rpc_rqst *req,
1034                                      struct xdr_stream *xdr,
1035                                      const void *data)
1036 {
1037         const struct nfs3_createargs *args = data;
1038
1039         encode_diropargs3(xdr, args->fh, args->name, args->len);
1040         encode_createhow3(xdr, args, rpc_rqst_userns(req));
1041 }
1042
1043 /*
1044  * 3.3.9  MKDIR3args
1045  *
1046  *      struct MKDIR3args {
1047  *              diropargs3      where;
1048  *              sattr3          attributes;
1049  *      };
1050  */
1051 static void nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req,
1052                                     struct xdr_stream *xdr,
1053                                     const void *data)
1054 {
1055         const struct nfs3_mkdirargs *args = data;
1056
1057         encode_diropargs3(xdr, args->fh, args->name, args->len);
1058         encode_sattr3(xdr, args->sattr, rpc_rqst_userns(req));
1059 }
1060
1061 /*
1062  * 3.3.10  SYMLINK3args
1063  *
1064  *      struct symlinkdata3 {
1065  *              sattr3          symlink_attributes;
1066  *              nfspath3        symlink_data;
1067  *      };
1068  *
1069  *      struct SYMLINK3args {
1070  *              diropargs3      where;
1071  *              symlinkdata3    symlink;
1072  *      };
1073  */
1074 static void encode_symlinkdata3(struct xdr_stream *xdr,
1075                                 const void *data,
1076                                 struct user_namespace *userns)
1077 {
1078         const struct nfs3_symlinkargs *args = data;
1079
1080         encode_sattr3(xdr, args->sattr, userns);
1081         encode_nfspath3(xdr, args->pages, args->pathlen);
1082 }
1083
1084 static void nfs3_xdr_enc_symlink3args(struct rpc_rqst *req,
1085                                       struct xdr_stream *xdr,
1086                                       const void *data)
1087 {
1088         const struct nfs3_symlinkargs *args = data;
1089
1090         encode_diropargs3(xdr, args->fromfh, args->fromname, args->fromlen);
1091         encode_symlinkdata3(xdr, args, rpc_rqst_userns(req));
1092         xdr->buf->flags |= XDRBUF_WRITE;
1093 }
1094
1095 /*
1096  * 3.3.11  MKNOD3args
1097  *
1098  *      struct devicedata3 {
1099  *              sattr3          dev_attributes;
1100  *              specdata3       spec;
1101  *      };
1102  *
1103  *      union mknoddata3 switch (ftype3 type) {
1104  *      case NF3CHR:
1105  *      case NF3BLK:
1106  *              devicedata3     device;
1107  *      case NF3SOCK:
1108  *      case NF3FIFO:
1109  *              sattr3          pipe_attributes;
1110  *      default:
1111  *              void;
1112  *      };
1113  *
1114  *      struct MKNOD3args {
1115  *              diropargs3      where;
1116  *              mknoddata3      what;
1117  *      };
1118  */
1119 static void encode_devicedata3(struct xdr_stream *xdr,
1120                                const struct nfs3_mknodargs *args,
1121                                struct user_namespace *userns)
1122 {
1123         encode_sattr3(xdr, args->sattr, userns);
1124         encode_specdata3(xdr, args->rdev);
1125 }
1126
1127 static void encode_mknoddata3(struct xdr_stream *xdr,
1128                               const struct nfs3_mknodargs *args,
1129                               struct user_namespace *userns)
1130 {
1131         encode_ftype3(xdr, args->type);
1132         switch (args->type) {
1133         case NF3CHR:
1134         case NF3BLK:
1135                 encode_devicedata3(xdr, args, userns);
1136                 break;
1137         case NF3SOCK:
1138         case NF3FIFO:
1139                 encode_sattr3(xdr, args->sattr, userns);
1140                 break;
1141         case NF3REG:
1142         case NF3DIR:
1143                 break;
1144         default:
1145                 BUG();
1146         }
1147 }
1148
1149 static void nfs3_xdr_enc_mknod3args(struct rpc_rqst *req,
1150                                     struct xdr_stream *xdr,
1151                                     const void *data)
1152 {
1153         const struct nfs3_mknodargs *args = data;
1154
1155         encode_diropargs3(xdr, args->fh, args->name, args->len);
1156         encode_mknoddata3(xdr, args, rpc_rqst_userns(req));
1157 }
1158
1159 /*
1160  * 3.3.12  REMOVE3args
1161  *
1162  *      struct REMOVE3args {
1163  *              diropargs3  object;
1164  *      };
1165  */
1166 static void nfs3_xdr_enc_remove3args(struct rpc_rqst *req,
1167                                      struct xdr_stream *xdr,
1168                                      const void *data)
1169 {
1170         const struct nfs_removeargs *args = data;
1171
1172         encode_diropargs3(xdr, args->fh, args->name.name, args->name.len);
1173 }
1174
1175 /*
1176  * 3.3.14  RENAME3args
1177  *
1178  *      struct RENAME3args {
1179  *              diropargs3      from;
1180  *              diropargs3      to;
1181  *      };
1182  */
1183 static void nfs3_xdr_enc_rename3args(struct rpc_rqst *req,
1184                                      struct xdr_stream *xdr,
1185                                      const void *data)
1186 {
1187         const struct nfs_renameargs *args = data;
1188         const struct qstr *old = args->old_name;
1189         const struct qstr *new = args->new_name;
1190
1191         encode_diropargs3(xdr, args->old_dir, old->name, old->len);
1192         encode_diropargs3(xdr, args->new_dir, new->name, new->len);
1193 }
1194
1195 /*
1196  * 3.3.15  LINK3args
1197  *
1198  *      struct LINK3args {
1199  *              nfs_fh3         file;
1200  *              diropargs3      link;
1201  *      };
1202  */
1203 static void nfs3_xdr_enc_link3args(struct rpc_rqst *req,
1204                                    struct xdr_stream *xdr,
1205                                    const void *data)
1206 {
1207         const struct nfs3_linkargs *args = data;
1208
1209         encode_nfs_fh3(xdr, args->fromfh);
1210         encode_diropargs3(xdr, args->tofh, args->toname, args->tolen);
1211 }
1212
1213 /*
1214  * 3.3.16  READDIR3args
1215  *
1216  *      struct READDIR3args {
1217  *              nfs_fh3         dir;
1218  *              cookie3         cookie;
1219  *              cookieverf3     cookieverf;
1220  *              count3          count;
1221  *      };
1222  */
1223 static void encode_readdir3args(struct xdr_stream *xdr,
1224                                 const struct nfs3_readdirargs *args)
1225 {
1226         __be32 *p;
1227
1228         encode_nfs_fh3(xdr, args->fh);
1229
1230         p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4);
1231         p = xdr_encode_cookie3(p, args->cookie);
1232         p = xdr_encode_cookieverf3(p, args->verf);
1233         *p = cpu_to_be32(args->count);
1234 }
1235
1236 static void nfs3_xdr_enc_readdir3args(struct rpc_rqst *req,
1237                                       struct xdr_stream *xdr,
1238                                       const void *data)
1239 {
1240         const struct nfs3_readdirargs *args = data;
1241
1242         encode_readdir3args(xdr, args);
1243         rpc_prepare_reply_pages(req, args->pages, 0, args->count,
1244                                 NFS3_readdirres_sz - NFS3_pagepad_sz);
1245 }
1246
1247 /*
1248  * 3.3.17  READDIRPLUS3args
1249  *
1250  *      struct READDIRPLUS3args {
1251  *              nfs_fh3         dir;
1252  *              cookie3         cookie;
1253  *              cookieverf3     cookieverf;
1254  *              count3          dircount;
1255  *              count3          maxcount;
1256  *      };
1257  */
1258 static void encode_readdirplus3args(struct xdr_stream *xdr,
1259                                     const struct nfs3_readdirargs *args)
1260 {
1261         uint32_t dircount = args->count;
1262         uint32_t maxcount = args->count;
1263         __be32 *p;
1264
1265         encode_nfs_fh3(xdr, args->fh);
1266
1267         p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4 + 4);
1268         p = xdr_encode_cookie3(p, args->cookie);
1269         p = xdr_encode_cookieverf3(p, args->verf);
1270
1271         /*
1272          * readdirplus: need dircount + buffer size.
1273          * We just make sure we make dircount big enough
1274          */
1275         *p++ = cpu_to_be32(dircount);
1276         *p = cpu_to_be32(maxcount);
1277 }
1278
1279 static void nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req,
1280                                           struct xdr_stream *xdr,
1281                                           const void *data)
1282 {
1283         const struct nfs3_readdirargs *args = data;
1284
1285         encode_readdirplus3args(xdr, args);
1286         rpc_prepare_reply_pages(req, args->pages, 0, args->count,
1287                                 NFS3_readdirres_sz - NFS3_pagepad_sz);
1288 }
1289
1290 /*
1291  * 3.3.21  COMMIT3args
1292  *
1293  *      struct COMMIT3args {
1294  *              nfs_fh3         file;
1295  *              offset3         offset;
1296  *              count3          count;
1297  *      };
1298  */
1299 static void encode_commit3args(struct xdr_stream *xdr,
1300                                const struct nfs_commitargs *args)
1301 {
1302         __be32 *p;
1303
1304         encode_nfs_fh3(xdr, args->fh);
1305
1306         p = xdr_reserve_space(xdr, 8 + 4);
1307         p = xdr_encode_hyper(p, args->offset);
1308         *p = cpu_to_be32(args->count);
1309 }
1310
1311 static void nfs3_xdr_enc_commit3args(struct rpc_rqst *req,
1312                                      struct xdr_stream *xdr,
1313                                      const void *data)
1314 {
1315         const struct nfs_commitargs *args = data;
1316
1317         encode_commit3args(xdr, args);
1318 }
1319
1320 #ifdef CONFIG_NFS_V3_ACL
1321
1322 static void nfs3_xdr_enc_getacl3args(struct rpc_rqst *req,
1323                                      struct xdr_stream *xdr,
1324                                      const void *data)
1325 {
1326         const struct nfs3_getaclargs *args = data;
1327
1328         encode_nfs_fh3(xdr, args->fh);
1329         encode_uint32(xdr, args->mask);
1330         if (args->mask & (NFS_ACL | NFS_DFACL)) {
1331                 rpc_prepare_reply_pages(req, args->pages, 0,
1332                                         NFSACL_MAXPAGES << PAGE_SHIFT,
1333                                         ACL3_getaclres_sz - NFS3_pagepad_sz);
1334                 req->rq_rcv_buf.flags |= XDRBUF_SPARSE_PAGES;
1335         }
1336 }
1337
1338 static void nfs3_xdr_enc_setacl3args(struct rpc_rqst *req,
1339                                      struct xdr_stream *xdr,
1340                                      const void *data)
1341 {
1342         const struct nfs3_setaclargs *args = data;
1343         unsigned int base;
1344         int error;
1345
1346         encode_nfs_fh3(xdr, NFS_FH(args->inode));
1347         encode_uint32(xdr, args->mask);
1348
1349         base = req->rq_slen;
1350         if (args->npages != 0)
1351                 xdr_write_pages(xdr, args->pages, 0, args->len);
1352         else
1353                 xdr_reserve_space(xdr, args->len);
1354
1355         error = nfsacl_encode(xdr->buf, base, args->inode,
1356                             (args->mask & NFS_ACL) ?
1357                             args->acl_access : NULL, 1, 0);
1358         /* FIXME: this is just broken */
1359         BUG_ON(error < 0);
1360         error = nfsacl_encode(xdr->buf, base + error, args->inode,
1361                             (args->mask & NFS_DFACL) ?
1362                             args->acl_default : NULL, 1,
1363                             NFS_ACL_DEFAULT);
1364         BUG_ON(error < 0);
1365 }
1366
1367 #endif  /* CONFIG_NFS_V3_ACL */
1368
1369 /*
1370  * NFSv3 XDR decode functions
1371  *
1372  * NFSv3 result types are defined in section 3.3 of RFC 1813:
1373  * "NFS Version 3 Protocol Specification".
1374  */
1375
1376 /*
1377  * 3.3.1  GETATTR3res
1378  *
1379  *      struct GETATTR3resok {
1380  *              fattr3          obj_attributes;
1381  *      };
1382  *
1383  *      union GETATTR3res switch (nfsstat3 status) {
1384  *      case NFS3_OK:
1385  *              GETATTR3resok  resok;
1386  *      default:
1387  *              void;
1388  *      };
1389  */
1390 static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req,
1391                                     struct xdr_stream *xdr,
1392                                     void *result)
1393 {
1394         enum nfs_stat status;
1395         int error;
1396
1397         error = decode_nfsstat3(xdr, &status);
1398         if (unlikely(error))
1399                 goto out;
1400         if (status != NFS3_OK)
1401                 goto out_default;
1402         error = decode_fattr3(xdr, result, rpc_rqst_userns(req));
1403 out:
1404         return error;
1405 out_default:
1406         return nfs_stat_to_errno(status);
1407 }
1408
1409 /*
1410  * 3.3.2  SETATTR3res
1411  *
1412  *      struct SETATTR3resok {
1413  *              wcc_data  obj_wcc;
1414  *      };
1415  *
1416  *      struct SETATTR3resfail {
1417  *              wcc_data  obj_wcc;
1418  *      };
1419  *
1420  *      union SETATTR3res switch (nfsstat3 status) {
1421  *      case NFS3_OK:
1422  *              SETATTR3resok   resok;
1423  *      default:
1424  *              SETATTR3resfail resfail;
1425  *      };
1426  */
1427 static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req,
1428                                     struct xdr_stream *xdr,
1429                                     void *result)
1430 {
1431         enum nfs_stat status;
1432         int error;
1433
1434         error = decode_nfsstat3(xdr, &status);
1435         if (unlikely(error))
1436                 goto out;
1437         error = decode_wcc_data(xdr, result, rpc_rqst_userns(req));
1438         if (unlikely(error))
1439                 goto out;
1440         if (status != NFS3_OK)
1441                 goto out_status;
1442 out:
1443         return error;
1444 out_status:
1445         return nfs_stat_to_errno(status);
1446 }
1447
1448 /*
1449  * 3.3.3  LOOKUP3res
1450  *
1451  *      struct LOOKUP3resok {
1452  *              nfs_fh3         object;
1453  *              post_op_attr    obj_attributes;
1454  *              post_op_attr    dir_attributes;
1455  *      };
1456  *
1457  *      struct LOOKUP3resfail {
1458  *              post_op_attr    dir_attributes;
1459  *      };
1460  *
1461  *      union LOOKUP3res switch (nfsstat3 status) {
1462  *      case NFS3_OK:
1463  *              LOOKUP3resok    resok;
1464  *      default:
1465  *              LOOKUP3resfail  resfail;
1466  *      };
1467  */
1468 static int nfs3_xdr_dec_lookup3res(struct rpc_rqst *req,
1469                                    struct xdr_stream *xdr,
1470                                    void *data)
1471 {
1472         struct user_namespace *userns = rpc_rqst_userns(req);
1473         struct nfs3_diropres *result = data;
1474         enum nfs_stat status;
1475         int error;
1476
1477         error = decode_nfsstat3(xdr, &status);
1478         if (unlikely(error))
1479                 goto out;
1480         if (status != NFS3_OK)
1481                 goto out_default;
1482         error = decode_nfs_fh3(xdr, result->fh);
1483         if (unlikely(error))
1484                 goto out;
1485         error = decode_post_op_attr(xdr, result->fattr, userns);
1486         if (unlikely(error))
1487                 goto out;
1488         error = decode_post_op_attr(xdr, result->dir_attr, userns);
1489 out:
1490         return error;
1491 out_default:
1492         error = decode_post_op_attr(xdr, result->dir_attr, userns);
1493         if (unlikely(error))
1494                 goto out;
1495         return nfs_stat_to_errno(status);
1496 }
1497
1498 /*
1499  * 3.3.4  ACCESS3res
1500  *
1501  *      struct ACCESS3resok {
1502  *              post_op_attr    obj_attributes;
1503  *              uint32          access;
1504  *      };
1505  *
1506  *      struct ACCESS3resfail {
1507  *              post_op_attr    obj_attributes;
1508  *      };
1509  *
1510  *      union ACCESS3res switch (nfsstat3 status) {
1511  *      case NFS3_OK:
1512  *              ACCESS3resok    resok;
1513  *      default:
1514  *              ACCESS3resfail  resfail;
1515  *      };
1516  */
1517 static int nfs3_xdr_dec_access3res(struct rpc_rqst *req,
1518                                    struct xdr_stream *xdr,
1519                                    void *data)
1520 {
1521         struct nfs3_accessres *result = data;
1522         enum nfs_stat status;
1523         int error;
1524
1525         error = decode_nfsstat3(xdr, &status);
1526         if (unlikely(error))
1527                 goto out;
1528         error = decode_post_op_attr(xdr, result->fattr, rpc_rqst_userns(req));
1529         if (unlikely(error))
1530                 goto out;
1531         if (status != NFS3_OK)
1532                 goto out_default;
1533         error = decode_uint32(xdr, &result->access);
1534 out:
1535         return error;
1536 out_default:
1537         return nfs_stat_to_errno(status);
1538 }
1539
1540 /*
1541  * 3.3.5  READLINK3res
1542  *
1543  *      struct READLINK3resok {
1544  *              post_op_attr    symlink_attributes;
1545  *              nfspath3        data;
1546  *      };
1547  *
1548  *      struct READLINK3resfail {
1549  *              post_op_attr    symlink_attributes;
1550  *      };
1551  *
1552  *      union READLINK3res switch (nfsstat3 status) {
1553  *      case NFS3_OK:
1554  *              READLINK3resok  resok;
1555  *      default:
1556  *              READLINK3resfail resfail;
1557  *      };
1558  */
1559 static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req,
1560                                      struct xdr_stream *xdr,
1561                                      void *result)
1562 {
1563         enum nfs_stat status;
1564         int error;
1565
1566         error = decode_nfsstat3(xdr, &status);
1567         if (unlikely(error))
1568                 goto out;
1569         error = decode_post_op_attr(xdr, result, rpc_rqst_userns(req));
1570         if (unlikely(error))
1571                 goto out;
1572         if (status != NFS3_OK)
1573                 goto out_default;
1574         error = decode_nfspath3(xdr);
1575 out:
1576         return error;
1577 out_default:
1578         return nfs_stat_to_errno(status);
1579 }
1580
1581 /*
1582  * 3.3.6  READ3res
1583  *
1584  *      struct READ3resok {
1585  *              post_op_attr    file_attributes;
1586  *              count3          count;
1587  *              bool            eof;
1588  *              opaque          data<>;
1589  *      };
1590  *
1591  *      struct READ3resfail {
1592  *              post_op_attr    file_attributes;
1593  *      };
1594  *
1595  *      union READ3res switch (nfsstat3 status) {
1596  *      case NFS3_OK:
1597  *              READ3resok      resok;
1598  *      default:
1599  *              READ3resfail    resfail;
1600  *      };
1601  */
1602 static int decode_read3resok(struct xdr_stream *xdr,
1603                              struct nfs_pgio_res *result)
1604 {
1605         u32 eof, count, ocount, recvd;
1606         __be32 *p;
1607
1608         p = xdr_inline_decode(xdr, 4 + 4 + 4);
1609         if (unlikely(!p))
1610                 return -EIO;
1611         count = be32_to_cpup(p++);
1612         eof = be32_to_cpup(p++);
1613         ocount = be32_to_cpup(p++);
1614         if (unlikely(ocount != count))
1615                 goto out_mismatch;
1616         recvd = xdr_read_pages(xdr, count);
1617         if (unlikely(count > recvd))
1618                 goto out_cheating;
1619 out:
1620         result->eof = eof;
1621         result->count = count;
1622         return count;
1623 out_mismatch:
1624         dprintk("NFS: READ count doesn't match length of opaque: "
1625                 "count %u != ocount %u\n", count, ocount);
1626         return -EIO;
1627 out_cheating:
1628         dprintk("NFS: server cheating in read result: "
1629                 "count %u > recvd %u\n", count, recvd);
1630         count = recvd;
1631         eof = 0;
1632         goto out;
1633 }
1634
1635 static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr,
1636                                  void *data)
1637 {
1638         struct nfs_pgio_res *result = data;
1639         unsigned int pos;
1640         enum nfs_stat status;
1641         int error;
1642
1643         pos = xdr_stream_pos(xdr);
1644         error = decode_nfsstat3(xdr, &status);
1645         if (unlikely(error))
1646                 goto out;
1647         error = decode_post_op_attr(xdr, result->fattr, rpc_rqst_userns(req));
1648         if (unlikely(error))
1649                 goto out;
1650         result->op_status = status;
1651         if (status != NFS3_OK)
1652                 goto out_status;
1653         result->replen = 3 + ((xdr_stream_pos(xdr) - pos) >> 2);
1654         error = decode_read3resok(xdr, result);
1655 out:
1656         return error;
1657 out_status:
1658         return nfs_stat_to_errno(status);
1659 }
1660
1661 /*
1662  * 3.3.7  WRITE3res
1663  *
1664  *      enum stable_how {
1665  *              UNSTABLE  = 0,
1666  *              DATA_SYNC = 1,
1667  *              FILE_SYNC = 2
1668  *      };
1669  *
1670  *      struct WRITE3resok {
1671  *              wcc_data        file_wcc;
1672  *              count3          count;
1673  *              stable_how      committed;
1674  *              writeverf3      verf;
1675  *      };
1676  *
1677  *      struct WRITE3resfail {
1678  *              wcc_data        file_wcc;
1679  *      };
1680  *
1681  *      union WRITE3res switch (nfsstat3 status) {
1682  *      case NFS3_OK:
1683  *              WRITE3resok     resok;
1684  *      default:
1685  *              WRITE3resfail   resfail;
1686  *      };
1687  */
1688 static int decode_write3resok(struct xdr_stream *xdr,
1689                               struct nfs_pgio_res *result)
1690 {
1691         __be32 *p;
1692
1693         p = xdr_inline_decode(xdr, 4 + 4);
1694         if (unlikely(!p))
1695                 return -EIO;
1696         result->count = be32_to_cpup(p++);
1697         result->verf->committed = be32_to_cpup(p++);
1698         if (unlikely(result->verf->committed > NFS_FILE_SYNC))
1699                 goto out_badvalue;
1700         if (decode_writeverf3(xdr, &result->verf->verifier))
1701                 return -EIO;
1702         return result->count;
1703 out_badvalue:
1704         dprintk("NFS: bad stable_how value: %u\n", result->verf->committed);
1705         return -EIO;
1706 }
1707
1708 static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, struct xdr_stream *xdr,
1709                                   void *data)
1710 {
1711         struct nfs_pgio_res *result = data;
1712         enum nfs_stat status;
1713         int error;
1714
1715         error = decode_nfsstat3(xdr, &status);
1716         if (unlikely(error))
1717                 goto out;
1718         error = decode_wcc_data(xdr, result->fattr, rpc_rqst_userns(req));
1719         if (unlikely(error))
1720                 goto out;
1721         result->op_status = status;
1722         if (status != NFS3_OK)
1723                 goto out_status;
1724         error = decode_write3resok(xdr, result);
1725 out:
1726         return error;
1727 out_status:
1728         return nfs_stat_to_errno(status);
1729 }
1730
1731 /*
1732  * 3.3.8  CREATE3res
1733  *
1734  *      struct CREATE3resok {
1735  *              post_op_fh3     obj;
1736  *              post_op_attr    obj_attributes;
1737  *              wcc_data        dir_wcc;
1738  *      };
1739  *
1740  *      struct CREATE3resfail {
1741  *              wcc_data        dir_wcc;
1742  *      };
1743  *
1744  *      union CREATE3res switch (nfsstat3 status) {
1745  *      case NFS3_OK:
1746  *              CREATE3resok    resok;
1747  *      default:
1748  *              CREATE3resfail  resfail;
1749  *      };
1750  */
1751 static int decode_create3resok(struct xdr_stream *xdr,
1752                                struct nfs3_diropres *result,
1753                                struct user_namespace *userns)
1754 {
1755         int error;
1756
1757         error = decode_post_op_fh3(xdr, result->fh);
1758         if (unlikely(error))
1759                 goto out;
1760         error = decode_post_op_attr(xdr, result->fattr, userns);
1761         if (unlikely(error))
1762                 goto out;
1763         /* The server isn't required to return a file handle.
1764          * If it didn't, force the client to perform a LOOKUP
1765          * to determine the correct file handle and attribute
1766          * values for the new object. */
1767         if (result->fh->size == 0)
1768                 result->fattr->valid = 0;
1769         error = decode_wcc_data(xdr, result->dir_attr, userns);
1770 out:
1771         return error;
1772 }
1773
1774 static int nfs3_xdr_dec_create3res(struct rpc_rqst *req,
1775                                    struct xdr_stream *xdr,
1776                                    void *data)
1777 {
1778         struct user_namespace *userns = rpc_rqst_userns(req);
1779         struct nfs3_diropres *result = data;
1780         enum nfs_stat status;
1781         int error;
1782
1783         error = decode_nfsstat3(xdr, &status);
1784         if (unlikely(error))
1785                 goto out;
1786         if (status != NFS3_OK)
1787                 goto out_default;
1788         error = decode_create3resok(xdr, result, userns);
1789 out:
1790         return error;
1791 out_default:
1792         error = decode_wcc_data(xdr, result->dir_attr, userns);
1793         if (unlikely(error))
1794                 goto out;
1795         return nfs_stat_to_errno(status);
1796 }
1797
1798 /*
1799  * 3.3.12  REMOVE3res
1800  *
1801  *      struct REMOVE3resok {
1802  *              wcc_data    dir_wcc;
1803  *      };
1804  *
1805  *      struct REMOVE3resfail {
1806  *              wcc_data    dir_wcc;
1807  *      };
1808  *
1809  *      union REMOVE3res switch (nfsstat3 status) {
1810  *      case NFS3_OK:
1811  *              REMOVE3resok   resok;
1812  *      default:
1813  *              REMOVE3resfail resfail;
1814  *      };
1815  */
1816 static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req,
1817                                    struct xdr_stream *xdr,
1818                                    void *data)
1819 {
1820         struct nfs_removeres *result = data;
1821         enum nfs_stat status;
1822         int error;
1823
1824         error = decode_nfsstat3(xdr, &status);
1825         if (unlikely(error))
1826                 goto out;
1827         error = decode_wcc_data(xdr, result->dir_attr, rpc_rqst_userns(req));
1828         if (unlikely(error))
1829                 goto out;
1830         if (status != NFS3_OK)
1831                 goto out_status;
1832 out:
1833         return error;
1834 out_status:
1835         return nfs_stat_to_errno(status);
1836 }
1837
1838 /*
1839  * 3.3.14  RENAME3res
1840  *
1841  *      struct RENAME3resok {
1842  *              wcc_data        fromdir_wcc;
1843  *              wcc_data        todir_wcc;
1844  *      };
1845  *
1846  *      struct RENAME3resfail {
1847  *              wcc_data        fromdir_wcc;
1848  *              wcc_data        todir_wcc;
1849  *      };
1850  *
1851  *      union RENAME3res switch (nfsstat3 status) {
1852  *      case NFS3_OK:
1853  *              RENAME3resok   resok;
1854  *      default:
1855  *              RENAME3resfail resfail;
1856  *      };
1857  */
1858 static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req,
1859                                    struct xdr_stream *xdr,
1860                                    void *data)
1861 {
1862         struct user_namespace *userns = rpc_rqst_userns(req);
1863         struct nfs_renameres *result = data;
1864         enum nfs_stat status;
1865         int error;
1866
1867         error = decode_nfsstat3(xdr, &status);
1868         if (unlikely(error))
1869                 goto out;
1870         error = decode_wcc_data(xdr, result->old_fattr, userns);
1871         if (unlikely(error))
1872                 goto out;
1873         error = decode_wcc_data(xdr, result->new_fattr, userns);
1874         if (unlikely(error))
1875                 goto out;
1876         if (status != NFS3_OK)
1877                 goto out_status;
1878 out:
1879         return error;
1880 out_status:
1881         return nfs_stat_to_errno(status);
1882 }
1883
1884 /*
1885  * 3.3.15  LINK3res
1886  *
1887  *      struct LINK3resok {
1888  *              post_op_attr    file_attributes;
1889  *              wcc_data        linkdir_wcc;
1890  *      };
1891  *
1892  *      struct LINK3resfail {
1893  *              post_op_attr    file_attributes;
1894  *              wcc_data        linkdir_wcc;
1895  *      };
1896  *
1897  *      union LINK3res switch (nfsstat3 status) {
1898  *      case NFS3_OK:
1899  *              LINK3resok      resok;
1900  *      default:
1901  *              LINK3resfail    resfail;
1902  *      };
1903  */
1904 static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, struct xdr_stream *xdr,
1905                                  void *data)
1906 {
1907         struct user_namespace *userns = rpc_rqst_userns(req);
1908         struct nfs3_linkres *result = data;
1909         enum nfs_stat status;
1910         int error;
1911
1912         error = decode_nfsstat3(xdr, &status);
1913         if (unlikely(error))
1914                 goto out;
1915         error = decode_post_op_attr(xdr, result->fattr, userns);
1916         if (unlikely(error))
1917                 goto out;
1918         error = decode_wcc_data(xdr, result->dir_attr, userns);
1919         if (unlikely(error))
1920                 goto out;
1921         if (status != NFS3_OK)
1922                 goto out_status;
1923 out:
1924         return error;
1925 out_status:
1926         return nfs_stat_to_errno(status);
1927 }
1928
1929 /**
1930  * nfs3_decode_dirent - Decode a single NFSv3 directory entry stored in
1931  *                      the local page cache
1932  * @xdr: XDR stream where entry resides
1933  * @entry: buffer to fill in with entry data
1934  * @plus: boolean indicating whether this should be a readdirplus entry
1935  *
1936  * Returns zero if successful, otherwise a negative errno value is
1937  * returned.
1938  *
1939  * This function is not invoked during READDIR reply decoding, but
1940  * rather whenever an application invokes the getdents(2) system call
1941  * on a directory already in our cache.
1942  *
1943  * 3.3.16  entry3
1944  *
1945  *      struct entry3 {
1946  *              fileid3         fileid;
1947  *              filename3       name;
1948  *              cookie3         cookie;
1949  *              fhandle3        filehandle;
1950  *              post_op_attr3   attributes;
1951  *              entry3          *nextentry;
1952  *      };
1953  *
1954  * 3.3.17  entryplus3
1955  *      struct entryplus3 {
1956  *              fileid3         fileid;
1957  *              filename3       name;
1958  *              cookie3         cookie;
1959  *              post_op_attr    name_attributes;
1960  *              post_op_fh3     name_handle;
1961  *              entryplus3      *nextentry;
1962  *      };
1963  */
1964 int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
1965                        bool plus)
1966 {
1967         struct user_namespace *userns = rpc_userns(entry->server->client);
1968         __be32 *p;
1969         int error;
1970         u64 new_cookie;
1971
1972         p = xdr_inline_decode(xdr, 4);
1973         if (unlikely(!p))
1974                 return -EAGAIN;
1975         if (*p == xdr_zero) {
1976                 p = xdr_inline_decode(xdr, 4);
1977                 if (unlikely(!p))
1978                         return -EAGAIN;
1979                 if (*p == xdr_zero)
1980                         return -EAGAIN;
1981                 entry->eof = 1;
1982                 return -EBADCOOKIE;
1983         }
1984
1985         error = decode_fileid3(xdr, &entry->ino);
1986         if (unlikely(error))
1987                 return -EAGAIN;
1988
1989         error = decode_inline_filename3(xdr, &entry->name, &entry->len);
1990         if (unlikely(error))
1991                 return error == -ENAMETOOLONG ? -ENAMETOOLONG : -EAGAIN;
1992
1993         error = decode_cookie3(xdr, &new_cookie);
1994         if (unlikely(error))
1995                 return -EAGAIN;
1996
1997         entry->d_type = DT_UNKNOWN;
1998
1999         if (plus) {
2000                 entry->fattr->valid = 0;
2001                 error = decode_post_op_attr(xdr, entry->fattr, userns);
2002                 if (unlikely(error))
2003                         return -EAGAIN;
2004                 if (entry->fattr->valid & NFS_ATTR_FATTR_V3)
2005                         entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
2006
2007                 if (entry->fattr->fileid != entry->ino) {
2008                         entry->fattr->mounted_on_fileid = entry->ino;
2009                         entry->fattr->valid |= NFS_ATTR_FATTR_MOUNTED_ON_FILEID;
2010                 }
2011
2012                 /* In fact, a post_op_fh3: */
2013                 p = xdr_inline_decode(xdr, 4);
2014                 if (unlikely(!p))
2015                         return -EAGAIN;
2016                 if (*p != xdr_zero) {
2017                         error = decode_nfs_fh3(xdr, entry->fh);
2018                         if (unlikely(error))
2019                                 return -EAGAIN;
2020                 } else
2021                         zero_nfs_fh3(entry->fh);
2022         }
2023
2024         entry->cookie = new_cookie;
2025
2026         return 0;
2027 }
2028
2029 /*
2030  * 3.3.16  READDIR3res
2031  *
2032  *      struct dirlist3 {
2033  *              entry3          *entries;
2034  *              bool            eof;
2035  *      };
2036  *
2037  *      struct READDIR3resok {
2038  *              post_op_attr    dir_attributes;
2039  *              cookieverf3     cookieverf;
2040  *              dirlist3        reply;
2041  *      };
2042  *
2043  *      struct READDIR3resfail {
2044  *              post_op_attr    dir_attributes;
2045  *      };
2046  *
2047  *      union READDIR3res switch (nfsstat3 status) {
2048  *      case NFS3_OK:
2049  *              READDIR3resok   resok;
2050  *      default:
2051  *              READDIR3resfail resfail;
2052  *      };
2053  *
2054  * Read the directory contents into the page cache, but otherwise
2055  * don't touch them.  The actual decoding is done by nfs3_decode_entry()
2056  * during subsequent nfs_readdir() calls.
2057  */
2058 static int decode_dirlist3(struct xdr_stream *xdr)
2059 {
2060         return xdr_read_pages(xdr, xdr->buf->page_len);
2061 }
2062
2063 static int decode_readdir3resok(struct xdr_stream *xdr,
2064                                 struct nfs3_readdirres *result,
2065                                 struct user_namespace *userns)
2066 {
2067         int error;
2068
2069         error = decode_post_op_attr(xdr, result->dir_attr, userns);
2070         if (unlikely(error))
2071                 goto out;
2072         /* XXX: do we need to check if result->verf != NULL ? */
2073         error = decode_cookieverf3(xdr, result->verf);
2074         if (unlikely(error))
2075                 goto out;
2076         error = decode_dirlist3(xdr);
2077 out:
2078         return error;
2079 }
2080
2081 static int nfs3_xdr_dec_readdir3res(struct rpc_rqst *req,
2082                                     struct xdr_stream *xdr,
2083                                     void *data)
2084 {
2085         struct nfs3_readdirres *result = data;
2086         enum nfs_stat status;
2087         int error;
2088
2089         error = decode_nfsstat3(xdr, &status);
2090         if (unlikely(error))
2091                 goto out;
2092         if (status != NFS3_OK)
2093                 goto out_default;
2094         error = decode_readdir3resok(xdr, result, rpc_rqst_userns(req));
2095 out:
2096         return error;
2097 out_default:
2098         error = decode_post_op_attr(xdr, result->dir_attr, rpc_rqst_userns(req));
2099         if (unlikely(error))
2100                 goto out;
2101         return nfs_stat_to_errno(status);
2102 }
2103
2104 /*
2105  * 3.3.18  FSSTAT3res
2106  *
2107  *      struct FSSTAT3resok {
2108  *              post_op_attr    obj_attributes;
2109  *              size3           tbytes;
2110  *              size3           fbytes;
2111  *              size3           abytes;
2112  *              size3           tfiles;
2113  *              size3           ffiles;
2114  *              size3           afiles;
2115  *              uint32          invarsec;
2116  *      };
2117  *
2118  *      struct FSSTAT3resfail {
2119  *              post_op_attr    obj_attributes;
2120  *      };
2121  *
2122  *      union FSSTAT3res switch (nfsstat3 status) {
2123  *      case NFS3_OK:
2124  *              FSSTAT3resok    resok;
2125  *      default:
2126  *              FSSTAT3resfail  resfail;
2127  *      };
2128  */
2129 static int decode_fsstat3resok(struct xdr_stream *xdr,
2130                                struct nfs_fsstat *result)
2131 {
2132         __be32 *p;
2133
2134         p = xdr_inline_decode(xdr, 8 * 6 + 4);
2135         if (unlikely(!p))
2136                 return -EIO;
2137         p = xdr_decode_size3(p, &result->tbytes);
2138         p = xdr_decode_size3(p, &result->fbytes);
2139         p = xdr_decode_size3(p, &result->abytes);
2140         p = xdr_decode_size3(p, &result->tfiles);
2141         p = xdr_decode_size3(p, &result->ffiles);
2142         xdr_decode_size3(p, &result->afiles);
2143         /* ignore invarsec */
2144         return 0;
2145 }
2146
2147 static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req,
2148                                    struct xdr_stream *xdr,
2149                                    void *data)
2150 {
2151         struct nfs_fsstat *result = data;
2152         enum nfs_stat status;
2153         int error;
2154
2155         error = decode_nfsstat3(xdr, &status);
2156         if (unlikely(error))
2157                 goto out;
2158         error = decode_post_op_attr(xdr, result->fattr, rpc_rqst_userns(req));
2159         if (unlikely(error))
2160                 goto out;
2161         if (status != NFS3_OK)
2162                 goto out_status;
2163         error = decode_fsstat3resok(xdr, result);
2164 out:
2165         return error;
2166 out_status:
2167         return nfs_stat_to_errno(status);
2168 }
2169
2170 /*
2171  * 3.3.19  FSINFO3res
2172  *
2173  *      struct FSINFO3resok {
2174  *              post_op_attr    obj_attributes;
2175  *              uint32          rtmax;
2176  *              uint32          rtpref;
2177  *              uint32          rtmult;
2178  *              uint32          wtmax;
2179  *              uint32          wtpref;
2180  *              uint32          wtmult;
2181  *              uint32          dtpref;
2182  *              size3           maxfilesize;
2183  *              nfstime3        time_delta;
2184  *              uint32          properties;
2185  *      };
2186  *
2187  *      struct FSINFO3resfail {
2188  *              post_op_attr    obj_attributes;
2189  *      };
2190  *
2191  *      union FSINFO3res switch (nfsstat3 status) {
2192  *      case NFS3_OK:
2193  *              FSINFO3resok    resok;
2194  *      default:
2195  *              FSINFO3resfail  resfail;
2196  *      };
2197  */
2198 static int decode_fsinfo3resok(struct xdr_stream *xdr,
2199                                struct nfs_fsinfo *result)
2200 {
2201         __be32 *p;
2202
2203         p = xdr_inline_decode(xdr, 4 * 7 + 8 + 8 + 4);
2204         if (unlikely(!p))
2205                 return -EIO;
2206         result->rtmax  = be32_to_cpup(p++);
2207         result->rtpref = be32_to_cpup(p++);
2208         result->rtmult = be32_to_cpup(p++);
2209         result->wtmax  = be32_to_cpup(p++);
2210         result->wtpref = be32_to_cpup(p++);
2211         result->wtmult = be32_to_cpup(p++);
2212         result->dtpref = be32_to_cpup(p++);
2213         p = xdr_decode_size3(p, &result->maxfilesize);
2214         xdr_decode_nfstime3(p, &result->time_delta);
2215
2216         /* ignore properties */
2217         result->lease_time = 0;
2218         result->change_attr_type = NFS4_CHANGE_TYPE_IS_UNDEFINED;
2219         result->xattr_support = 0;
2220         return 0;
2221 }
2222
2223 static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req,
2224                                    struct xdr_stream *xdr,
2225                                    void *data)
2226 {
2227         struct nfs_fsinfo *result = data;
2228         enum nfs_stat status;
2229         int error;
2230
2231         error = decode_nfsstat3(xdr, &status);
2232         if (unlikely(error))
2233                 goto out;
2234         error = decode_post_op_attr(xdr, result->fattr, rpc_rqst_userns(req));
2235         if (unlikely(error))
2236                 goto out;
2237         if (status != NFS3_OK)
2238                 goto out_status;
2239         error = decode_fsinfo3resok(xdr, result);
2240 out:
2241         return error;
2242 out_status:
2243         return nfs_stat_to_errno(status);
2244 }
2245
2246 /*
2247  * 3.3.20  PATHCONF3res
2248  *
2249  *      struct PATHCONF3resok {
2250  *              post_op_attr    obj_attributes;
2251  *              uint32          linkmax;
2252  *              uint32          name_max;
2253  *              bool            no_trunc;
2254  *              bool            chown_restricted;
2255  *              bool            case_insensitive;
2256  *              bool            case_preserving;
2257  *      };
2258  *
2259  *      struct PATHCONF3resfail {
2260  *              post_op_attr    obj_attributes;
2261  *      };
2262  *
2263  *      union PATHCONF3res switch (nfsstat3 status) {
2264  *      case NFS3_OK:
2265  *              PATHCONF3resok  resok;
2266  *      default:
2267  *              PATHCONF3resfail resfail;
2268  *      };
2269  */
2270 static int decode_pathconf3resok(struct xdr_stream *xdr,
2271                                  struct nfs_pathconf *result)
2272 {
2273         __be32 *p;
2274
2275         p = xdr_inline_decode(xdr, 4 * 6);
2276         if (unlikely(!p))
2277                 return -EIO;
2278         result->max_link = be32_to_cpup(p++);
2279         result->max_namelen = be32_to_cpup(p);
2280         /* ignore remaining fields */
2281         return 0;
2282 }
2283
2284 static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req,
2285                                      struct xdr_stream *xdr,
2286                                      void *data)
2287 {
2288         struct nfs_pathconf *result = data;
2289         enum nfs_stat status;
2290         int error;
2291
2292         error = decode_nfsstat3(xdr, &status);
2293         if (unlikely(error))
2294                 goto out;
2295         error = decode_post_op_attr(xdr, result->fattr, rpc_rqst_userns(req));
2296         if (unlikely(error))
2297                 goto out;
2298         if (status != NFS3_OK)
2299                 goto out_status;
2300         error = decode_pathconf3resok(xdr, result);
2301 out:
2302         return error;
2303 out_status:
2304         return nfs_stat_to_errno(status);
2305 }
2306
2307 /*
2308  * 3.3.21  COMMIT3res
2309  *
2310  *      struct COMMIT3resok {
2311  *              wcc_data        file_wcc;
2312  *              writeverf3      verf;
2313  *      };
2314  *
2315  *      struct COMMIT3resfail {
2316  *              wcc_data        file_wcc;
2317  *      };
2318  *
2319  *      union COMMIT3res switch (nfsstat3 status) {
2320  *      case NFS3_OK:
2321  *              COMMIT3resok    resok;
2322  *      default:
2323  *              COMMIT3resfail  resfail;
2324  *      };
2325  */
2326 static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req,
2327                                    struct xdr_stream *xdr,
2328                                    void *data)
2329 {
2330         struct nfs_commitres *result = data;
2331         struct nfs_writeverf *verf = result->verf;
2332         enum nfs_stat status;
2333         int error;
2334
2335         error = decode_nfsstat3(xdr, &status);
2336         if (unlikely(error))
2337                 goto out;
2338         error = decode_wcc_data(xdr, result->fattr, rpc_rqst_userns(req));
2339         if (unlikely(error))
2340                 goto out;
2341         result->op_status = status;
2342         if (status != NFS3_OK)
2343                 goto out_status;
2344         error = decode_writeverf3(xdr, &verf->verifier);
2345         if (!error)
2346                 verf->committed = NFS_FILE_SYNC;
2347 out:
2348         return error;
2349 out_status:
2350         return nfs_stat_to_errno(status);
2351 }
2352
2353 #ifdef CONFIG_NFS_V3_ACL
2354
2355 static inline int decode_getacl3resok(struct xdr_stream *xdr,
2356                                       struct nfs3_getaclres *result,
2357                                       struct user_namespace *userns)
2358 {
2359         struct posix_acl **acl;
2360         unsigned int *aclcnt;
2361         size_t hdrlen;
2362         int error;
2363
2364         error = decode_post_op_attr(xdr, result->fattr, userns);
2365         if (unlikely(error))
2366                 goto out;
2367         error = decode_uint32(xdr, &result->mask);
2368         if (unlikely(error))
2369                 goto out;
2370         error = -EINVAL;
2371         if (result->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
2372                 goto out;
2373
2374         hdrlen = xdr_stream_pos(xdr);
2375
2376         acl = NULL;
2377         if (result->mask & NFS_ACL)
2378                 acl = &result->acl_access;
2379         aclcnt = NULL;
2380         if (result->mask & NFS_ACLCNT)
2381                 aclcnt = &result->acl_access_count;
2382         error = nfsacl_decode(xdr->buf, hdrlen, aclcnt, acl);
2383         if (unlikely(error <= 0))
2384                 goto out;
2385
2386         acl = NULL;
2387         if (result->mask & NFS_DFACL)
2388                 acl = &result->acl_default;
2389         aclcnt = NULL;
2390         if (result->mask & NFS_DFACLCNT)
2391                 aclcnt = &result->acl_default_count;
2392         error = nfsacl_decode(xdr->buf, hdrlen + error, aclcnt, acl);
2393         if (unlikely(error <= 0))
2394                 return error;
2395         error = 0;
2396 out:
2397         return error;
2398 }
2399
2400 static int nfs3_xdr_dec_getacl3res(struct rpc_rqst *req,
2401                                    struct xdr_stream *xdr,
2402                                    void *result)
2403 {
2404         enum nfs_stat status;
2405         int error;
2406
2407         error = decode_nfsstat3(xdr, &status);
2408         if (unlikely(error))
2409                 goto out;
2410         if (status != NFS3_OK)
2411                 goto out_default;
2412         error = decode_getacl3resok(xdr, result, rpc_rqst_userns(req));
2413 out:
2414         return error;
2415 out_default:
2416         return nfs_stat_to_errno(status);
2417 }
2418
2419 static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req,
2420                                    struct xdr_stream *xdr,
2421                                    void *result)
2422 {
2423         enum nfs_stat status;
2424         int error;
2425
2426         error = decode_nfsstat3(xdr, &status);
2427         if (unlikely(error))
2428                 goto out;
2429         if (status != NFS3_OK)
2430                 goto out_default;
2431         error = decode_post_op_attr(xdr, result, rpc_rqst_userns(req));
2432 out:
2433         return error;
2434 out_default:
2435         return nfs_stat_to_errno(status);
2436 }
2437
2438 #endif  /* CONFIG_NFS_V3_ACL */
2439
2440 #define PROC(proc, argtype, restype, timer)                             \
2441 [NFS3PROC_##proc] = {                                                   \
2442         .p_proc      = NFS3PROC_##proc,                                 \
2443         .p_encode    = nfs3_xdr_enc_##argtype##3args,                   \
2444         .p_decode    = nfs3_xdr_dec_##restype##3res,                    \
2445         .p_arglen    = NFS3_##argtype##args_sz,                         \
2446         .p_replen    = NFS3_##restype##res_sz,                          \
2447         .p_timer     = timer,                                           \
2448         .p_statidx   = NFS3PROC_##proc,                                 \
2449         .p_name      = #proc,                                           \
2450         }
2451
2452 const struct rpc_procinfo nfs3_procedures[] = {
2453         PROC(GETATTR,           getattr,        getattr,        1),
2454         PROC(SETATTR,           setattr,        setattr,        0),
2455         PROC(LOOKUP,            lookup,         lookup,         2),
2456         PROC(ACCESS,            access,         access,         1),
2457         PROC(READLINK,          readlink,       readlink,       3),
2458         PROC(READ,              read,           read,           3),
2459         PROC(WRITE,             write,          write,          4),
2460         PROC(CREATE,            create,         create,         0),
2461         PROC(MKDIR,             mkdir,          create,         0),
2462         PROC(SYMLINK,           symlink,        create,         0),
2463         PROC(MKNOD,             mknod,          create,         0),
2464         PROC(REMOVE,            remove,         remove,         0),
2465         PROC(RMDIR,             lookup,         setattr,        0),
2466         PROC(RENAME,            rename,         rename,         0),
2467         PROC(LINK,              link,           link,           0),
2468         PROC(READDIR,           readdir,        readdir,        3),
2469         PROC(READDIRPLUS,       readdirplus,    readdir,        3),
2470         PROC(FSSTAT,            getattr,        fsstat,         0),
2471         PROC(FSINFO,            getattr,        fsinfo,         0),
2472         PROC(PATHCONF,          getattr,        pathconf,       0),
2473         PROC(COMMIT,            commit,         commit,         5),
2474 };
2475
2476 static unsigned int nfs_version3_counts[ARRAY_SIZE(nfs3_procedures)];
2477 const struct rpc_version nfs_version3 = {
2478         .number                 = 3,
2479         .nrprocs                = ARRAY_SIZE(nfs3_procedures),
2480         .procs                  = nfs3_procedures,
2481         .counts                 = nfs_version3_counts,
2482 };
2483
2484 #ifdef CONFIG_NFS_V3_ACL
2485 static const struct rpc_procinfo nfs3_acl_procedures[] = {
2486         [ACLPROC3_GETACL] = {
2487                 .p_proc = ACLPROC3_GETACL,
2488                 .p_encode = nfs3_xdr_enc_getacl3args,
2489                 .p_decode = nfs3_xdr_dec_getacl3res,
2490                 .p_arglen = ACL3_getaclargs_sz,
2491                 .p_replen = ACL3_getaclres_sz,
2492                 .p_timer = 1,
2493                 .p_name = "GETACL",
2494         },
2495         [ACLPROC3_SETACL] = {
2496                 .p_proc = ACLPROC3_SETACL,
2497                 .p_encode = nfs3_xdr_enc_setacl3args,
2498                 .p_decode = nfs3_xdr_dec_setacl3res,
2499                 .p_arglen = ACL3_setaclargs_sz,
2500                 .p_replen = ACL3_setaclres_sz,
2501                 .p_timer = 0,
2502                 .p_name = "SETACL",
2503         },
2504 };
2505
2506 static unsigned int nfs3_acl_counts[ARRAY_SIZE(nfs3_acl_procedures)];
2507 const struct rpc_version nfsacl_version3 = {
2508         .number                 = 3,
2509         .nrprocs                = ARRAY_SIZE(nfs3_acl_procedures),
2510         .procs                  = nfs3_acl_procedures,
2511         .counts                 = nfs3_acl_counts,
2512 };
2513 #endif  /* CONFIG_NFS_V3_ACL */
This page took 0.170205 seconds and 4 git commands to generate.