NFS: Switch in new NFSv3 decoder functions
[pandora-kernel.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 /*
90  * Map file type to S_IFMT bits
91  */
92 static const umode_t nfs_type2fmt[] = {
93         [NF3BAD] = 0,
94         [NF3REG] = S_IFREG,
95         [NF3DIR] = S_IFDIR,
96         [NF3BLK] = S_IFBLK,
97         [NF3CHR] = S_IFCHR,
98         [NF3LNK] = S_IFLNK,
99         [NF3SOCK] = S_IFSOCK,
100         [NF3FIFO] = S_IFIFO,
101 };
102
103 /*
104  * While encoding arguments, set up the reply buffer in advance to
105  * receive reply data directly into the page cache.
106  */
107 static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
108                                  unsigned int base, unsigned int len,
109                                  unsigned int bufsize)
110 {
111         struct rpc_auth *auth = req->rq_cred->cr_auth;
112         unsigned int replen;
113
114         replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
115         xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
116 }
117
118 /*
119  * Handle decode buffer overflows out-of-line.
120  */
121 static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
122 {
123         dprintk("NFS: %s prematurely hit the end of our receive buffer. "
124                 "Remaining buffer length is %tu words.\n",
125                 func, xdr->end - xdr->p);
126 }
127
128
129 /*
130  * Common NFS XDR functions as inlines
131  */
132 static inline __be32 *
133 xdr_decode_fhandle(__be32 *p, struct nfs_fh *fh)
134 {
135         if ((fh->size = ntohl(*p++)) <= NFS3_FHSIZE) {
136                 memcpy(fh->data, p, fh->size);
137                 return p + XDR_QUADLEN(fh->size);
138         }
139         return NULL;
140 }
141
142 static inline __be32 *
143 xdr_decode_fhandle_stream(struct xdr_stream *xdr, struct nfs_fh *fh)
144 {
145         __be32 *p;
146         p = xdr_inline_decode(xdr, 4);
147         if (unlikely(!p))
148                 goto out_overflow;
149         fh->size = ntohl(*p++);
150
151         if (fh->size <= NFS3_FHSIZE) {
152                 p = xdr_inline_decode(xdr, fh->size);
153                 if (unlikely(!p))
154                         goto out_overflow;
155                 memcpy(fh->data, p, fh->size);
156                 return p + XDR_QUADLEN(fh->size);
157         }
158         return NULL;
159
160 out_overflow:
161         print_overflow_msg(__func__, xdr);
162         return ERR_PTR(-EIO);
163 }
164
165 /*
166  * Encode/decode time.
167  */
168 static inline __be32 *
169 xdr_decode_time3(__be32 *p, struct timespec *timep)
170 {
171         timep->tv_sec = ntohl(*p++);
172         timep->tv_nsec = ntohl(*p++);
173         return p;
174 }
175
176 static __be32 *
177 xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
178 {
179         unsigned int    type, major, minor;
180         umode_t         fmode;
181
182         type = ntohl(*p++);
183         if (type > NF3FIFO)
184                 type = NF3NON;
185         fmode = nfs_type2fmt[type];
186         fattr->mode = (ntohl(*p++) & ~S_IFMT) | fmode;
187         fattr->nlink = ntohl(*p++);
188         fattr->uid = ntohl(*p++);
189         fattr->gid = ntohl(*p++);
190         p = xdr_decode_hyper(p, &fattr->size);
191         p = xdr_decode_hyper(p, &fattr->du.nfs3.used);
192
193         /* Turn remote device info into Linux-specific dev_t */
194         major = ntohl(*p++);
195         minor = ntohl(*p++);
196         fattr->rdev = MKDEV(major, minor);
197         if (MAJOR(fattr->rdev) != major || MINOR(fattr->rdev) != minor)
198                 fattr->rdev = 0;
199
200         p = xdr_decode_hyper(p, &fattr->fsid.major);
201         fattr->fsid.minor = 0;
202         p = xdr_decode_hyper(p, &fattr->fileid);
203         p = xdr_decode_time3(p, &fattr->atime);
204         p = xdr_decode_time3(p, &fattr->mtime);
205         p = xdr_decode_time3(p, &fattr->ctime);
206
207         /* Update the mode bits */
208         fattr->valid |= NFS_ATTR_FATTR_V3;
209         return p;
210 }
211
212 static inline __be32 *
213 xdr_decode_wcc_attr(__be32 *p, struct nfs_fattr *fattr)
214 {
215         p = xdr_decode_hyper(p, &fattr->pre_size);
216         p = xdr_decode_time3(p, &fattr->pre_mtime);
217         p = xdr_decode_time3(p, &fattr->pre_ctime);
218         fattr->valid |= NFS_ATTR_FATTR_PRESIZE
219                 | NFS_ATTR_FATTR_PREMTIME
220                 | NFS_ATTR_FATTR_PRECTIME;
221         return p;
222 }
223
224 static inline __be32 *
225 xdr_decode_post_op_attr(__be32 *p, struct nfs_fattr *fattr)
226 {
227         if (*p++)
228                 p = xdr_decode_fattr(p, fattr);
229         return p;
230 }
231
232 static inline __be32 *
233 xdr_decode_post_op_attr_stream(struct xdr_stream *xdr, struct nfs_fattr *fattr)
234 {
235         __be32 *p;
236
237         p = xdr_inline_decode(xdr, 4);
238         if (unlikely(!p))
239                 goto out_overflow;
240         if (ntohl(*p++)) {
241                 p = xdr_inline_decode(xdr, 84);
242                 if (unlikely(!p))
243                         goto out_overflow;
244                 p = xdr_decode_fattr(p, fattr);
245         }
246         return p;
247 out_overflow:
248         print_overflow_msg(__func__, xdr);
249         return ERR_PTR(-EIO);
250 }
251
252 static inline __be32 *
253 xdr_decode_pre_op_attr(__be32 *p, struct nfs_fattr *fattr)
254 {
255         if (*p++)
256                 return xdr_decode_wcc_attr(p, fattr);
257         return p;
258 }
259
260
261 static inline __be32 *
262 xdr_decode_wcc_data(__be32 *p, struct nfs_fattr *fattr)
263 {
264         p = xdr_decode_pre_op_attr(p, fattr);
265         return xdr_decode_post_op_attr(p, fattr);
266 }
267
268
269 /*
270  * Encode/decode NFSv3 basic data types
271  *
272  * Basic NFSv3 data types are defined in section 2.5 of RFC 1813:
273  * "NFS Version 3 Protocol Specification".
274  *
275  * Not all basic data types have their own encoding and decoding
276  * functions.  For run-time efficiency, some data types are encoded
277  * or decoded inline.
278  */
279
280 static void encode_uint32(struct xdr_stream *xdr, u32 value)
281 {
282         __be32 *p = xdr_reserve_space(xdr, 4);
283         *p = cpu_to_be32(value);
284 }
285
286 static int decode_uint32(struct xdr_stream *xdr, u32 *value)
287 {
288         __be32 *p;
289
290         p = xdr_inline_decode(xdr, 4);
291         if (unlikely(p == NULL))
292                 goto out_overflow;
293         *value = be32_to_cpup(p);
294         return 0;
295 out_overflow:
296         print_overflow_msg(__func__, xdr);
297         return -EIO;
298 }
299
300 static int decode_uint64(struct xdr_stream *xdr, u64 *value)
301 {
302         __be32 *p;
303
304         p = xdr_inline_decode(xdr, 8);
305         if (unlikely(p == NULL))
306                 goto out_overflow;
307         xdr_decode_hyper(p, value);
308         return 0;
309 out_overflow:
310         print_overflow_msg(__func__, xdr);
311         return -EIO;
312 }
313
314 /*
315  * fileid3
316  *
317  *      typedef uint64 fileid3;
318  */
319 static int decode_fileid3(struct xdr_stream *xdr, u64 *fileid)
320 {
321         return decode_uint64(xdr, fileid);
322 }
323
324 /*
325  * filename3
326  *
327  *      typedef string filename3<>;
328  */
329 static void encode_filename3(struct xdr_stream *xdr,
330                              const char *name, u32 length)
331 {
332         __be32 *p;
333
334         BUG_ON(length > NFS3_MAXNAMLEN);
335         p = xdr_reserve_space(xdr, 4 + length);
336         xdr_encode_opaque(p, name, length);
337 }
338
339 static int decode_inline_filename3(struct xdr_stream *xdr,
340                                    const char **name, u32 *length)
341 {
342         __be32 *p;
343         u32 count;
344
345         p = xdr_inline_decode(xdr, 4);
346         if (unlikely(p == NULL))
347                 goto out_overflow;
348         count = be32_to_cpup(p);
349         if (count > NFS3_MAXNAMLEN)
350                 goto out_nametoolong;
351         p = xdr_inline_decode(xdr, count);
352         if (unlikely(p == NULL))
353                 goto out_overflow;
354         *name = (const char *)p;
355         *length = count;
356         return 0;
357
358 out_nametoolong:
359         dprintk("NFS: returned filename too long: %u\n", count);
360         return -ENAMETOOLONG;
361 out_overflow:
362         print_overflow_msg(__func__, xdr);
363         return -EIO;
364 }
365
366 /*
367  * nfspath3
368  *
369  *      typedef string nfspath3<>;
370  */
371 static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages,
372                             const u32 length)
373 {
374         BUG_ON(length > NFS3_MAXPATHLEN);
375         encode_uint32(xdr, length);
376         xdr_write_pages(xdr, pages, 0, length);
377 }
378
379 static int decode_nfspath3(struct xdr_stream *xdr)
380 {
381         u32 recvd, count;
382         size_t hdrlen;
383         __be32 *p;
384
385         p = xdr_inline_decode(xdr, 4);
386         if (unlikely(p == NULL))
387                 goto out_overflow;
388         count = be32_to_cpup(p);
389         if (unlikely(count >= xdr->buf->page_len || count > NFS3_MAXPATHLEN))
390                 goto out_nametoolong;
391         hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
392         recvd = xdr->buf->len - hdrlen;
393         if (unlikely(count > recvd))
394                 goto out_cheating;
395
396         xdr_read_pages(xdr, count);
397         xdr_terminate_string(xdr->buf, count);
398         return 0;
399
400 out_nametoolong:
401         dprintk("NFS: returned pathname too long: %u\n", count);
402         return -ENAMETOOLONG;
403 out_cheating:
404         dprintk("NFS: server cheating in pathname result: "
405                 "count %u > recvd %u\n", count, recvd);
406         return -EIO;
407 out_overflow:
408         print_overflow_msg(__func__, xdr);
409         return -EIO;
410 }
411
412 /*
413  * cookie3
414  *
415  *      typedef uint64 cookie3
416  */
417 static __be32 *xdr_encode_cookie3(__be32 *p, u64 cookie)
418 {
419         return xdr_encode_hyper(p, cookie);
420 }
421
422 static int decode_cookie3(struct xdr_stream *xdr, u64 *cookie)
423 {
424         return decode_uint64(xdr, cookie);
425 }
426
427 /*
428  * cookieverf3
429  *
430  *      typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
431  */
432 static __be32 *xdr_encode_cookieverf3(__be32 *p, const __be32 *verifier)
433 {
434         memcpy(p, verifier, NFS3_COOKIEVERFSIZE);
435         return p + XDR_QUADLEN(NFS3_COOKIEVERFSIZE);
436 }
437
438 static int decode_cookieverf3(struct xdr_stream *xdr, __be32 *verifier)
439 {
440         __be32 *p;
441
442         p = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE);
443         if (unlikely(p == NULL))
444                 goto out_overflow;
445         memcpy(verifier, p, NFS3_COOKIEVERFSIZE);
446         return 0;
447 out_overflow:
448         print_overflow_msg(__func__, xdr);
449         return -EIO;
450 }
451
452 /*
453  * createverf3
454  *
455  *      typedef opaque createverf3[NFS3_CREATEVERFSIZE];
456  */
457 static void encode_createverf3(struct xdr_stream *xdr, const __be32 *verifier)
458 {
459         __be32 *p;
460
461         p = xdr_reserve_space(xdr, NFS3_CREATEVERFSIZE);
462         memcpy(p, verifier, NFS3_CREATEVERFSIZE);
463 }
464
465 static int decode_writeverf3(struct xdr_stream *xdr, __be32 *verifier)
466 {
467         __be32 *p;
468
469         p = xdr_inline_decode(xdr, NFS3_WRITEVERFSIZE);
470         if (unlikely(p == NULL))
471                 goto out_overflow;
472         memcpy(verifier, p, NFS3_WRITEVERFSIZE);
473         return 0;
474 out_overflow:
475         print_overflow_msg(__func__, xdr);
476         return -EIO;
477 }
478
479 /*
480  * size3
481  *
482  *      typedef uint64 size3;
483  */
484 static __be32 *xdr_decode_size3(__be32 *p, u64 *size)
485 {
486         return xdr_decode_hyper(p, size);
487 }
488
489 /*
490  * nfsstat3
491  *
492  *      enum nfsstat3 {
493  *              NFS3_OK = 0,
494  *              ...
495  *      }
496  */
497 #define NFS3_OK         NFS_OK
498
499 static int decode_nfsstat3(struct xdr_stream *xdr, enum nfs_stat *status)
500 {
501         __be32 *p;
502
503         p = xdr_inline_decode(xdr, 4);
504         if (unlikely(p == NULL))
505                 goto out_overflow;
506         *status = be32_to_cpup(p);
507         return 0;
508 out_overflow:
509         print_overflow_msg(__func__, xdr);
510         return -EIO;
511 }
512
513 /*
514  * ftype3
515  *
516  *      enum ftype3 {
517  *              NF3REG  = 1,
518  *              NF3DIR  = 2,
519  *              NF3BLK  = 3,
520  *              NF3CHR  = 4,
521  *              NF3LNK  = 5,
522  *              NF3SOCK = 6,
523  *              NF3FIFO = 7
524  *      };
525  */
526 static void encode_ftype3(struct xdr_stream *xdr, const u32 type)
527 {
528         BUG_ON(type > NF3FIFO);
529         encode_uint32(xdr, type);
530 }
531
532 /*
533  * specdata3
534  *
535  *     struct specdata3 {
536  *             uint32  specdata1;
537  *             uint32  specdata2;
538  *     };
539  */
540 static void encode_specdata3(struct xdr_stream *xdr, const dev_t rdev)
541 {
542         __be32 *p;
543
544         p = xdr_reserve_space(xdr, 8);
545         *p++ = cpu_to_be32(MAJOR(rdev));
546         *p = cpu_to_be32(MINOR(rdev));
547 }
548
549 /*
550  * nfs_fh3
551  *
552  *      struct nfs_fh3 {
553  *              opaque       data<NFS3_FHSIZE>;
554  *      };
555  */
556 static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh)
557 {
558         __be32 *p;
559
560         BUG_ON(fh->size > NFS3_FHSIZE);
561         p = xdr_reserve_space(xdr, 4 + fh->size);
562         xdr_encode_opaque(p, fh->data, fh->size);
563 }
564
565 static int decode_nfs_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
566 {
567         u32 length;
568         __be32 *p;
569
570         p = xdr_inline_decode(xdr, 4);
571         if (unlikely(p == NULL))
572                 goto out_overflow;
573         length = be32_to_cpup(p++);
574         if (unlikely(length > NFS3_FHSIZE))
575                 goto out_toobig;
576         p = xdr_inline_decode(xdr, length);
577         if (unlikely(p == NULL))
578                 goto out_overflow;
579         fh->size = length;
580         memcpy(fh->data, p, length);
581         return 0;
582 out_toobig:
583         dprintk("NFS: file handle size (%u) too big\n", length);
584         return -E2BIG;
585 out_overflow:
586         print_overflow_msg(__func__, xdr);
587         return -EIO;
588 }
589
590 static void zero_nfs_fh3(struct nfs_fh *fh)
591 {
592         memset(fh, 0, sizeof(*fh));
593 }
594
595 /*
596  * nfstime3
597  *
598  *      struct nfstime3 {
599  *              uint32  seconds;
600  *              uint32  nseconds;
601  *      };
602  */
603 static __be32 *xdr_encode_nfstime3(__be32 *p, const struct timespec *timep)
604 {
605         *p++ = cpu_to_be32(timep->tv_sec);
606         *p++ = cpu_to_be32(timep->tv_nsec);
607         return p;
608 }
609
610 /*
611  * sattr3
612  *
613  *      enum time_how {
614  *              DONT_CHANGE             = 0,
615  *              SET_TO_SERVER_TIME      = 1,
616  *              SET_TO_CLIENT_TIME      = 2
617  *      };
618  *
619  *      union set_mode3 switch (bool set_it) {
620  *      case TRUE:
621  *              mode3   mode;
622  *      default:
623  *              void;
624  *      };
625  *
626  *      union set_uid3 switch (bool set_it) {
627  *      case TRUE:
628  *              uid3    uid;
629  *      default:
630  *              void;
631  *      };
632  *
633  *      union set_gid3 switch (bool set_it) {
634  *      case TRUE:
635  *              gid3    gid;
636  *      default:
637  *              void;
638  *      };
639  *
640  *      union set_size3 switch (bool set_it) {
641  *      case TRUE:
642  *              size3   size;
643  *      default:
644  *              void;
645  *      };
646  *
647  *      union set_atime switch (time_how set_it) {
648  *      case SET_TO_CLIENT_TIME:
649  *              nfstime3        atime;
650  *      default:
651  *              void;
652  *      };
653  *
654  *      union set_mtime switch (time_how set_it) {
655  *      case SET_TO_CLIENT_TIME:
656  *              nfstime3  mtime;
657  *      default:
658  *              void;
659  *      };
660  *
661  *      struct sattr3 {
662  *              set_mode3       mode;
663  *              set_uid3        uid;
664  *              set_gid3        gid;
665  *              set_size3       size;
666  *              set_atime       atime;
667  *              set_mtime       mtime;
668  *      };
669  */
670 static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)
671 {
672         u32 nbytes;
673         __be32 *p;
674
675         /*
676          * In order to make only a single xdr_reserve_space() call,
677          * pre-compute the total number of bytes to be reserved.
678          * Six boolean values, one for each set_foo field, are always
679          * present in the encoded result, so start there.
680          */
681         nbytes = 6 * 4;
682         if (attr->ia_valid & ATTR_MODE)
683                 nbytes += 4;
684         if (attr->ia_valid & ATTR_UID)
685                 nbytes += 4;
686         if (attr->ia_valid & ATTR_GID)
687                 nbytes += 4;
688         if (attr->ia_valid & ATTR_SIZE)
689                 nbytes += 8;
690         if (attr->ia_valid & ATTR_ATIME_SET)
691                 nbytes += 8;
692         if (attr->ia_valid & ATTR_MTIME_SET)
693                 nbytes += 8;
694         p = xdr_reserve_space(xdr, nbytes);
695
696         if (attr->ia_valid & ATTR_MODE) {
697                 *p++ = xdr_one;
698                 *p++ = cpu_to_be32(attr->ia_mode & S_IALLUGO);
699         } else
700                 *p++ = xdr_zero;
701
702         if (attr->ia_valid & ATTR_UID) {
703                 *p++ = xdr_one;
704                 *p++ = cpu_to_be32(attr->ia_uid);
705         } else
706                 *p++ = xdr_zero;
707
708         if (attr->ia_valid & ATTR_GID) {
709                 *p++ = xdr_one;
710                 *p++ = cpu_to_be32(attr->ia_gid);
711         } else
712                 *p++ = xdr_zero;
713
714         if (attr->ia_valid & ATTR_SIZE) {
715                 *p++ = xdr_one;
716                 p = xdr_encode_hyper(p, (u64)attr->ia_size);
717         } else
718                 *p++ = xdr_zero;
719
720         if (attr->ia_valid & ATTR_ATIME_SET) {
721                 *p++ = xdr_two;
722                 p = xdr_encode_nfstime3(p, &attr->ia_atime);
723         } else if (attr->ia_valid & ATTR_ATIME) {
724                 *p++ = xdr_one;
725         } else
726                 *p++ = xdr_zero;
727
728         if (attr->ia_valid & ATTR_MTIME_SET) {
729                 *p++ = xdr_two;
730                 xdr_encode_nfstime3(p, &attr->ia_mtime);
731         } else if (attr->ia_valid & ATTR_MTIME) {
732                 *p = xdr_one;
733         } else
734                 *p = xdr_zero;
735 }
736
737 /*
738  * fattr3
739  *
740  *      struct fattr3 {
741  *              ftype3          type;
742  *              mode3           mode;
743  *              uint32          nlink;
744  *              uid3            uid;
745  *              gid3            gid;
746  *              size3           size;
747  *              size3           used;
748  *              specdata3       rdev;
749  *              uint64          fsid;
750  *              fileid3         fileid;
751  *              nfstime3        atime;
752  *              nfstime3        mtime;
753  *              nfstime3        ctime;
754  *      };
755  */
756 static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr)
757 {
758         __be32 *p;
759
760         p = xdr_inline_decode(xdr, NFS3_fattr_sz << 2);
761         if (unlikely(p == NULL))
762                 goto out_overflow;
763         xdr_decode_fattr(p, fattr);
764         return 0;
765 out_overflow:
766         print_overflow_msg(__func__, xdr);
767         return -EIO;
768 }
769
770 /*
771  * post_op_attr
772  *
773  *      union post_op_attr switch (bool attributes_follow) {
774  *      case TRUE:
775  *              fattr3  attributes;
776  *      case FALSE:
777  *              void;
778  *      };
779  */
780 static int decode_post_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
781 {
782         __be32 *p;
783
784         p = xdr_inline_decode(xdr, 4);
785         if (unlikely(p == NULL))
786                 goto out_overflow;
787         if (*p != xdr_zero)
788                 return decode_fattr3(xdr, fattr);
789         return 0;
790 out_overflow:
791         print_overflow_msg(__func__, xdr);
792         return -EIO;
793 }
794
795 /*
796  * wcc_attr
797  *      struct wcc_attr {
798  *              size3           size;
799  *              nfstime3        mtime;
800  *              nfstime3        ctime;
801  *      };
802  */
803 static int decode_wcc_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
804 {
805         __be32 *p;
806
807         p = xdr_inline_decode(xdr, NFS3_wcc_attr_sz << 2);
808         if (unlikely(p == NULL))
809                 goto out_overflow;
810         xdr_decode_wcc_attr(p, fattr);
811         return 0;
812 out_overflow:
813         print_overflow_msg(__func__, xdr);
814         return -EIO;
815 }
816
817 /*
818  * pre_op_attr
819  *      union pre_op_attr switch (bool attributes_follow) {
820  *      case TRUE:
821  *              wcc_attr        attributes;
822  *      case FALSE:
823  *              void;
824  *      };
825  *
826  * wcc_data
827  *
828  *      struct wcc_data {
829  *              pre_op_attr     before;
830  *              post_op_attr    after;
831  *      };
832  */
833 static int decode_pre_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
834 {
835         __be32 *p;
836
837         p = xdr_inline_decode(xdr, 4);
838         if (unlikely(p == NULL))
839                 goto out_overflow;
840         if (*p != xdr_zero)
841                 return decode_wcc_attr(xdr, fattr);
842         return 0;
843 out_overflow:
844         print_overflow_msg(__func__, xdr);
845         return -EIO;
846 }
847
848 static int decode_wcc_data(struct xdr_stream *xdr, struct nfs_fattr *fattr)
849 {
850         int error;
851
852         error = decode_pre_op_attr(xdr, fattr);
853         if (unlikely(error))
854                 goto out;
855         error = decode_post_op_attr(xdr, fattr);
856 out:
857         return error;
858 }
859
860 /*
861  * post_op_fh3
862  *
863  *      union post_op_fh3 switch (bool handle_follows) {
864  *      case TRUE:
865  *              nfs_fh3  handle;
866  *      case FALSE:
867  *              void;
868  *      };
869  */
870 static int decode_post_op_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
871 {
872         __be32 *p = xdr_inline_decode(xdr, 4);
873         if (unlikely(p == NULL))
874                 goto out_overflow;
875         if (*p != xdr_zero)
876                 return decode_nfs_fh3(xdr, fh);
877         zero_nfs_fh3(fh);
878         return 0;
879 out_overflow:
880         print_overflow_msg(__func__, xdr);
881         return -EIO;
882 }
883
884 /*
885  * diropargs3
886  *
887  *      struct diropargs3 {
888  *              nfs_fh3         dir;
889  *              filename3       name;
890  *      };
891  */
892 static void encode_diropargs3(struct xdr_stream *xdr, const struct nfs_fh *fh,
893                               const char *name, u32 length)
894 {
895         encode_nfs_fh3(xdr, fh);
896         encode_filename3(xdr, name, length);
897 }
898
899
900 /*
901  * NFSv3 XDR encode functions
902  *
903  * NFSv3 argument types are defined in section 3.3 of RFC 1813:
904  * "NFS Version 3 Protocol Specification".
905  */
906
907 /*
908  * 3.3.1  GETATTR3args
909  *
910  *      struct GETATTR3args {
911  *              nfs_fh3  object;
912  *      };
913  */
914 static int nfs3_xdr_enc_getattr3args(struct rpc_rqst *req, __be32 *p,
915                                      const struct nfs_fh *fh)
916 {
917         struct xdr_stream xdr;
918
919         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
920         encode_nfs_fh3(&xdr, fh);
921         return 0;
922 }
923
924 /*
925  * 3.3.2  SETATTR3args
926  *
927  *      union sattrguard3 switch (bool check) {
928  *      case TRUE:
929  *              nfstime3  obj_ctime;
930  *      case FALSE:
931  *              void;
932  *      };
933  *
934  *      struct SETATTR3args {
935  *              nfs_fh3         object;
936  *              sattr3          new_attributes;
937  *              sattrguard3     guard;
938  *      };
939  */
940 static void encode_sattrguard3(struct xdr_stream *xdr,
941                                const struct nfs3_sattrargs *args)
942 {
943         __be32 *p;
944
945         if (args->guard) {
946                 p = xdr_reserve_space(xdr, 4 + 8);
947                 *p++ = xdr_one;
948                 xdr_encode_nfstime3(p, &args->guardtime);
949         } else {
950                 p = xdr_reserve_space(xdr, 4);
951                 *p = xdr_zero;
952         }
953 }
954
955 static int nfs3_xdr_enc_setattr3args(struct rpc_rqst *req, __be32 *p,
956                                      const struct nfs3_sattrargs *args)
957 {
958         struct xdr_stream xdr;
959
960         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
961         encode_nfs_fh3(&xdr, args->fh);
962         encode_sattr3(&xdr, args->sattr);
963         encode_sattrguard3(&xdr, args);
964         return 0;
965 }
966
967 /*
968  * 3.3.3  LOOKUP3args
969  *
970  *      struct LOOKUP3args {
971  *              diropargs3  what;
972  *      };
973  */
974 static int nfs3_xdr_enc_lookup3args(struct rpc_rqst *req, __be32 *p,
975                                     const struct nfs3_diropargs *args)
976 {
977         struct xdr_stream xdr;
978
979         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
980         encode_diropargs3(&xdr, args->fh, args->name, args->len);
981         return 0;
982 }
983
984 /*
985  * 3.3.4  ACCESS3args
986  *
987  *      struct ACCESS3args {
988  *              nfs_fh3         object;
989  *              uint32          access;
990  *      };
991  */
992 static void encode_access3args(struct xdr_stream *xdr,
993                                const struct nfs3_accessargs *args)
994 {
995         encode_nfs_fh3(xdr, args->fh);
996         encode_uint32(xdr, args->access);
997 }
998
999 static int nfs3_xdr_enc_access3args(struct rpc_rqst *req, __be32 *p,
1000                                     const struct nfs3_accessargs *args)
1001 {
1002         struct xdr_stream xdr;
1003
1004         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1005         encode_access3args(&xdr, args);
1006         return 0;
1007 }
1008
1009 /*
1010  * 3.3.5  READLINK3args
1011  *
1012  *      struct READLINK3args {
1013  *              nfs_fh3 symlink;
1014  *      };
1015  */
1016 static int nfs3_xdr_enc_readlink3args(struct rpc_rqst *req, __be32 *p,
1017                                       const struct nfs3_readlinkargs *args)
1018 {
1019         struct xdr_stream xdr;
1020
1021         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1022         encode_nfs_fh3(&xdr, args->fh);
1023         prepare_reply_buffer(req, args->pages, args->pgbase,
1024                                         args->pglen, NFS3_readlinkres_sz);
1025         return 0;
1026 }
1027
1028 /*
1029  * 3.3.6  READ3args
1030  *
1031  *      struct READ3args {
1032  *              nfs_fh3         file;
1033  *              offset3         offset;
1034  *              count3          count;
1035  *      };
1036  */
1037 static void encode_read3args(struct xdr_stream *xdr,
1038                              const struct nfs_readargs *args)
1039 {
1040         __be32 *p;
1041
1042         encode_nfs_fh3(xdr, args->fh);
1043
1044         p = xdr_reserve_space(xdr, 8 + 4);
1045         p = xdr_encode_hyper(p, args->offset);
1046         *p = cpu_to_be32(args->count);
1047 }
1048
1049 static int nfs3_xdr_enc_read3args(struct rpc_rqst *req, __be32 *p,
1050                                   const struct nfs_readargs *args)
1051 {
1052         struct xdr_stream xdr;
1053
1054         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1055         encode_read3args(&xdr, args);
1056         prepare_reply_buffer(req, args->pages, args->pgbase,
1057                                         args->count, NFS3_readres_sz);
1058         req->rq_rcv_buf.flags |= XDRBUF_READ;
1059         return 0;
1060 }
1061
1062 /*
1063  * 3.3.7  WRITE3args
1064  *
1065  *      enum stable_how {
1066  *              UNSTABLE  = 0,
1067  *              DATA_SYNC = 1,
1068  *              FILE_SYNC = 2
1069  *      };
1070  *
1071  *      struct WRITE3args {
1072  *              nfs_fh3         file;
1073  *              offset3         offset;
1074  *              count3          count;
1075  *              stable_how      stable;
1076  *              opaque          data<>;
1077  *      };
1078  */
1079 static void encode_write3args(struct xdr_stream *xdr,
1080                               const struct nfs_writeargs *args)
1081 {
1082         __be32 *p;
1083
1084         encode_nfs_fh3(xdr, args->fh);
1085
1086         p = xdr_reserve_space(xdr, 8 + 4 + 4 + 4);
1087         p = xdr_encode_hyper(p, args->offset);
1088         *p++ = cpu_to_be32(args->count);
1089
1090         BUG_ON(args->stable > NFS_FILE_SYNC);
1091         *p++ = cpu_to_be32(args->stable);
1092
1093         *p = cpu_to_be32(args->count);
1094         xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
1095 }
1096
1097 static int nfs3_xdr_enc_write3args(struct rpc_rqst *req, __be32 *p,
1098                                    const struct nfs_writeargs *args)
1099 {
1100         struct xdr_stream xdr;
1101
1102         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1103         encode_write3args(&xdr, args);
1104         xdr.buf->flags |= XDRBUF_WRITE;
1105         return 0;
1106 }
1107
1108 /*
1109  * 3.3.8  CREATE3args
1110  *
1111  *      enum createmode3 {
1112  *              UNCHECKED = 0,
1113  *              GUARDED   = 1,
1114  *              EXCLUSIVE = 2
1115  *      };
1116  *
1117  *      union createhow3 switch (createmode3 mode) {
1118  *      case UNCHECKED:
1119  *      case GUARDED:
1120  *              sattr3       obj_attributes;
1121  *      case EXCLUSIVE:
1122  *              createverf3  verf;
1123  *      };
1124  *
1125  *      struct CREATE3args {
1126  *              diropargs3      where;
1127  *              createhow3      how;
1128  *      };
1129  */
1130 static void encode_createhow3(struct xdr_stream *xdr,
1131                               const struct nfs3_createargs *args)
1132 {
1133         encode_uint32(xdr, args->createmode);
1134         switch (args->createmode) {
1135         case NFS3_CREATE_UNCHECKED:
1136         case NFS3_CREATE_GUARDED:
1137                 encode_sattr3(xdr, args->sattr);
1138                 break;
1139         case NFS3_CREATE_EXCLUSIVE:
1140                 encode_createverf3(xdr, args->verifier);
1141                 break;
1142         default:
1143                 BUG();
1144         }
1145 }
1146
1147 static int nfs3_xdr_enc_create3args(struct rpc_rqst *req, __be32 *p,
1148                                     const struct nfs3_createargs *args)
1149 {
1150         struct xdr_stream xdr;
1151
1152         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1153         encode_diropargs3(&xdr, args->fh, args->name, args->len);
1154         encode_createhow3(&xdr, args);
1155         return 0;
1156 }
1157
1158 /*
1159  * 3.3.9  MKDIR3args
1160  *
1161  *      struct MKDIR3args {
1162  *              diropargs3      where;
1163  *              sattr3          attributes;
1164  *      };
1165  */
1166 static int nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req, __be32 *p,
1167                                    const struct nfs3_mkdirargs *args)
1168 {
1169         struct xdr_stream xdr;
1170
1171         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1172         encode_diropargs3(&xdr, args->fh, args->name, args->len);
1173         encode_sattr3(&xdr, args->sattr);
1174         return 0;
1175 }
1176
1177 /*
1178  * 3.3.10  SYMLINK3args
1179  *
1180  *      struct symlinkdata3 {
1181  *              sattr3          symlink_attributes;
1182  *              nfspath3        symlink_data;
1183  *      };
1184  *
1185  *      struct SYMLINK3args {
1186  *              diropargs3      where;
1187  *              symlinkdata3    symlink;
1188  *      };
1189  */
1190 static void encode_symlinkdata3(struct xdr_stream *xdr,
1191                                 const struct nfs3_symlinkargs *args)
1192 {
1193         encode_sattr3(xdr, args->sattr);
1194         encode_nfspath3(xdr, args->pages, args->pathlen);
1195 }
1196
1197 static int nfs3_xdr_enc_symlink3args(struct rpc_rqst *req, __be32 *p,
1198                                      const struct nfs3_symlinkargs *args)
1199 {
1200         struct xdr_stream xdr;
1201
1202         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1203         encode_diropargs3(&xdr, args->fromfh, args->fromname, args->fromlen);
1204         encode_symlinkdata3(&xdr, args);
1205         return 0;
1206 }
1207
1208 /*
1209  * 3.3.11  MKNOD3args
1210  *
1211  *      struct devicedata3 {
1212  *              sattr3          dev_attributes;
1213  *              specdata3       spec;
1214  *      };
1215  *
1216  *      union mknoddata3 switch (ftype3 type) {
1217  *      case NF3CHR:
1218  *      case NF3BLK:
1219  *              devicedata3     device;
1220  *      case NF3SOCK:
1221  *      case NF3FIFO:
1222  *              sattr3          pipe_attributes;
1223  *      default:
1224  *              void;
1225  *      };
1226  *
1227  *      struct MKNOD3args {
1228  *              diropargs3      where;
1229  *              mknoddata3      what;
1230  *      };
1231  */
1232 static void encode_devicedata3(struct xdr_stream *xdr,
1233                                const struct nfs3_mknodargs *args)
1234 {
1235         encode_sattr3(xdr, args->sattr);
1236         encode_specdata3(xdr, args->rdev);
1237 }
1238
1239 static void encode_mknoddata3(struct xdr_stream *xdr,
1240                               const struct nfs3_mknodargs *args)
1241 {
1242         encode_ftype3(xdr, args->type);
1243         switch (args->type) {
1244         case NF3CHR:
1245         case NF3BLK:
1246                 encode_devicedata3(xdr, args);
1247                 break;
1248         case NF3SOCK:
1249         case NF3FIFO:
1250                 encode_sattr3(xdr, args->sattr);
1251                 break;
1252         case NF3REG:
1253         case NF3DIR:
1254                 break;
1255         default:
1256                 BUG();
1257         }
1258 }
1259
1260 static int nfs3_xdr_enc_mknod3args(struct rpc_rqst *req, __be32 *p,
1261                                    const struct nfs3_mknodargs *args)
1262 {
1263         struct xdr_stream xdr;
1264
1265         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1266         encode_diropargs3(&xdr, args->fh, args->name, args->len);
1267         encode_mknoddata3(&xdr, args);
1268         return 0;
1269 }
1270
1271 /*
1272  * 3.3.12  REMOVE3args
1273  *
1274  *      struct REMOVE3args {
1275  *              diropargs3  object;
1276  *      };
1277  */
1278 static int nfs3_xdr_enc_remove3args(struct rpc_rqst *req, __be32 *p,
1279                                     const struct nfs_removeargs *args)
1280 {
1281         struct xdr_stream xdr;
1282
1283         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1284         encode_diropargs3(&xdr, args->fh, args->name.name, args->name.len);
1285         return 0;
1286 }
1287
1288 /*
1289  * 3.3.14  RENAME3args
1290  *
1291  *      struct RENAME3args {
1292  *              diropargs3      from;
1293  *              diropargs3      to;
1294  *      };
1295  */
1296 static int nfs3_xdr_enc_rename3args(struct rpc_rqst *req, __be32 *p,
1297                                     const struct nfs_renameargs *args)
1298 {
1299         const struct qstr *old = args->old_name;
1300         const struct qstr *new = args->new_name;
1301         struct xdr_stream xdr;
1302
1303         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1304         encode_diropargs3(&xdr, args->old_dir, old->name, old->len);
1305         encode_diropargs3(&xdr, args->new_dir, new->name, new->len);
1306         return 0;
1307 }
1308
1309 /*
1310  * 3.3.15  LINK3args
1311  *
1312  *      struct LINK3args {
1313  *              nfs_fh3         file;
1314  *              diropargs3      link;
1315  *      };
1316  */
1317 static int nfs3_xdr_enc_link3args(struct rpc_rqst *req, __be32 *p,
1318                                   const struct nfs3_linkargs *args)
1319 {
1320         struct xdr_stream xdr;
1321
1322         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1323         encode_nfs_fh3(&xdr, args->fromfh);
1324         encode_diropargs3(&xdr, args->tofh, args->toname, args->tolen);
1325         return 0;
1326 }
1327
1328 /*
1329  * 3.3.16  READDIR3args
1330  *
1331  *      struct READDIR3args {
1332  *              nfs_fh3         dir;
1333  *              cookie3         cookie;
1334  *              cookieverf3     cookieverf;
1335  *              count3          count;
1336  *      };
1337  */
1338 static void encode_readdir3args(struct xdr_stream *xdr,
1339                                 const struct nfs3_readdirargs *args)
1340 {
1341         __be32 *p;
1342
1343         encode_nfs_fh3(xdr, args->fh);
1344
1345         p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4);
1346         p = xdr_encode_cookie3(p, args->cookie);
1347         p = xdr_encode_cookieverf3(p, args->verf);
1348         *p = cpu_to_be32(args->count);
1349 }
1350
1351 static int nfs3_xdr_enc_readdir3args(struct rpc_rqst *req, __be32 *p,
1352                                      const struct nfs3_readdirargs *args)
1353 {
1354         struct xdr_stream xdr;
1355
1356         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1357         encode_readdir3args(&xdr, args);
1358         prepare_reply_buffer(req, args->pages, 0,
1359                                 args->count, NFS3_readdirres_sz);
1360         return 0;
1361 }
1362
1363 /*
1364  * 3.3.17  READDIRPLUS3args
1365  *
1366  *      struct READDIRPLUS3args {
1367  *              nfs_fh3         dir;
1368  *              cookie3         cookie;
1369  *              cookieverf3     cookieverf;
1370  *              count3          dircount;
1371  *              count3          maxcount;
1372  *      };
1373  */
1374 static void encode_readdirplus3args(struct xdr_stream *xdr,
1375                                     const struct nfs3_readdirargs *args)
1376 {
1377         __be32 *p;
1378
1379         encode_nfs_fh3(xdr, args->fh);
1380
1381         p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4 + 4);
1382         p = xdr_encode_cookie3(p, args->cookie);
1383         p = xdr_encode_cookieverf3(p, args->verf);
1384
1385         /*
1386          * readdirplus: need dircount + buffer size.
1387          * We just make sure we make dircount big enough
1388          */
1389         *p++ = cpu_to_be32(args->count >> 3);
1390
1391         *p = cpu_to_be32(args->count);
1392 }
1393
1394 static int nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req, __be32 *p,
1395                                          const struct nfs3_readdirargs *args)
1396 {
1397         struct xdr_stream xdr;
1398
1399         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1400         encode_readdirplus3args(&xdr, args);
1401         prepare_reply_buffer(req, args->pages, 0,
1402                                 args->count, NFS3_readdirres_sz);
1403         return 0;
1404 }
1405
1406 /*
1407  * Decode the result of a readdir call.
1408  * We just check for syntactical correctness.
1409  */
1410 static int
1411 nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res)
1412 {
1413         struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
1414         struct kvec *iov = rcvbuf->head;
1415         struct page **page;
1416         size_t hdrlen;
1417         u32 recvd, pglen;
1418         int status;
1419
1420         status = ntohl(*p++);
1421         /* Decode post_op_attrs */
1422         p = xdr_decode_post_op_attr(p, res->dir_attr);
1423         if (status)
1424                 return nfs_stat_to_errno(status);
1425         /* Decode verifier cookie */
1426         if (res->verf) {
1427                 res->verf[0] = *p++;
1428                 res->verf[1] = *p++;
1429         } else {
1430                 p += 2;
1431         }
1432
1433         hdrlen = (u8 *) p - (u8 *) iov->iov_base;
1434         if (iov->iov_len < hdrlen) {
1435                 dprintk("NFS: READDIR reply header overflowed:"
1436                                 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1437                 return -errno_NFSERR_IO;
1438         } else if (iov->iov_len != hdrlen) {
1439                 dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
1440                 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
1441         }
1442
1443         pglen = rcvbuf->page_len;
1444         recvd = rcvbuf->len - hdrlen;
1445         if (pglen > recvd)
1446                 pglen = recvd;
1447         page = rcvbuf->pages;
1448
1449         return pglen;
1450 }
1451
1452 /*
1453  * 3.3.21  COMMIT3args
1454  *
1455  *      struct COMMIT3args {
1456  *              nfs_fh3         file;
1457  *              offset3         offset;
1458  *              count3          count;
1459  *      };
1460  */
1461 static void encode_commit3args(struct xdr_stream *xdr,
1462                                const struct nfs_writeargs *args)
1463 {
1464         __be32 *p;
1465
1466         encode_nfs_fh3(xdr, args->fh);
1467
1468         p = xdr_reserve_space(xdr, 8 + 4);
1469         p = xdr_encode_hyper(p, args->offset);
1470         *p = cpu_to_be32(args->count);
1471 }
1472
1473 static int nfs3_xdr_enc_commit3args(struct rpc_rqst *req, __be32 *p,
1474                                     const struct nfs_writeargs *args)
1475 {
1476         struct xdr_stream xdr;
1477
1478         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1479         encode_commit3args(&xdr, args);
1480         return 0;
1481 }
1482
1483 #ifdef CONFIG_NFS_V3_ACL
1484
1485 static int nfs3_xdr_enc_getacl3args(struct rpc_rqst *req, __be32 *p,
1486                                     const struct nfs3_getaclargs *args)
1487 {
1488         struct xdr_stream xdr;
1489
1490         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1491         encode_nfs_fh3(&xdr, args->fh);
1492         encode_uint32(&xdr, args->mask);
1493         if (args->mask & (NFS_ACL | NFS_DFACL))
1494                 prepare_reply_buffer(req, args->pages, 0,
1495                                         NFSACL_MAXPAGES << PAGE_SHIFT,
1496                                         ACL3_getaclres_sz);
1497         return 0;
1498 }
1499
1500 static int nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, __be32 *p,
1501                                     const struct nfs3_setaclargs *args)
1502 {
1503         struct xdr_stream xdr;
1504         unsigned int base;
1505         int error;
1506
1507         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1508         encode_nfs_fh3(&xdr, NFS_FH(args->inode));
1509         encode_uint32(&xdr, args->mask);
1510         if (args->npages != 0)
1511                 xdr_write_pages(&xdr, args->pages, 0, args->len);
1512
1513         base = req->rq_slen;
1514         error = nfsacl_encode(xdr.buf, base, args->inode,
1515                             (args->mask & NFS_ACL) ?
1516                             args->acl_access : NULL, 1, 0);
1517         BUG_ON(error < 0);
1518         error = nfsacl_encode(xdr.buf, base + error, args->inode,
1519                             (args->mask & NFS_DFACL) ?
1520                             args->acl_default : NULL, 1,
1521                             NFS_ACL_DEFAULT);
1522         BUG_ON(error < 0);
1523         return 0;
1524 }
1525
1526 #endif  /* CONFIG_NFS_V3_ACL */
1527
1528 /*
1529  * NFS XDR decode functions
1530  */
1531
1532 /*
1533  * Decode attrstat reply.
1534  */
1535 static int
1536 nfs3_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1537 {
1538         int     status;
1539
1540         if ((status = ntohl(*p++)))
1541                 return nfs_stat_to_errno(status);
1542         xdr_decode_fattr(p, fattr);
1543         return 0;
1544 }
1545
1546 /*
1547  * 3.3.1  GETATTR3res
1548  *
1549  *      struct GETATTR3resok {
1550  *              fattr3          obj_attributes;
1551  *      };
1552  *
1553  *      union GETATTR3res switch (nfsstat3 status) {
1554  *      case NFS3_OK:
1555  *              GETATTR3resok  resok;
1556  *      default:
1557  *              void;
1558  *      };
1559  */
1560 static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req, __be32 *p,
1561                                     struct nfs_fattr *result)
1562 {
1563         struct xdr_stream xdr;
1564         enum nfs_stat status;
1565         int error;
1566
1567         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1568         error = decode_nfsstat3(&xdr, &status);
1569         if (unlikely(error))
1570                 goto out;
1571         if (status != NFS3_OK)
1572                 goto out_default;
1573         error = decode_fattr3(&xdr, result);
1574 out:
1575         return error;
1576 out_default:
1577         return nfs_stat_to_errno(status);
1578 }
1579
1580 /*
1581  * Decode status+wcc_data reply
1582  * SATTR, REMOVE, RMDIR
1583  */
1584 static int
1585 nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1586 {
1587         int     status;
1588
1589         if ((status = ntohl(*p++)))
1590                 status = nfs_stat_to_errno(status);
1591         xdr_decode_wcc_data(p, fattr);
1592         return status;
1593 }
1594
1595 /*
1596  * 3.3.2  SETATTR3res
1597  *
1598  *      struct SETATTR3resok {
1599  *              wcc_data  obj_wcc;
1600  *      };
1601  *
1602  *      struct SETATTR3resfail {
1603  *              wcc_data  obj_wcc;
1604  *      };
1605  *
1606  *      union SETATTR3res switch (nfsstat3 status) {
1607  *      case NFS3_OK:
1608  *              SETATTR3resok   resok;
1609  *      default:
1610  *              SETATTR3resfail resfail;
1611  *      };
1612  */
1613 static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req, __be32 *p,
1614                                     struct nfs_fattr *result)
1615 {
1616         struct xdr_stream xdr;
1617         enum nfs_stat status;
1618         int error;
1619
1620         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1621         error = decode_nfsstat3(&xdr, &status);
1622         if (unlikely(error))
1623                 goto out;
1624         error = decode_wcc_data(&xdr, result);
1625         if (unlikely(error))
1626                 goto out;
1627         if (status != NFS3_OK)
1628                 goto out_status;
1629 out:
1630         return error;
1631 out_status:
1632         return nfs_stat_to_errno(status);
1633 }
1634
1635 static int
1636 nfs3_xdr_removeres(struct rpc_rqst *req, __be32 *p, struct nfs_removeres *res)
1637 {
1638         return nfs3_xdr_wccstat(req, p, res->dir_attr);
1639 }
1640
1641 /*
1642  * Decode LOOKUP reply
1643  */
1644 static int
1645 nfs3_xdr_lookupres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
1646 {
1647         int     status;
1648
1649         if ((status = ntohl(*p++))) {
1650                 status = nfs_stat_to_errno(status);
1651         } else {
1652                 if (!(p = xdr_decode_fhandle(p, res->fh)))
1653                         return -errno_NFSERR_IO;
1654                 p = xdr_decode_post_op_attr(p, res->fattr);
1655         }
1656         xdr_decode_post_op_attr(p, res->dir_attr);
1657         return status;
1658 }
1659
1660 /*
1661  * 3.3.3  LOOKUP3res
1662  *
1663  *      struct LOOKUP3resok {
1664  *              nfs_fh3         object;
1665  *              post_op_attr    obj_attributes;
1666  *              post_op_attr    dir_attributes;
1667  *      };
1668  *
1669  *      struct LOOKUP3resfail {
1670  *              post_op_attr    dir_attributes;
1671  *      };
1672  *
1673  *      union LOOKUP3res switch (nfsstat3 status) {
1674  *      case NFS3_OK:
1675  *              LOOKUP3resok    resok;
1676  *      default:
1677  *              LOOKUP3resfail  resfail;
1678  *      };
1679  */
1680 static int nfs3_xdr_dec_lookup3res(struct rpc_rqst *req, __be32 *p,
1681                                    struct nfs3_diropres *result)
1682 {
1683         struct xdr_stream xdr;
1684         enum nfs_stat status;
1685         int error;
1686
1687         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1688         error = decode_nfsstat3(&xdr, &status);
1689         if (unlikely(error))
1690                 goto out;
1691         if (status != NFS3_OK)
1692                 goto out_default;
1693         error = decode_nfs_fh3(&xdr, result->fh);
1694         if (unlikely(error))
1695                 goto out;
1696         error = decode_post_op_attr(&xdr, result->fattr);
1697         if (unlikely(error))
1698                 goto out;
1699         error = decode_post_op_attr(&xdr, result->dir_attr);
1700 out:
1701         return error;
1702 out_default:
1703         error = decode_post_op_attr(&xdr, result->dir_attr);
1704         if (unlikely(error))
1705                 goto out;
1706         return nfs_stat_to_errno(status);
1707 }
1708
1709 /*
1710  * Decode ACCESS reply
1711  */
1712 static int
1713 nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res)
1714 {
1715         int     status = ntohl(*p++);
1716
1717         p = xdr_decode_post_op_attr(p, res->fattr);
1718         if (status)
1719                 return nfs_stat_to_errno(status);
1720         res->access = ntohl(*p++);
1721         return 0;
1722 }
1723
1724 /*
1725  * 3.3.4  ACCESS3res
1726  *
1727  *      struct ACCESS3resok {
1728  *              post_op_attr    obj_attributes;
1729  *              uint32          access;
1730  *      };
1731  *
1732  *      struct ACCESS3resfail {
1733  *              post_op_attr    obj_attributes;
1734  *      };
1735  *
1736  *      union ACCESS3res switch (nfsstat3 status) {
1737  *      case NFS3_OK:
1738  *              ACCESS3resok    resok;
1739  *      default:
1740  *              ACCESS3resfail  resfail;
1741  *      };
1742  */
1743 static int nfs3_xdr_dec_access3res(struct rpc_rqst *req, __be32 *p,
1744                                    struct nfs3_accessres *result)
1745 {
1746         struct xdr_stream xdr;
1747         enum nfs_stat status;
1748         int error;
1749
1750         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1751         error = decode_nfsstat3(&xdr, &status);
1752         if (unlikely(error))
1753                 goto out;
1754         error = decode_post_op_attr(&xdr, result->fattr);
1755         if (unlikely(error))
1756                 goto out;
1757         if (status != NFS3_OK)
1758                 goto out_default;
1759         error = decode_uint32(&xdr, &result->access);
1760 out:
1761         return error;
1762 out_default:
1763         return nfs_stat_to_errno(status);
1764 }
1765
1766 /*
1767  * Decode READLINK reply
1768  */
1769 static int
1770 nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1771 {
1772         struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
1773         struct kvec *iov = rcvbuf->head;
1774         size_t hdrlen;
1775         u32 len, recvd;
1776         int     status;
1777
1778         status = ntohl(*p++);
1779         p = xdr_decode_post_op_attr(p, fattr);
1780
1781         if (status != 0)
1782                 return nfs_stat_to_errno(status);
1783
1784         /* Convert length of symlink */
1785         len = ntohl(*p++);
1786         if (len >= rcvbuf->page_len) {
1787                 dprintk("nfs: server returned giant symlink!\n");
1788                 return -ENAMETOOLONG;
1789         }
1790
1791         hdrlen = (u8 *) p - (u8 *) iov->iov_base;
1792         if (iov->iov_len < hdrlen) {
1793                 dprintk("NFS: READLINK reply header overflowed:"
1794                                 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1795                 return -errno_NFSERR_IO;
1796         } else if (iov->iov_len != hdrlen) {
1797                 dprintk("NFS: READLINK header is short. "
1798                         "iovec will be shifted.\n");
1799                 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
1800         }
1801         recvd = req->rq_rcv_buf.len - hdrlen;
1802         if (recvd < len) {
1803                 dprintk("NFS: server cheating in readlink reply: "
1804                                 "count %u > recvd %u\n", len, recvd);
1805                 return -EIO;
1806         }
1807
1808         xdr_terminate_string(rcvbuf, len);
1809         return 0;
1810 }
1811
1812 /*
1813  * 3.3.5  READLINK3res
1814  *
1815  *      struct READLINK3resok {
1816  *              post_op_attr    symlink_attributes;
1817  *              nfspath3        data;
1818  *      };
1819  *
1820  *      struct READLINK3resfail {
1821  *              post_op_attr    symlink_attributes;
1822  *      };
1823  *
1824  *      union READLINK3res switch (nfsstat3 status) {
1825  *      case NFS3_OK:
1826  *              READLINK3resok  resok;
1827  *      default:
1828  *              READLINK3resfail resfail;
1829  *      };
1830  */
1831 static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req, __be32 *p,
1832                                      struct nfs_fattr *result)
1833 {
1834         struct xdr_stream xdr;
1835         enum nfs_stat status;
1836         int error;
1837
1838         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1839         error = decode_nfsstat3(&xdr, &status);
1840         if (unlikely(error))
1841                 goto out;
1842         error = decode_post_op_attr(&xdr, result);
1843         if (unlikely(error))
1844                 goto out;
1845         if (status != NFS3_OK)
1846                 goto out_default;
1847         error = decode_nfspath3(&xdr);
1848 out:
1849         return error;
1850 out_default:
1851         return nfs_stat_to_errno(status);
1852 }
1853
1854 /*
1855  * Decode READ reply
1856  */
1857 static int
1858 nfs3_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
1859 {
1860         struct kvec *iov = req->rq_rcv_buf.head;
1861         size_t hdrlen;
1862         u32 count, ocount, recvd;
1863         int status;
1864
1865         status = ntohl(*p++);
1866         p = xdr_decode_post_op_attr(p, res->fattr);
1867
1868         if (status != 0)
1869                 return nfs_stat_to_errno(status);
1870
1871         /* Decode reply count and EOF flag. NFSv3 is somewhat redundant
1872          * in that it puts the count both in the res struct and in the
1873          * opaque data count. */
1874         count    = ntohl(*p++);
1875         res->eof = ntohl(*p++);
1876         ocount   = ntohl(*p++);
1877
1878         if (ocount != count) {
1879                 dprintk("NFS: READ count doesn't match RPC opaque count.\n");
1880                 return -errno_NFSERR_IO;
1881         }
1882
1883         hdrlen = (u8 *) p - (u8 *) iov->iov_base;
1884         if (iov->iov_len < hdrlen) {
1885                 dprintk("NFS: READ reply header overflowed:"
1886                                 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1887                 return -errno_NFSERR_IO;
1888         } else if (iov->iov_len != hdrlen) {
1889                 dprintk("NFS: READ header is short. iovec will be shifted.\n");
1890                 xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
1891         }
1892
1893         recvd = req->rq_rcv_buf.len - hdrlen;
1894         if (count > recvd) {
1895                 dprintk("NFS: server cheating in read reply: "
1896                         "count %u > recvd %u\n", count, recvd);
1897                 count = recvd;
1898                 res->eof = 0;
1899         }
1900
1901         if (count < res->count)
1902                 res->count = count;
1903
1904         return count;
1905 }
1906
1907 /*
1908  * 3.3.6  READ3res
1909  *
1910  *      struct READ3resok {
1911  *              post_op_attr    file_attributes;
1912  *              count3          count;
1913  *              bool            eof;
1914  *              opaque          data<>;
1915  *      };
1916  *
1917  *      struct READ3resfail {
1918  *              post_op_attr    file_attributes;
1919  *      };
1920  *
1921  *      union READ3res switch (nfsstat3 status) {
1922  *      case NFS3_OK:
1923  *              READ3resok      resok;
1924  *      default:
1925  *              READ3resfail    resfail;
1926  *      };
1927  */
1928 static int decode_read3resok(struct xdr_stream *xdr,
1929                              struct nfs_readres *result)
1930 {
1931         u32 eof, count, ocount, recvd;
1932         size_t hdrlen;
1933         __be32 *p;
1934
1935         p = xdr_inline_decode(xdr, 4 + 4 + 4);
1936         if (unlikely(p == NULL))
1937                 goto out_overflow;
1938         count = be32_to_cpup(p++);
1939         eof = be32_to_cpup(p++);
1940         ocount = be32_to_cpup(p++);
1941         if (unlikely(ocount != count))
1942                 goto out_mismatch;
1943         hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
1944         recvd = xdr->buf->len - hdrlen;
1945         if (unlikely(count > recvd))
1946                 goto out_cheating;
1947
1948 out:
1949         xdr_read_pages(xdr, count);
1950         result->eof = eof;
1951         result->count = count;
1952         return count;
1953 out_mismatch:
1954         dprintk("NFS: READ count doesn't match length of opaque: "
1955                 "count %u != ocount %u\n", count, ocount);
1956         return -EIO;
1957 out_cheating:
1958         dprintk("NFS: server cheating in read result: "
1959                 "count %u > recvd %u\n", count, recvd);
1960         count = recvd;
1961         eof = 0;
1962         goto out;
1963 out_overflow:
1964         print_overflow_msg(__func__, xdr);
1965         return -EIO;
1966 }
1967
1968 static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, __be32 *p,
1969                                  struct nfs_readres *result)
1970 {
1971         struct xdr_stream xdr;
1972         enum nfs_stat status;
1973         int error;
1974
1975         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1976         error = decode_nfsstat3(&xdr, &status);
1977         if (unlikely(error))
1978                 goto out;
1979         error = decode_post_op_attr(&xdr, result->fattr);
1980         if (unlikely(error))
1981                 goto out;
1982         if (status != NFS3_OK)
1983                 goto out_status;
1984         error = decode_read3resok(&xdr, result);
1985 out:
1986         return error;
1987 out_status:
1988         return nfs_stat_to_errno(status);
1989 }
1990
1991 /*
1992  * Decode WRITE response
1993  */
1994 static int
1995 nfs3_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
1996 {
1997         int     status;
1998
1999         status = ntohl(*p++);
2000         p = xdr_decode_wcc_data(p, res->fattr);
2001
2002         if (status != 0)
2003                 return nfs_stat_to_errno(status);
2004
2005         res->count = ntohl(*p++);
2006         res->verf->committed = (enum nfs3_stable_how)ntohl(*p++);
2007         res->verf->verifier[0] = *p++;
2008         res->verf->verifier[1] = *p++;
2009
2010         return res->count;
2011 }
2012
2013 /*
2014  * 3.3.7  WRITE3res
2015  *
2016  *      enum stable_how {
2017  *              UNSTABLE  = 0,
2018  *              DATA_SYNC = 1,
2019  *              FILE_SYNC = 2
2020  *      };
2021  *
2022  *      struct WRITE3resok {
2023  *              wcc_data        file_wcc;
2024  *              count3          count;
2025  *              stable_how      committed;
2026  *              writeverf3      verf;
2027  *      };
2028  *
2029  *      struct WRITE3resfail {
2030  *              wcc_data        file_wcc;
2031  *      };
2032  *
2033  *      union WRITE3res switch (nfsstat3 status) {
2034  *      case NFS3_OK:
2035  *              WRITE3resok     resok;
2036  *      default:
2037  *              WRITE3resfail   resfail;
2038  *      };
2039  */
2040 static int decode_write3resok(struct xdr_stream *xdr,
2041                               struct nfs_writeres *result)
2042 {
2043         __be32 *p;
2044
2045         p = xdr_inline_decode(xdr, 4 + 4 + NFS3_WRITEVERFSIZE);
2046         if (unlikely(p == NULL))
2047                 goto out_overflow;
2048         result->count = be32_to_cpup(p++);
2049         result->verf->committed = be32_to_cpup(p++);
2050         if (unlikely(result->verf->committed > NFS_FILE_SYNC))
2051                 goto out_badvalue;
2052         memcpy(result->verf->verifier, p, NFS3_WRITEVERFSIZE);
2053         return result->count;
2054 out_badvalue:
2055         dprintk("NFS: bad stable_how value: %u\n", result->verf->committed);
2056         return -EIO;
2057 out_overflow:
2058         print_overflow_msg(__func__, xdr);
2059         return -EIO;
2060 }
2061
2062 static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, __be32 *p,
2063                                   struct nfs_writeres *result)
2064 {
2065         struct xdr_stream xdr;
2066         enum nfs_stat status;
2067         int error;
2068
2069         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2070         error = decode_nfsstat3(&xdr, &status);
2071         if (unlikely(error))
2072                 goto out;
2073         error = decode_wcc_data(&xdr, result->fattr);
2074         if (unlikely(error))
2075                 goto out;
2076         if (status != NFS3_OK)
2077                 goto out_status;
2078         error = decode_write3resok(&xdr, result);
2079 out:
2080         return error;
2081 out_status:
2082         return nfs_stat_to_errno(status);
2083 }
2084
2085 /*
2086  * Decode a CREATE response
2087  */
2088 static int
2089 nfs3_xdr_createres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
2090 {
2091         int     status;
2092
2093         status = ntohl(*p++);
2094         if (status == 0) {
2095                 if (*p++) {
2096                         if (!(p = xdr_decode_fhandle(p, res->fh)))
2097                                 return -errno_NFSERR_IO;
2098                         p = xdr_decode_post_op_attr(p, res->fattr);
2099                 } else {
2100                         memset(res->fh, 0, sizeof(*res->fh));
2101                         /* Do decode post_op_attr but set it to NULL */
2102                         p = xdr_decode_post_op_attr(p, res->fattr);
2103                         res->fattr->valid = 0;
2104                 }
2105         } else {
2106                 status = nfs_stat_to_errno(status);
2107         }
2108         p = xdr_decode_wcc_data(p, res->dir_attr);
2109         return status;
2110 }
2111
2112 /*
2113  * 3.3.8  CREATE3res
2114  *
2115  *      struct CREATE3resok {
2116  *              post_op_fh3     obj;
2117  *              post_op_attr    obj_attributes;
2118  *              wcc_data        dir_wcc;
2119  *      };
2120  *
2121  *      struct CREATE3resfail {
2122  *              wcc_data        dir_wcc;
2123  *      };
2124  *
2125  *      union CREATE3res switch (nfsstat3 status) {
2126  *      case NFS3_OK:
2127  *              CREATE3resok    resok;
2128  *      default:
2129  *              CREATE3resfail  resfail;
2130  *      };
2131  */
2132 static int decode_create3resok(struct xdr_stream *xdr,
2133                                struct nfs3_diropres *result)
2134 {
2135         int error;
2136
2137         error = decode_post_op_fh3(xdr, result->fh);
2138         if (unlikely(error))
2139                 goto out;
2140         error = decode_post_op_attr(xdr, result->fattr);
2141         if (unlikely(error))
2142                 goto out;
2143         /* The server isn't required to return a file handle.
2144          * If it didn't, force the client to perform a LOOKUP
2145          * to determine the correct file handle and attribute
2146          * values for the new object. */
2147         if (result->fh->size == 0)
2148                 result->fattr->valid = 0;
2149         error = decode_wcc_data(xdr, result->dir_attr);
2150 out:
2151         return error;
2152 }
2153
2154 static int nfs3_xdr_dec_create3res(struct rpc_rqst *req, __be32 *p,
2155                                    struct nfs3_diropres *result)
2156 {
2157         struct xdr_stream xdr;
2158         enum nfs_stat status;
2159         int error;
2160
2161         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2162         error = decode_nfsstat3(&xdr, &status);
2163         if (unlikely(error))
2164                 goto out;
2165         if (status != NFS3_OK)
2166                 goto out_default;
2167         error = decode_create3resok(&xdr, result);
2168 out:
2169         return error;
2170 out_default:
2171         error = decode_wcc_data(&xdr, result->dir_attr);
2172         if (unlikely(error))
2173                 goto out;
2174         return nfs_stat_to_errno(status);
2175 }
2176
2177 /*
2178  * 3.3.12  REMOVE3res
2179  *
2180  *      struct REMOVE3resok {
2181  *              wcc_data    dir_wcc;
2182  *      };
2183  *
2184  *      struct REMOVE3resfail {
2185  *              wcc_data    dir_wcc;
2186  *      };
2187  *
2188  *      union REMOVE3res switch (nfsstat3 status) {
2189  *      case NFS3_OK:
2190  *              REMOVE3resok   resok;
2191  *      default:
2192  *              REMOVE3resfail resfail;
2193  *      };
2194  */
2195 static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req, __be32 *p,
2196                                    struct nfs_removeres *result)
2197 {
2198         struct xdr_stream xdr;
2199         enum nfs_stat status;
2200         int error;
2201
2202         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2203         error = decode_nfsstat3(&xdr, &status);
2204         if (unlikely(error))
2205                 goto out;
2206         error = decode_wcc_data(&xdr, result->dir_attr);
2207         if (unlikely(error))
2208                 goto out;
2209         if (status != NFS3_OK)
2210                 goto out_status;
2211 out:
2212         return error;
2213 out_status:
2214         return nfs_stat_to_errno(status);
2215 }
2216
2217 /*
2218  * Decode RENAME reply
2219  */
2220 static int
2221 nfs3_xdr_renameres(struct rpc_rqst *req, __be32 *p, struct nfs_renameres *res)
2222 {
2223         int     status;
2224
2225         if ((status = ntohl(*p++)) != 0)
2226                 status = nfs_stat_to_errno(status);
2227         p = xdr_decode_wcc_data(p, res->old_fattr);
2228         p = xdr_decode_wcc_data(p, res->new_fattr);
2229         return status;
2230 }
2231
2232 /*
2233  * 3.3.14  RENAME3res
2234  *
2235  *      struct RENAME3resok {
2236  *              wcc_data        fromdir_wcc;
2237  *              wcc_data        todir_wcc;
2238  *      };
2239  *
2240  *      struct RENAME3resfail {
2241  *              wcc_data        fromdir_wcc;
2242  *              wcc_data        todir_wcc;
2243  *      };
2244  *
2245  *      union RENAME3res switch (nfsstat3 status) {
2246  *      case NFS3_OK:
2247  *              RENAME3resok   resok;
2248  *      default:
2249  *              RENAME3resfail resfail;
2250  *      };
2251  */
2252 static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req, __be32 *p,
2253                                    struct nfs_renameres *result)
2254 {
2255         struct xdr_stream xdr;
2256         enum nfs_stat status;
2257         int error;
2258
2259         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2260         error = decode_nfsstat3(&xdr, &status);
2261         if (unlikely(error))
2262                 goto out;
2263         error = decode_wcc_data(&xdr, result->old_fattr);
2264         if (unlikely(error))
2265                 goto out;
2266         error = decode_wcc_data(&xdr, result->new_fattr);
2267         if (unlikely(error))
2268                 goto out;
2269         if (status != NFS3_OK)
2270                 goto out_status;
2271 out:
2272         return error;
2273 out_status:
2274         return nfs_stat_to_errno(status);
2275 }
2276
2277 /*
2278  * Decode LINK reply
2279  */
2280 static int
2281 nfs3_xdr_linkres(struct rpc_rqst *req, __be32 *p, struct nfs3_linkres *res)
2282 {
2283         int     status;
2284
2285         if ((status = ntohl(*p++)) != 0)
2286                 status = nfs_stat_to_errno(status);
2287         p = xdr_decode_post_op_attr(p, res->fattr);
2288         p = xdr_decode_wcc_data(p, res->dir_attr);
2289         return status;
2290 }
2291
2292 /*
2293  * 3.3.15  LINK3res
2294  *
2295  *      struct LINK3resok {
2296  *              post_op_attr    file_attributes;
2297  *              wcc_data        linkdir_wcc;
2298  *      };
2299  *
2300  *      struct LINK3resfail {
2301  *              post_op_attr    file_attributes;
2302  *              wcc_data        linkdir_wcc;
2303  *      };
2304  *
2305  *      union LINK3res switch (nfsstat3 status) {
2306  *      case NFS3_OK:
2307  *              LINK3resok      resok;
2308  *      default:
2309  *              LINK3resfail    resfail;
2310  *      };
2311  */
2312 static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, __be32 *p,
2313                                  struct nfs3_linkres *result)
2314 {
2315         struct xdr_stream xdr;
2316         enum nfs_stat status;
2317         int error;
2318
2319         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2320         error = decode_nfsstat3(&xdr, &status);
2321         if (unlikely(error))
2322                 goto out;
2323         error = decode_post_op_attr(&xdr, result->fattr);
2324         if (unlikely(error))
2325                 goto out;
2326         error = decode_wcc_data(&xdr, result->dir_attr);
2327         if (unlikely(error))
2328                 goto out;
2329         if (status != NFS3_OK)
2330                 goto out_status;
2331 out:
2332         return error;
2333 out_status:
2334         return nfs_stat_to_errno(status);
2335 }
2336
2337 /**
2338  * nfs3_decode_dirent - Decode a single NFSv3 directory entry stored in
2339  *                      the local page cache
2340  * @xdr: XDR stream where entry resides
2341  * @entry: buffer to fill in with entry data
2342  * @server: nfs_server data for this directory
2343  * @plus: boolean indicating whether this should be a readdirplus entry
2344  *
2345  * Returns the position of the next item in the buffer, or an ERR_PTR.
2346  *
2347  * This function is not invoked during READDIR reply decoding, but
2348  * rather whenever an application invokes the getdents(2) system call
2349  * on a directory already in our cache.
2350  *
2351  * 3.3.16  entry3
2352  *
2353  *      struct entry3 {
2354  *              fileid3         fileid;
2355  *              filename3       name;
2356  *              cookie3         cookie;
2357  *              fhandle3        filehandle;
2358  *              post_op_attr3   attributes;
2359  *              entry3          *nextentry;
2360  *      };
2361  *
2362  * 3.3.17  entryplus3
2363  *      struct entryplus3 {
2364  *              fileid3         fileid;
2365  *              filename3       name;
2366  *              cookie3         cookie;
2367  *              post_op_attr    name_attributes;
2368  *              post_op_fh3     name_handle;
2369  *              entryplus3      *nextentry;
2370  *      };
2371  */
2372 __be32 *nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
2373                            struct nfs_server *server, int plus)
2374 {
2375         struct nfs_entry old = *entry;
2376         __be32 *p;
2377         int error;
2378
2379         p = xdr_inline_decode(xdr, 4);
2380         if (unlikely(p == NULL))
2381                 goto out_overflow;
2382         if (*p == xdr_zero) {
2383                 p = xdr_inline_decode(xdr, 4);
2384                 if (unlikely(p == NULL))
2385                         goto out_overflow;
2386                 if (*p == xdr_zero)
2387                         return ERR_PTR(-EAGAIN);
2388                 entry->eof = 1;
2389                 return ERR_PTR(-EBADCOOKIE);
2390         }
2391
2392         error = decode_fileid3(xdr, &entry->ino);
2393         if (unlikely(error))
2394                 return ERR_PTR(error);
2395
2396         error = decode_inline_filename3(xdr, &entry->name, &entry->len);
2397         if (unlikely(error))
2398                 return ERR_PTR(error);
2399
2400         entry->prev_cookie = entry->cookie;
2401         error = decode_cookie3(xdr, &entry->cookie);
2402         if (unlikely(error))
2403                 return ERR_PTR(error);
2404
2405         entry->d_type = DT_UNKNOWN;
2406
2407         if (plus) {
2408                 entry->fattr->valid = 0;
2409                 error = decode_post_op_attr(xdr, entry->fattr);
2410                 if (unlikely(error))
2411                         return ERR_PTR(error);
2412                 if (entry->fattr->valid & NFS_ATTR_FATTR_V3)
2413                         entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
2414
2415                 /* In fact, a post_op_fh3: */
2416                 p = xdr_inline_decode(xdr, 4);
2417                 if (unlikely(p == NULL))
2418                         goto out_overflow;
2419                 if (*p != xdr_zero) {
2420                         error = decode_nfs_fh3(xdr, entry->fh);
2421                         if (unlikely(error)) {
2422                                 if (error == -E2BIG)
2423                                         goto out_truncated;
2424                                 return ERR_PTR(error);
2425                         }
2426                 } else
2427                         zero_nfs_fh3(entry->fh);
2428         }
2429
2430         /* Peek at the next entry to see if we're at EOD */
2431         p = xdr_inline_peek(xdr, 4 + 4);
2432         entry->eof = 0;
2433         if (p != NULL)
2434                 entry->eof = (p[0] == xdr_zero) && (p[1] != xdr_zero);
2435         return p;
2436
2437 out_overflow:
2438         print_overflow_msg(__func__, xdr);
2439         return ERR_PTR(-EAGAIN);
2440 out_truncated:
2441         dprintk("NFS: directory entry contains invalid file handle\n");
2442         *entry = old;
2443         return ERR_PTR(-EAGAIN);
2444 }
2445
2446 /*
2447  * 3.3.16  READDIR3res
2448  *
2449  *      struct dirlist3 {
2450  *              entry3          *entries;
2451  *              bool            eof;
2452  *      };
2453  *
2454  *      struct READDIR3resok {
2455  *              post_op_attr    dir_attributes;
2456  *              cookieverf3     cookieverf;
2457  *              dirlist3        reply;
2458  *      };
2459  *
2460  *      struct READDIR3resfail {
2461  *              post_op_attr    dir_attributes;
2462  *      };
2463  *
2464  *      union READDIR3res switch (nfsstat3 status) {
2465  *      case NFS3_OK:
2466  *              READDIR3resok   resok;
2467  *      default:
2468  *              READDIR3resfail resfail;
2469  *      };
2470  *
2471  * Read the directory contents into the page cache, but otherwise
2472  * don't touch them.  The actual decoding is done by nfs3_decode_entry()
2473  * during subsequent nfs_readdir() calls.
2474  */
2475 static int decode_dirlist3(struct xdr_stream *xdr)
2476 {
2477         u32 recvd, pglen;
2478         size_t hdrlen;
2479
2480         pglen = xdr->buf->page_len;
2481         hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
2482         recvd = xdr->buf->len - hdrlen;
2483         if (unlikely(pglen > recvd))
2484                 goto out_cheating;
2485 out:
2486         xdr_read_pages(xdr, pglen);
2487         return pglen;
2488 out_cheating:
2489         dprintk("NFS: server cheating in readdir result: "
2490                 "pglen %u > recvd %u\n", pglen, recvd);
2491         pglen = recvd;
2492         goto out;
2493 }
2494
2495 static int decode_readdir3resok(struct xdr_stream *xdr,
2496                                 struct nfs3_readdirres *result)
2497 {
2498         int error;
2499
2500         error = decode_post_op_attr(xdr, result->dir_attr);
2501         if (unlikely(error))
2502                 goto out;
2503         /* XXX: do we need to check if result->verf != NULL ? */
2504         error = decode_cookieverf3(xdr, result->verf);
2505         if (unlikely(error))
2506                 goto out;
2507         error = decode_dirlist3(xdr);
2508 out:
2509         return error;
2510 }
2511
2512 static int nfs3_xdr_dec_readdir3res(struct rpc_rqst *req, __be32 *p,
2513                                     struct nfs3_readdirres *result)
2514 {
2515         struct xdr_stream xdr;
2516         enum nfs_stat status;
2517         int error;
2518
2519         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2520         error = decode_nfsstat3(&xdr, &status);
2521         if (unlikely(error))
2522                 goto out;
2523         if (status != NFS3_OK)
2524                 goto out_default;
2525         error = decode_readdir3resok(&xdr, result);
2526 out:
2527         return error;
2528 out_default:
2529         error = decode_post_op_attr(&xdr, result->dir_attr);
2530         if (unlikely(error))
2531                 goto out;
2532         return nfs_stat_to_errno(status);
2533 }
2534
2535 /*
2536  * Decode FSSTAT reply
2537  */
2538 static int
2539 nfs3_xdr_fsstatres(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *res)
2540 {
2541         int             status;
2542
2543         status = ntohl(*p++);
2544
2545         p = xdr_decode_post_op_attr(p, res->fattr);
2546         if (status != 0)
2547                 return nfs_stat_to_errno(status);
2548
2549         p = xdr_decode_hyper(p, &res->tbytes);
2550         p = xdr_decode_hyper(p, &res->fbytes);
2551         p = xdr_decode_hyper(p, &res->abytes);
2552         p = xdr_decode_hyper(p, &res->tfiles);
2553         p = xdr_decode_hyper(p, &res->ffiles);
2554         p = xdr_decode_hyper(p, &res->afiles);
2555
2556         /* ignore invarsec */
2557         return 0;
2558 }
2559
2560 /*
2561  * 3.3.18  FSSTAT3res
2562  *
2563  *      struct FSSTAT3resok {
2564  *              post_op_attr    obj_attributes;
2565  *              size3           tbytes;
2566  *              size3           fbytes;
2567  *              size3           abytes;
2568  *              size3           tfiles;
2569  *              size3           ffiles;
2570  *              size3           afiles;
2571  *              uint32          invarsec;
2572  *      };
2573  *
2574  *      struct FSSTAT3resfail {
2575  *              post_op_attr    obj_attributes;
2576  *      };
2577  *
2578  *      union FSSTAT3res switch (nfsstat3 status) {
2579  *      case NFS3_OK:
2580  *              FSSTAT3resok    resok;
2581  *      default:
2582  *              FSSTAT3resfail  resfail;
2583  *      };
2584  */
2585 static int decode_fsstat3resok(struct xdr_stream *xdr,
2586                                struct nfs_fsstat *result)
2587 {
2588         __be32 *p;
2589
2590         p = xdr_inline_decode(xdr, 8 * 6 + 4);
2591         if (unlikely(p == NULL))
2592                 goto out_overflow;
2593         p = xdr_decode_size3(p, &result->tbytes);
2594         p = xdr_decode_size3(p, &result->fbytes);
2595         p = xdr_decode_size3(p, &result->abytes);
2596         p = xdr_decode_size3(p, &result->tfiles);
2597         p = xdr_decode_size3(p, &result->ffiles);
2598         xdr_decode_size3(p, &result->afiles);
2599         /* ignore invarsec */
2600         return 0;
2601 out_overflow:
2602         print_overflow_msg(__func__, xdr);
2603         return -EIO;
2604 }
2605
2606 static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req, __be32 *p,
2607                                    struct nfs_fsstat *result)
2608 {
2609         struct xdr_stream xdr;
2610         enum nfs_stat status;
2611         int error;
2612
2613         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2614         error = decode_nfsstat3(&xdr, &status);
2615         if (unlikely(error))
2616                 goto out;
2617         error = decode_post_op_attr(&xdr, result->fattr);
2618         if (unlikely(error))
2619                 goto out;
2620         if (status != NFS3_OK)
2621                 goto out_status;
2622         error = decode_fsstat3resok(&xdr, result);
2623 out:
2624         return error;
2625 out_status:
2626         return nfs_stat_to_errno(status);
2627 }
2628
2629 /*
2630  * Decode FSINFO reply
2631  */
2632 static int
2633 nfs3_xdr_fsinfores(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *res)
2634 {
2635         int             status;
2636
2637         status = ntohl(*p++);
2638
2639         p = xdr_decode_post_op_attr(p, res->fattr);
2640         if (status != 0)
2641                 return nfs_stat_to_errno(status);
2642
2643         res->rtmax  = ntohl(*p++);
2644         res->rtpref = ntohl(*p++);
2645         res->rtmult = ntohl(*p++);
2646         res->wtmax  = ntohl(*p++);
2647         res->wtpref = ntohl(*p++);
2648         res->wtmult = ntohl(*p++);
2649         res->dtpref = ntohl(*p++);
2650         p = xdr_decode_hyper(p, &res->maxfilesize);
2651         p = xdr_decode_time3(p, &res->time_delta);
2652
2653         /* ignore properties */
2654         res->lease_time = 0;
2655         return 0;
2656 }
2657
2658 /*
2659  * 3.3.19  FSINFO3res
2660  *
2661  *      struct FSINFO3resok {
2662  *              post_op_attr    obj_attributes;
2663  *              uint32          rtmax;
2664  *              uint32          rtpref;
2665  *              uint32          rtmult;
2666  *              uint32          wtmax;
2667  *              uint32          wtpref;
2668  *              uint32          wtmult;
2669  *              uint32          dtpref;
2670  *              size3           maxfilesize;
2671  *              nfstime3        time_delta;
2672  *              uint32          properties;
2673  *      };
2674  *
2675  *      struct FSINFO3resfail {
2676  *              post_op_attr    obj_attributes;
2677  *      };
2678  *
2679  *      union FSINFO3res switch (nfsstat3 status) {
2680  *      case NFS3_OK:
2681  *              FSINFO3resok    resok;
2682  *      default:
2683  *              FSINFO3resfail  resfail;
2684  *      };
2685  */
2686 static int decode_fsinfo3resok(struct xdr_stream *xdr,
2687                                struct nfs_fsinfo *result)
2688 {
2689         __be32 *p;
2690
2691         p = xdr_inline_decode(xdr, 4 * 7 + 8 + 8 + 4);
2692         if (unlikely(p == NULL))
2693                 goto out_overflow;
2694         result->rtmax  = be32_to_cpup(p++);
2695         result->rtpref = be32_to_cpup(p++);
2696         result->rtmult = be32_to_cpup(p++);
2697         result->wtmax  = be32_to_cpup(p++);
2698         result->wtpref = be32_to_cpup(p++);
2699         result->wtmult = be32_to_cpup(p++);
2700         result->dtpref = be32_to_cpup(p++);
2701         p = xdr_decode_size3(p, &result->maxfilesize);
2702         xdr_decode_time3(p, &result->time_delta);
2703
2704         /* ignore properties */
2705         result->lease_time = 0;
2706         return 0;
2707 out_overflow:
2708         print_overflow_msg(__func__, xdr);
2709         return -EIO;
2710 }
2711
2712 static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req, __be32 *p,
2713                                    struct nfs_fsinfo *result)
2714 {
2715         struct xdr_stream xdr;
2716         enum nfs_stat status;
2717         int error;
2718
2719         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2720         error = decode_nfsstat3(&xdr, &status);
2721         if (unlikely(error))
2722                 goto out;
2723         error = decode_post_op_attr(&xdr, result->fattr);
2724         if (unlikely(error))
2725                 goto out;
2726         if (status != NFS3_OK)
2727                 goto out_status;
2728         error = decode_fsinfo3resok(&xdr, result);
2729 out:
2730         return error;
2731 out_status:
2732         return nfs_stat_to_errno(status);
2733 }
2734
2735 /*
2736  * Decode PATHCONF reply
2737  */
2738 static int
2739 nfs3_xdr_pathconfres(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *res)
2740 {
2741         int             status;
2742
2743         status = ntohl(*p++);
2744
2745         p = xdr_decode_post_op_attr(p, res->fattr);
2746         if (status != 0)
2747                 return nfs_stat_to_errno(status);
2748         res->max_link = ntohl(*p++);
2749         res->max_namelen = ntohl(*p++);
2750
2751         /* ignore remaining fields */
2752         return 0;
2753 }
2754
2755 /*
2756  * 3.3.20  PATHCONF3res
2757  *
2758  *      struct PATHCONF3resok {
2759  *              post_op_attr    obj_attributes;
2760  *              uint32          linkmax;
2761  *              uint32          name_max;
2762  *              bool            no_trunc;
2763  *              bool            chown_restricted;
2764  *              bool            case_insensitive;
2765  *              bool            case_preserving;
2766  *      };
2767  *
2768  *      struct PATHCONF3resfail {
2769  *              post_op_attr    obj_attributes;
2770  *      };
2771  *
2772  *      union PATHCONF3res switch (nfsstat3 status) {
2773  *      case NFS3_OK:
2774  *              PATHCONF3resok  resok;
2775  *      default:
2776  *              PATHCONF3resfail resfail;
2777  *      };
2778  */
2779 static int decode_pathconf3resok(struct xdr_stream *xdr,
2780                                  struct nfs_pathconf *result)
2781 {
2782         __be32 *p;
2783
2784         p = xdr_inline_decode(xdr, 4 * 6);
2785         if (unlikely(p == NULL))
2786                 goto out_overflow;
2787         result->max_link = be32_to_cpup(p++);
2788         result->max_namelen = be32_to_cpup(p);
2789         /* ignore remaining fields */
2790         return 0;
2791 out_overflow:
2792         print_overflow_msg(__func__, xdr);
2793         return -EIO;
2794 }
2795
2796 static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req, __be32 *p,
2797                                      struct nfs_pathconf *result)
2798 {
2799         struct xdr_stream xdr;
2800         enum nfs_stat status;
2801         int error;
2802
2803         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2804         error = decode_nfsstat3(&xdr, &status);
2805         if (unlikely(error))
2806                 goto out;
2807         error = decode_post_op_attr(&xdr, result->fattr);
2808         if (unlikely(error))
2809                 goto out;
2810         if (status != NFS3_OK)
2811                 goto out_status;
2812         error = decode_pathconf3resok(&xdr, result);
2813 out:
2814         return error;
2815 out_status:
2816         return nfs_stat_to_errno(status);
2817 }
2818
2819 /*
2820  * Decode COMMIT reply
2821  */
2822 static int
2823 nfs3_xdr_commitres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
2824 {
2825         int             status;
2826
2827         status = ntohl(*p++);
2828         p = xdr_decode_wcc_data(p, res->fattr);
2829         if (status != 0)
2830                 return nfs_stat_to_errno(status);
2831
2832         res->verf->verifier[0] = *p++;
2833         res->verf->verifier[1] = *p++;
2834         return 0;
2835 }
2836
2837 /*
2838  * 3.3.21  COMMIT3res
2839  *
2840  *      struct COMMIT3resok {
2841  *              wcc_data        file_wcc;
2842  *              writeverf3      verf;
2843  *      };
2844  *
2845  *      struct COMMIT3resfail {
2846  *              wcc_data        file_wcc;
2847  *      };
2848  *
2849  *      union COMMIT3res switch (nfsstat3 status) {
2850  *      case NFS3_OK:
2851  *              COMMIT3resok    resok;
2852  *      default:
2853  *              COMMIT3resfail  resfail;
2854  *      };
2855  */
2856 static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req, __be32 *p,
2857                                    struct nfs_writeres *result)
2858 {
2859         struct xdr_stream xdr;
2860         enum nfs_stat status;
2861         int error;
2862
2863         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2864         error = decode_nfsstat3(&xdr, &status);
2865         if (unlikely(error))
2866                 goto out;
2867         error = decode_wcc_data(&xdr, result->fattr);
2868         if (unlikely(error))
2869                 goto out;
2870         if (status != NFS3_OK)
2871                 goto out_status;
2872         error = decode_writeverf3(&xdr, result->verf->verifier);
2873 out:
2874         return error;
2875 out_status:
2876         return nfs_stat_to_errno(status);
2877 }
2878
2879 #ifdef CONFIG_NFS_V3_ACL
2880 /*
2881  * Decode GETACL reply
2882  */
2883 static int
2884 nfs3_xdr_getaclres(struct rpc_rqst *req, __be32 *p,
2885                    struct nfs3_getaclres *res)
2886 {
2887         struct xdr_buf *buf = &req->rq_rcv_buf;
2888         int status = ntohl(*p++);
2889         struct posix_acl **acl;
2890         unsigned int *aclcnt;
2891         int err, base;
2892
2893         if (status != 0)
2894                 return nfs_stat_to_errno(status);
2895         p = xdr_decode_post_op_attr(p, res->fattr);
2896         res->mask = ntohl(*p++);
2897         if (res->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
2898                 return -EINVAL;
2899         base = (char *)p - (char *)req->rq_rcv_buf.head->iov_base;
2900
2901         acl = (res->mask & NFS_ACL) ? &res->acl_access : NULL;
2902         aclcnt = (res->mask & NFS_ACLCNT) ? &res->acl_access_count : NULL;
2903         err = nfsacl_decode(buf, base, aclcnt, acl);
2904
2905         acl = (res->mask & NFS_DFACL) ? &res->acl_default : NULL;
2906         aclcnt = (res->mask & NFS_DFACLCNT) ? &res->acl_default_count : NULL;
2907         if (err > 0)
2908                 err = nfsacl_decode(buf, base + err, aclcnt, acl);
2909         return (err > 0) ? 0 : err;
2910 }
2911
2912 static inline int decode_getacl3resok(struct xdr_stream *xdr,
2913                                       struct nfs3_getaclres *result)
2914 {
2915         struct posix_acl **acl;
2916         unsigned int *aclcnt;
2917         size_t hdrlen;
2918         int error;
2919
2920         error = decode_post_op_attr(xdr, result->fattr);
2921         if (unlikely(error))
2922                 goto out;
2923         error = decode_uint32(xdr, &result->mask);
2924         if (unlikely(error))
2925                 goto out;
2926         error = -EINVAL;
2927         if (result->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
2928                 goto out;
2929
2930         hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
2931
2932         acl = NULL;
2933         if (result->mask & NFS_ACL)
2934                 acl = &result->acl_access;
2935         aclcnt = NULL;
2936         if (result->mask & NFS_ACLCNT)
2937                 aclcnt = &result->acl_access_count;
2938         error = nfsacl_decode(xdr->buf, hdrlen, aclcnt, acl);
2939         if (unlikely(error <= 0))
2940                 goto out;
2941
2942         acl = NULL;
2943         if (result->mask & NFS_DFACL)
2944                 acl = &result->acl_default;
2945         aclcnt = NULL;
2946         if (result->mask & NFS_DFACLCNT)
2947                 aclcnt = &result->acl_default_count;
2948         error = nfsacl_decode(xdr->buf, hdrlen + error, aclcnt, acl);
2949         if (unlikely(error <= 0))
2950                 return error;
2951         error = 0;
2952 out:
2953         return error;
2954 }
2955
2956 static int nfs3_xdr_dec_getacl3res(struct rpc_rqst *req, __be32 *p,
2957                                    struct nfs3_getaclres *result)
2958 {
2959         struct xdr_stream xdr;
2960         enum nfs_stat status;
2961         int error;
2962
2963         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2964         error = decode_nfsstat3(&xdr, &status);
2965         if (unlikely(error))
2966                 goto out;
2967         if (status != NFS3_OK)
2968                 goto out_default;
2969         error = decode_getacl3resok(&xdr, result);
2970 out:
2971         return error;
2972 out_default:
2973         return nfs_stat_to_errno(status);
2974 }
2975
2976 /*
2977  * Decode setacl reply.
2978  */
2979 static int
2980 nfs3_xdr_setaclres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
2981 {
2982         int status = ntohl(*p++);
2983
2984         if (status)
2985                 return nfs_stat_to_errno(status);
2986         xdr_decode_post_op_attr(p, fattr);
2987         return 0;
2988 }
2989
2990 static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req, __be32 *p,
2991                                    struct nfs_fattr *result)
2992 {
2993         struct xdr_stream xdr;
2994         enum nfs_stat status;
2995         int error;
2996
2997         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2998         error = decode_nfsstat3(&xdr, &status);
2999         if (unlikely(error))
3000                 goto out;
3001         if (status != NFS3_OK)
3002                 goto out_default;
3003         error = decode_post_op_attr(&xdr, result);
3004 out:
3005         return error;
3006 out_default:
3007         return nfs_stat_to_errno(status);
3008 }
3009
3010 #endif  /* CONFIG_NFS_V3_ACL */
3011
3012 #define PROC(proc, argtype, restype, timer)                             \
3013 [NFS3PROC_##proc] = {                                                   \
3014         .p_proc      = NFS3PROC_##proc,                                 \
3015         .p_encode    = (kxdrproc_t)nfs3_xdr_enc_##argtype##3args,       \
3016         .p_decode    = (kxdrproc_t)nfs3_xdr_dec_##restype##3res,        \
3017         .p_arglen    = NFS3_##argtype##args_sz,                         \
3018         .p_replen    = NFS3_##restype##res_sz,                          \
3019         .p_timer     = timer,                                           \
3020         .p_statidx   = NFS3PROC_##proc,                                 \
3021         .p_name      = #proc,                                           \
3022         }
3023
3024 struct rpc_procinfo     nfs3_procedures[] = {
3025         PROC(GETATTR,           getattr,        getattr,        1),
3026         PROC(SETATTR,           setattr,        setattr,        0),
3027         PROC(LOOKUP,            lookup,         lookup,         2),
3028         PROC(ACCESS,            access,         access,         1),
3029         PROC(READLINK,          readlink,       readlink,       3),
3030         PROC(READ,              read,           read,           3),
3031         PROC(WRITE,             write,          write,          4),
3032         PROC(CREATE,            create,         create,         0),
3033         PROC(MKDIR,             mkdir,          create,         0),
3034         PROC(SYMLINK,           symlink,        create,         0),
3035         PROC(MKNOD,             mknod,          create,         0),
3036         PROC(REMOVE,            remove,         remove,         0),
3037         PROC(RMDIR,             lookup,         setattr,        0),
3038         PROC(RENAME,            rename,         rename,         0),
3039         PROC(LINK,              link,           link,           0),
3040         PROC(READDIR,           readdir,        readdir,        3),
3041         PROC(READDIRPLUS,       readdirplus,    readdir,        3),
3042         PROC(FSSTAT,            getattr,        fsstat,         0),
3043         PROC(FSINFO,            getattr,        fsinfo,         0),
3044         PROC(PATHCONF,          getattr,        pathconf,       0),
3045         PROC(COMMIT,            commit,         commit,         5),
3046 };
3047
3048 struct rpc_version              nfs_version3 = {
3049         .number                 = 3,
3050         .nrprocs                = ARRAY_SIZE(nfs3_procedures),
3051         .procs                  = nfs3_procedures
3052 };
3053
3054 #ifdef CONFIG_NFS_V3_ACL
3055 static struct rpc_procinfo      nfs3_acl_procedures[] = {
3056         [ACLPROC3_GETACL] = {
3057                 .p_proc = ACLPROC3_GETACL,
3058                 .p_encode = (kxdrproc_t)nfs3_xdr_enc_getacl3args,
3059                 .p_decode = (kxdrproc_t)nfs3_xdr_dec_getacl3res,
3060                 .p_arglen = ACL3_getaclargs_sz,
3061                 .p_replen = ACL3_getaclres_sz,
3062                 .p_timer = 1,
3063                 .p_name = "GETACL",
3064         },
3065         [ACLPROC3_SETACL] = {
3066                 .p_proc = ACLPROC3_SETACL,
3067                 .p_encode = (kxdrproc_t)nfs3_xdr_enc_setacl3args,
3068                 .p_decode = (kxdrproc_t)nfs3_xdr_dec_setacl3res,
3069                 .p_arglen = ACL3_setaclargs_sz,
3070                 .p_replen = ACL3_setaclres_sz,
3071                 .p_timer = 0,
3072                 .p_name = "SETACL",
3073         },
3074 };
3075
3076 struct rpc_version              nfsacl_version3 = {
3077         .number                 = 3,
3078         .nrprocs                = sizeof(nfs3_acl_procedures)/
3079                                   sizeof(nfs3_acl_procedures[0]),
3080         .procs                  = nfs3_acl_procedures,
3081 };
3082 #endif  /* CONFIG_NFS_V3_ACL */