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