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