]> git.karo-electronics.de Git - mv-sheeva.git/blob - fs/nfs/nfs3xdr.c
3d1043f7667c13c759929b75b153b4e36c269532
[mv-sheeva.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_fsstat_sz          
46 #define NFS3_fsinfo_sz          
47 #define NFS3_pathconf_sz                
48 #define NFS3_entry_sz           (NFS3_filename_sz+3)
49
50 #define NFS3_sattrargs_sz       (NFS3_fh_sz+NFS3_sattr_sz+3)
51 #define NFS3_diropargs_sz       (NFS3_fh_sz+NFS3_filename_sz)
52 #define NFS3_removeargs_sz      (NFS3_fh_sz+NFS3_filename_sz)
53 #define NFS3_accessargs_sz      (NFS3_fh_sz+1)
54 #define NFS3_readlinkargs_sz    (NFS3_fh_sz)
55 #define NFS3_readargs_sz        (NFS3_fh_sz+3)
56 #define NFS3_writeargs_sz       (NFS3_fh_sz+5)
57 #define NFS3_createargs_sz      (NFS3_diropargs_sz+NFS3_sattr_sz)
58 #define NFS3_mkdirargs_sz       (NFS3_diropargs_sz+NFS3_sattr_sz)
59 #define NFS3_symlinkargs_sz     (NFS3_diropargs_sz+1+NFS3_sattr_sz)
60 #define NFS3_mknodargs_sz       (NFS3_diropargs_sz+2+NFS3_sattr_sz)
61 #define NFS3_renameargs_sz      (NFS3_diropargs_sz+NFS3_diropargs_sz)
62 #define NFS3_linkargs_sz                (NFS3_fh_sz+NFS3_diropargs_sz)
63 #define NFS3_readdirargs_sz     (NFS3_fh_sz+NFS3_cookieverf_sz+3)
64 #define NFS3_readdirplusargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+4)
65 #define NFS3_commitargs_sz      (NFS3_fh_sz+3)
66
67 #define NFS3_attrstat_sz        (1+NFS3_fattr_sz)
68 #define NFS3_wccstat_sz         (1+NFS3_wcc_data_sz)
69 #define NFS3_removeres_sz       (NFS3_wccstat_sz)
70 #define NFS3_lookupres_sz       (1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz))
71 #define NFS3_accessres_sz       (1+NFS3_post_op_attr_sz+1)
72 #define NFS3_readlinkres_sz     (1+NFS3_post_op_attr_sz+1)
73 #define NFS3_readres_sz         (1+NFS3_post_op_attr_sz+3)
74 #define NFS3_writeres_sz        (1+NFS3_wcc_data_sz+4)
75 #define NFS3_createres_sz       (1+NFS3_fh_sz+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
76 #define NFS3_renameres_sz       (1+(2 * NFS3_wcc_data_sz))
77 #define NFS3_linkres_sz         (1+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
78 #define NFS3_readdirres_sz      (1+NFS3_post_op_attr_sz+2)
79 #define NFS3_fsstatres_sz       (1+NFS3_post_op_attr_sz+13)
80 #define NFS3_fsinfores_sz       (1+NFS3_post_op_attr_sz+12)
81 #define NFS3_pathconfres_sz     (1+NFS3_post_op_attr_sz+6)
82 #define NFS3_commitres_sz       (1+NFS3_wcc_data_sz+2)
83
84 #define ACL3_getaclargs_sz      (NFS3_fh_sz+1)
85 #define ACL3_setaclargs_sz      (NFS3_fh_sz+1+ \
86                                 XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
87 #define ACL3_getaclres_sz       (1+NFS3_post_op_attr_sz+1+ \
88                                 XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
89 #define ACL3_setaclres_sz       (1+NFS3_post_op_attr_sz)
90
91 /*
92  * Map file type to S_IFMT bits
93  */
94 static const umode_t nfs_type2fmt[] = {
95         [NF3BAD] = 0,
96         [NF3REG] = S_IFREG,
97         [NF3DIR] = S_IFDIR,
98         [NF3BLK] = S_IFBLK,
99         [NF3CHR] = S_IFCHR,
100         [NF3LNK] = S_IFLNK,
101         [NF3SOCK] = S_IFSOCK,
102         [NF3FIFO] = S_IFIFO,
103 };
104
105 static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
106 {
107         dprintk("nfs: %s: prematurely hit end of receive buffer. "
108                 "Remaining buffer length is %tu words.\n",
109                 func, xdr->end - xdr->p);
110 }
111
112 /*
113  * While encoding arguments, set up the reply buffer in advance to
114  * receive reply data directly into the page cache.
115  */
116 static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
117                                  unsigned int base, unsigned int len,
118                                  unsigned int bufsize)
119 {
120         struct rpc_auth *auth = req->rq_cred->cr_auth;
121         unsigned int replen;
122
123         replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
124         xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
125 }
126
127
128 /*
129  * Common NFS XDR functions as inlines
130  */
131 static inline __be32 *
132 xdr_encode_fhandle(__be32 *p, const struct nfs_fh *fh)
133 {
134         return xdr_encode_array(p, fh->data, fh->size);
135 }
136
137 static inline __be32 *
138 xdr_decode_fhandle(__be32 *p, struct nfs_fh *fh)
139 {
140         if ((fh->size = ntohl(*p++)) <= NFS3_FHSIZE) {
141                 memcpy(fh->data, p, fh->size);
142                 return p + XDR_QUADLEN(fh->size);
143         }
144         return NULL;
145 }
146
147 static inline __be32 *
148 xdr_decode_fhandle_stream(struct xdr_stream *xdr, struct nfs_fh *fh)
149 {
150         __be32 *p;
151         p = xdr_inline_decode(xdr, 4);
152         if (unlikely(!p))
153                 goto out_overflow;
154         fh->size = ntohl(*p++);
155
156         if (fh->size <= NFS3_FHSIZE) {
157                 p = xdr_inline_decode(xdr, fh->size);
158                 if (unlikely(!p))
159                         goto out_overflow;
160                 memcpy(fh->data, p, fh->size);
161                 return p + XDR_QUADLEN(fh->size);
162         }
163         return NULL;
164
165 out_overflow:
166         print_overflow_msg(__func__, xdr);
167         return ERR_PTR(-EIO);
168 }
169
170 /*
171  * Encode/decode time.
172  */
173 static inline __be32 *
174 xdr_encode_time3(__be32 *p, const struct timespec *timep)
175 {
176         *p++ = htonl(timep->tv_sec);
177         *p++ = htonl(timep->tv_nsec);
178         return p;
179 }
180
181 static inline __be32 *
182 xdr_decode_time3(__be32 *p, struct timespec *timep)
183 {
184         timep->tv_sec = ntohl(*p++);
185         timep->tv_nsec = ntohl(*p++);
186         return p;
187 }
188
189 static __be32 *
190 xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
191 {
192         unsigned int    type, major, minor;
193         umode_t         fmode;
194
195         type = ntohl(*p++);
196         if (type > NF3FIFO)
197                 type = NF3NON;
198         fmode = nfs_type2fmt[type];
199         fattr->mode = (ntohl(*p++) & ~S_IFMT) | fmode;
200         fattr->nlink = ntohl(*p++);
201         fattr->uid = ntohl(*p++);
202         fattr->gid = ntohl(*p++);
203         p = xdr_decode_hyper(p, &fattr->size);
204         p = xdr_decode_hyper(p, &fattr->du.nfs3.used);
205
206         /* Turn remote device info into Linux-specific dev_t */
207         major = ntohl(*p++);
208         minor = ntohl(*p++);
209         fattr->rdev = MKDEV(major, minor);
210         if (MAJOR(fattr->rdev) != major || MINOR(fattr->rdev) != minor)
211                 fattr->rdev = 0;
212
213         p = xdr_decode_hyper(p, &fattr->fsid.major);
214         fattr->fsid.minor = 0;
215         p = xdr_decode_hyper(p, &fattr->fileid);
216         p = xdr_decode_time3(p, &fattr->atime);
217         p = xdr_decode_time3(p, &fattr->mtime);
218         p = xdr_decode_time3(p, &fattr->ctime);
219
220         /* Update the mode bits */
221         fattr->valid |= NFS_ATTR_FATTR_V3;
222         return p;
223 }
224
225 static inline __be32 *
226 xdr_encode_sattr(__be32 *p, const struct iattr *attr)
227 {
228         if (attr->ia_valid & ATTR_MODE) {
229                 *p++ = xdr_one;
230                 *p++ = htonl(attr->ia_mode & S_IALLUGO);
231         } else {
232                 *p++ = xdr_zero;
233         }
234         if (attr->ia_valid & ATTR_UID) {
235                 *p++ = xdr_one;
236                 *p++ = htonl(attr->ia_uid);
237         } else {
238                 *p++ = xdr_zero;
239         }
240         if (attr->ia_valid & ATTR_GID) {
241                 *p++ = xdr_one;
242                 *p++ = htonl(attr->ia_gid);
243         } else {
244                 *p++ = xdr_zero;
245         }
246         if (attr->ia_valid & ATTR_SIZE) {
247                 *p++ = xdr_one;
248                 p = xdr_encode_hyper(p, (__u64) attr->ia_size);
249         } else {
250                 *p++ = xdr_zero;
251         }
252         if (attr->ia_valid & ATTR_ATIME_SET) {
253                 *p++ = xdr_two;
254                 p = xdr_encode_time3(p, &attr->ia_atime);
255         } else if (attr->ia_valid & ATTR_ATIME) {
256                 *p++ = xdr_one;
257         } else {
258                 *p++ = xdr_zero;
259         }
260         if (attr->ia_valid & ATTR_MTIME_SET) {
261                 *p++ = xdr_two;
262                 p = xdr_encode_time3(p, &attr->ia_mtime);
263         } else if (attr->ia_valid & ATTR_MTIME) {
264                 *p++ = xdr_one;
265         } else {
266                 *p++ = xdr_zero;
267         }
268         return p;
269 }
270
271 static inline __be32 *
272 xdr_decode_wcc_attr(__be32 *p, struct nfs_fattr *fattr)
273 {
274         p = xdr_decode_hyper(p, &fattr->pre_size);
275         p = xdr_decode_time3(p, &fattr->pre_mtime);
276         p = xdr_decode_time3(p, &fattr->pre_ctime);
277         fattr->valid |= NFS_ATTR_FATTR_PRESIZE
278                 | NFS_ATTR_FATTR_PREMTIME
279                 | NFS_ATTR_FATTR_PRECTIME;
280         return p;
281 }
282
283 static inline __be32 *
284 xdr_decode_post_op_attr(__be32 *p, struct nfs_fattr *fattr)
285 {
286         if (*p++)
287                 p = xdr_decode_fattr(p, fattr);
288         return p;
289 }
290
291 static inline __be32 *
292 xdr_decode_post_op_attr_stream(struct xdr_stream *xdr, struct nfs_fattr *fattr)
293 {
294         __be32 *p;
295
296         p = xdr_inline_decode(xdr, 4);
297         if (unlikely(!p))
298                 goto out_overflow;
299         if (ntohl(*p++)) {
300                 p = xdr_inline_decode(xdr, 84);
301                 if (unlikely(!p))
302                         goto out_overflow;
303                 p = xdr_decode_fattr(p, fattr);
304         }
305         return p;
306 out_overflow:
307         print_overflow_msg(__func__, xdr);
308         return ERR_PTR(-EIO);
309 }
310
311 static inline __be32 *
312 xdr_decode_pre_op_attr(__be32 *p, struct nfs_fattr *fattr)
313 {
314         if (*p++)
315                 return xdr_decode_wcc_attr(p, fattr);
316         return p;
317 }
318
319
320 static inline __be32 *
321 xdr_decode_wcc_data(__be32 *p, struct nfs_fattr *fattr)
322 {
323         p = xdr_decode_pre_op_attr(p, fattr);
324         return xdr_decode_post_op_attr(p, fattr);
325 }
326
327
328 /*
329  * Encode/decode NFSv3 basic data types
330  *
331  * Basic NFSv3 data types are defined in section 2.5 of RFC 1813:
332  * "NFS Version 3 Protocol Specification".
333  *
334  * Not all basic data types have their own encoding and decoding
335  * functions.  For run-time efficiency, some data types are encoded
336  * or decoded inline.
337  */
338
339 static void encode_uint32(struct xdr_stream *xdr, u32 value)
340 {
341         __be32 *p = xdr_reserve_space(xdr, 4);
342         *p = cpu_to_be32(value);
343 }
344
345 /*
346  * filename3
347  *
348  *      typedef string filename3<>;
349  */
350 static void encode_filename3(struct xdr_stream *xdr,
351                              const char *name, u32 length)
352 {
353         __be32 *p;
354
355         BUG_ON(length > NFS3_MAXNAMLEN);
356         p = xdr_reserve_space(xdr, 4 + length);
357         xdr_encode_opaque(p, name, length);
358 }
359
360 /*
361  * nfspath3
362  *
363  *      typedef string nfspath3<>;
364  */
365 static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages,
366                             const u32 length)
367 {
368         BUG_ON(length > NFS3_MAXPATHLEN);
369         encode_uint32(xdr, length);
370         xdr_write_pages(xdr, pages, 0, length);
371 }
372
373 /*
374  * cookie3
375  *
376  *      typedef uint64 cookie3
377  */
378 static __be32 *xdr_encode_cookie3(__be32 *p, u64 cookie)
379 {
380         return xdr_encode_hyper(p, cookie);
381 }
382
383 /*
384  * cookieverf3
385  *
386  *      typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
387  */
388 static __be32 *xdr_encode_cookieverf3(__be32 *p, const __be32 *verifier)
389 {
390         memcpy(p, verifier, NFS3_COOKIEVERFSIZE);
391         return p + XDR_QUADLEN(NFS3_COOKIEVERFSIZE);
392 }
393
394 /*
395  * createverf3
396  *
397  *      typedef opaque createverf3[NFS3_CREATEVERFSIZE];
398  */
399 static void encode_createverf3(struct xdr_stream *xdr, const __be32 *verifier)
400 {
401         __be32 *p;
402
403         p = xdr_reserve_space(xdr, NFS3_CREATEVERFSIZE);
404         memcpy(p, verifier, NFS3_CREATEVERFSIZE);
405 }
406
407 /*
408  * ftype3
409  *
410  *      enum ftype3 {
411  *              NF3REG  = 1,
412  *              NF3DIR  = 2,
413  *              NF3BLK  = 3,
414  *              NF3CHR  = 4,
415  *              NF3LNK  = 5,
416  *              NF3SOCK = 6,
417  *              NF3FIFO = 7
418  *      };
419  */
420 static void encode_ftype3(struct xdr_stream *xdr, const u32 type)
421 {
422         BUG_ON(type > NF3FIFO);
423         encode_uint32(xdr, type);
424 }
425
426 /*
427  * specdata3
428  *
429  *     struct specdata3 {
430  *             uint32  specdata1;
431  *             uint32  specdata2;
432  *     };
433  */
434 static void encode_specdata3(struct xdr_stream *xdr, const dev_t rdev)
435 {
436         __be32 *p;
437
438         p = xdr_reserve_space(xdr, 8);
439         *p++ = cpu_to_be32(MAJOR(rdev));
440         *p = cpu_to_be32(MINOR(rdev));
441 }
442
443 /*
444  * nfs_fh3
445  *
446  *      struct nfs_fh3 {
447  *              opaque       data<NFS3_FHSIZE>;
448  *      };
449  */
450 static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh)
451 {
452         __be32 *p;
453
454         BUG_ON(fh->size > NFS3_FHSIZE);
455         p = xdr_reserve_space(xdr, 4 + fh->size);
456         xdr_encode_opaque(p, fh->data, fh->size);
457 }
458
459 /*
460  * sattr3
461  *
462  *      enum time_how {
463  *              DONT_CHANGE             = 0,
464  *              SET_TO_SERVER_TIME      = 1,
465  *              SET_TO_CLIENT_TIME      = 2
466  *      };
467  *
468  *      union set_mode3 switch (bool set_it) {
469  *      case TRUE:
470  *              mode3   mode;
471  *      default:
472  *              void;
473  *      };
474  *
475  *      union set_uid3 switch (bool set_it) {
476  *      case TRUE:
477  *              uid3    uid;
478  *      default:
479  *              void;
480  *      };
481  *
482  *      union set_gid3 switch (bool set_it) {
483  *      case TRUE:
484  *              gid3    gid;
485  *      default:
486  *              void;
487  *      };
488  *
489  *      union set_size3 switch (bool set_it) {
490  *      case TRUE:
491  *              size3   size;
492  *      default:
493  *              void;
494  *      };
495  *
496  *      union set_atime switch (time_how set_it) {
497  *      case SET_TO_CLIENT_TIME:
498  *              nfstime3        atime;
499  *      default:
500  *              void;
501  *      };
502  *
503  *      union set_mtime switch (time_how set_it) {
504  *      case SET_TO_CLIENT_TIME:
505  *              nfstime3  mtime;
506  *      default:
507  *              void;
508  *      };
509  *
510  *      struct sattr3 {
511  *              set_mode3       mode;
512  *              set_uid3        uid;
513  *              set_gid3        gid;
514  *              set_size3       size;
515  *              set_atime       atime;
516  *              set_mtime       mtime;
517  *      };
518  */
519 static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)
520 {
521         u32 nbytes;
522         __be32 *p;
523
524         /*
525          * In order to make only a single xdr_reserve_space() call,
526          * pre-compute the total number of bytes to be reserved.
527          * Six boolean values, one for each set_foo field, are always
528          * present in the encoded result, so start there.
529          */
530         nbytes = 6 * 4;
531         if (attr->ia_valid & ATTR_MODE)
532                 nbytes += 4;
533         if (attr->ia_valid & ATTR_UID)
534                 nbytes += 4;
535         if (attr->ia_valid & ATTR_GID)
536                 nbytes += 4;
537         if (attr->ia_valid & ATTR_SIZE)
538                 nbytes += 8;
539         if (attr->ia_valid & ATTR_ATIME_SET)
540                 nbytes += 8;
541         if (attr->ia_valid & ATTR_MTIME_SET)
542                 nbytes += 8;
543         p = xdr_reserve_space(xdr, nbytes);
544
545         xdr_encode_sattr(p, attr);
546 }
547
548 /*
549  * diropargs3
550  *
551  *      struct diropargs3 {
552  *              nfs_fh3         dir;
553  *              filename3       name;
554  *      };
555  */
556 static void encode_diropargs3(struct xdr_stream *xdr, const struct nfs_fh *fh,
557                               const char *name, u32 length)
558 {
559         encode_nfs_fh3(xdr, fh);
560         encode_filename3(xdr, name, length);
561 }
562
563
564 /*
565  * NFS encode functions
566  */
567
568 /*
569  * Encode file handle argument
570  */
571 static int
572 nfs3_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh)
573 {
574         p = xdr_encode_fhandle(p, fh);
575         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
576         return 0;
577 }
578
579 /*
580  * 3.3.1  GETATTR3args
581  *
582  *      struct GETATTR3args {
583  *              nfs_fh3  object;
584  *      };
585  */
586 static int nfs3_xdr_enc_getattr3args(struct rpc_rqst *req, __be32 *p,
587                                      const struct nfs_fh *fh)
588 {
589         struct xdr_stream xdr;
590
591         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
592         encode_nfs_fh3(&xdr, fh);
593         return 0;
594 }
595
596 /*
597  * Encode SETATTR arguments
598  */
599 static int
600 nfs3_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs3_sattrargs *args)
601 {
602         p = xdr_encode_fhandle(p, args->fh);
603         p = xdr_encode_sattr(p, args->sattr);
604         *p++ = htonl(args->guard);
605         if (args->guard)
606                 p = xdr_encode_time3(p, &args->guardtime);
607         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
608         return 0;
609 }
610
611 /*
612  * 3.3.2  SETATTR3args
613  *
614  *      union sattrguard3 switch (bool check) {
615  *      case TRUE:
616  *              nfstime3  obj_ctime;
617  *      case FALSE:
618  *              void;
619  *      };
620  *
621  *      struct SETATTR3args {
622  *              nfs_fh3         object;
623  *              sattr3          new_attributes;
624  *              sattrguard3     guard;
625  *      };
626  */
627 static void encode_sattrguard3(struct xdr_stream *xdr,
628                                const struct nfs3_sattrargs *args)
629 {
630         __be32 *p;
631
632         if (args->guard) {
633                 p = xdr_reserve_space(xdr, 4 + 8);
634                 *p++ = xdr_one;
635                 xdr_encode_time3(p, &args->guardtime);
636         } else {
637                 p = xdr_reserve_space(xdr, 4);
638                 *p = xdr_zero;
639         }
640 }
641
642 static int nfs3_xdr_enc_setattr3args(struct rpc_rqst *req, __be32 *p,
643                                      const struct nfs3_sattrargs *args)
644 {
645         struct xdr_stream xdr;
646
647         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
648         encode_nfs_fh3(&xdr, args->fh);
649         encode_sattr3(&xdr, args->sattr);
650         encode_sattrguard3(&xdr, args);
651         return 0;
652 }
653
654 /*
655  * Encode directory ops argument
656  */
657 static int
658 nfs3_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs3_diropargs *args)
659 {
660         p = xdr_encode_fhandle(p, args->fh);
661         p = xdr_encode_array(p, args->name, args->len);
662         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
663         return 0;
664 }
665
666 /*
667  * 3.3.3  LOOKUP3args
668  *
669  *      struct LOOKUP3args {
670  *              diropargs3  what;
671  *      };
672  */
673 static int nfs3_xdr_enc_lookup3args(struct rpc_rqst *req, __be32 *p,
674                                     const struct nfs3_diropargs *args)
675 {
676         struct xdr_stream xdr;
677
678         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
679         encode_diropargs3(&xdr, args->fh, args->name, args->len);
680         return 0;
681 }
682
683 /*
684  * Encode REMOVE argument
685  */
686 static int
687 nfs3_xdr_removeargs(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args)
688 {
689         p = xdr_encode_fhandle(p, args->fh);
690         p = xdr_encode_array(p, args->name.name, args->name.len);
691         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
692         return 0;
693 }
694
695 /*
696  * Encode access() argument
697  */
698 static int
699 nfs3_xdr_accessargs(struct rpc_rqst *req, __be32 *p, struct nfs3_accessargs *args)
700 {
701         p = xdr_encode_fhandle(p, args->fh);
702         *p++ = htonl(args->access);
703         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
704         return 0;
705 }
706
707 /*
708  * 3.3.4  ACCESS3args
709  *
710  *      struct ACCESS3args {
711  *              nfs_fh3         object;
712  *              uint32          access;
713  *      };
714  */
715 static void encode_access3args(struct xdr_stream *xdr,
716                                const struct nfs3_accessargs *args)
717 {
718         encode_nfs_fh3(xdr, args->fh);
719         encode_uint32(xdr, args->access);
720 }
721
722 static int nfs3_xdr_enc_access3args(struct rpc_rqst *req, __be32 *p,
723                                     const struct nfs3_accessargs *args)
724 {
725         struct xdr_stream xdr;
726
727         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
728         encode_access3args(&xdr, args);
729         return 0;
730 }
731
732 /*
733  * 3.3.5  READLINK3args
734  *
735  *      struct READLINK3args {
736  *              nfs_fh3 symlink;
737  *      };
738  */
739 static int nfs3_xdr_enc_readlink3args(struct rpc_rqst *req, __be32 *p,
740                                       const struct nfs3_readlinkargs *args)
741 {
742         struct xdr_stream xdr;
743
744         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
745         encode_nfs_fh3(&xdr, args->fh);
746         prepare_reply_buffer(req, args->pages, args->pgbase,
747                                         args->pglen, NFS3_readlinkres_sz);
748         return 0;
749 }
750
751 /*
752  * Arguments to a READ call. Since we read data directly into the page
753  * cache, we also set up the reply iovec here so that iov[1] points
754  * exactly to the page we want to fetch.
755  */
756 static int
757 nfs3_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
758 {
759         struct rpc_auth *auth = req->rq_cred->cr_auth;
760         unsigned int replen;
761         u32 count = args->count;
762
763         p = xdr_encode_fhandle(p, args->fh);
764         p = xdr_encode_hyper(p, args->offset);
765         *p++ = htonl(count);
766         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
767
768         /* Inline the page array */
769         replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readres_sz) << 2;
770         xdr_inline_pages(&req->rq_rcv_buf, replen,
771                          args->pages, args->pgbase, count);
772         req->rq_rcv_buf.flags |= XDRBUF_READ;
773         return 0;
774 }
775
776 /*
777  * 3.3.6  READ3args
778  *
779  *      struct READ3args {
780  *              nfs_fh3         file;
781  *              offset3         offset;
782  *              count3          count;
783  *      };
784  */
785 static void encode_read3args(struct xdr_stream *xdr,
786                              const struct nfs_readargs *args)
787 {
788         __be32 *p;
789
790         encode_nfs_fh3(xdr, args->fh);
791
792         p = xdr_reserve_space(xdr, 8 + 4);
793         p = xdr_encode_hyper(p, args->offset);
794         *p = cpu_to_be32(args->count);
795 }
796
797 static int nfs3_xdr_enc_read3args(struct rpc_rqst *req, __be32 *p,
798                                   const struct nfs_readargs *args)
799 {
800         struct xdr_stream xdr;
801
802         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
803         encode_read3args(&xdr, args);
804         prepare_reply_buffer(req, args->pages, args->pgbase,
805                                         args->count, NFS3_readres_sz);
806         req->rq_rcv_buf.flags |= XDRBUF_READ;
807         return 0;
808 }
809
810 /*
811  * Write arguments. Splice the buffer to be written into the iovec.
812  */
813 static int
814 nfs3_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
815 {
816         struct xdr_buf *sndbuf = &req->rq_snd_buf;
817         u32 count = args->count;
818
819         p = xdr_encode_fhandle(p, args->fh);
820         p = xdr_encode_hyper(p, args->offset);
821         *p++ = htonl(count);
822         *p++ = htonl(args->stable);
823         *p++ = htonl(count);
824         sndbuf->len = xdr_adjust_iovec(sndbuf->head, p);
825
826         /* Copy the page array */
827         xdr_encode_pages(sndbuf, args->pages, args->pgbase, count);
828         sndbuf->flags |= XDRBUF_WRITE;
829         return 0;
830 }
831
832 /*
833  * 3.3.7  WRITE3args
834  *
835  *      enum stable_how {
836  *              UNSTABLE  = 0,
837  *              DATA_SYNC = 1,
838  *              FILE_SYNC = 2
839  *      };
840  *
841  *      struct WRITE3args {
842  *              nfs_fh3         file;
843  *              offset3         offset;
844  *              count3          count;
845  *              stable_how      stable;
846  *              opaque          data<>;
847  *      };
848  */
849 static void encode_write3args(struct xdr_stream *xdr,
850                               const struct nfs_writeargs *args)
851 {
852         __be32 *p;
853
854         encode_nfs_fh3(xdr, args->fh);
855
856         p = xdr_reserve_space(xdr, 8 + 4 + 4 + 4);
857         p = xdr_encode_hyper(p, args->offset);
858         *p++ = cpu_to_be32(args->count);
859
860         BUG_ON(args->stable > NFS_FILE_SYNC);
861         *p++ = cpu_to_be32(args->stable);
862
863         *p = cpu_to_be32(args->count);
864         xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
865 }
866
867 static int nfs3_xdr_enc_write3args(struct rpc_rqst *req, __be32 *p,
868                                    const struct nfs_writeargs *args)
869 {
870         struct xdr_stream xdr;
871
872         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
873         encode_write3args(&xdr, args);
874         xdr.buf->flags |= XDRBUF_WRITE;
875         return 0;
876 }
877
878 /*
879  * Encode CREATE arguments
880  */
881 static int
882 nfs3_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs3_createargs *args)
883 {
884         p = xdr_encode_fhandle(p, args->fh);
885         p = xdr_encode_array(p, args->name, args->len);
886
887         *p++ = htonl(args->createmode);
888         if (args->createmode == NFS3_CREATE_EXCLUSIVE) {
889                 *p++ = args->verifier[0];
890                 *p++ = args->verifier[1];
891         } else
892                 p = xdr_encode_sattr(p, args->sattr);
893
894         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
895         return 0;
896 }
897
898 /*
899  * 3.3.8  CREATE3args
900  *
901  *      enum createmode3 {
902  *              UNCHECKED = 0,
903  *              GUARDED   = 1,
904  *              EXCLUSIVE = 2
905  *      };
906  *
907  *      union createhow3 switch (createmode3 mode) {
908  *      case UNCHECKED:
909  *      case GUARDED:
910  *              sattr3       obj_attributes;
911  *      case EXCLUSIVE:
912  *              createverf3  verf;
913  *      };
914  *
915  *      struct CREATE3args {
916  *              diropargs3      where;
917  *              createhow3      how;
918  *      };
919  */
920 static void encode_createhow3(struct xdr_stream *xdr,
921                               const struct nfs3_createargs *args)
922 {
923         encode_uint32(xdr, args->createmode);
924         switch (args->createmode) {
925         case NFS3_CREATE_UNCHECKED:
926         case NFS3_CREATE_GUARDED:
927                 encode_sattr3(xdr, args->sattr);
928                 break;
929         case NFS3_CREATE_EXCLUSIVE:
930                 encode_createverf3(xdr, args->verifier);
931                 break;
932         default:
933                 BUG();
934         }
935 }
936
937 static int nfs3_xdr_enc_create3args(struct rpc_rqst *req, __be32 *p,
938                                     const struct nfs3_createargs *args)
939 {
940         struct xdr_stream xdr;
941
942         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
943         encode_diropargs3(&xdr, args->fh, args->name, args->len);
944         encode_createhow3(&xdr, args);
945         return 0;
946 }
947
948 /*
949  * Encode MKDIR arguments
950  */
951 static int
952 nfs3_xdr_mkdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mkdirargs *args)
953 {
954         p = xdr_encode_fhandle(p, args->fh);
955         p = xdr_encode_array(p, args->name, args->len);
956         p = xdr_encode_sattr(p, args->sattr);
957         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
958         return 0;
959 }
960
961 /*
962  * 3.3.9  MKDIR3args
963  *
964  *      struct MKDIR3args {
965  *              diropargs3      where;
966  *              sattr3          attributes;
967  *      };
968  */
969 static int nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req, __be32 *p,
970                                    const struct nfs3_mkdirargs *args)
971 {
972         struct xdr_stream xdr;
973
974         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
975         encode_diropargs3(&xdr, args->fh, args->name, args->len);
976         encode_sattr3(&xdr, args->sattr);
977         return 0;
978 }
979
980 /*
981  * Encode SYMLINK arguments
982  */
983 static int
984 nfs3_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_symlinkargs *args)
985 {
986         p = xdr_encode_fhandle(p, args->fromfh);
987         p = xdr_encode_array(p, args->fromname, args->fromlen);
988         p = xdr_encode_sattr(p, args->sattr);
989         *p++ = htonl(args->pathlen);
990         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
991
992         /* Copy the page */
993         xdr_encode_pages(&req->rq_snd_buf, args->pages, 0, args->pathlen);
994         return 0;
995 }
996
997 /*
998  * 3.3.10  SYMLINK3args
999  *
1000  *      struct symlinkdata3 {
1001  *              sattr3          symlink_attributes;
1002  *              nfspath3        symlink_data;
1003  *      };
1004  *
1005  *      struct SYMLINK3args {
1006  *              diropargs3      where;
1007  *              symlinkdata3    symlink;
1008  *      };
1009  */
1010 static void encode_symlinkdata3(struct xdr_stream *xdr,
1011                                 const struct nfs3_symlinkargs *args)
1012 {
1013         encode_sattr3(xdr, args->sattr);
1014         encode_nfspath3(xdr, args->pages, args->pathlen);
1015 }
1016
1017 static int nfs3_xdr_enc_symlink3args(struct rpc_rqst *req, __be32 *p,
1018                                      const struct nfs3_symlinkargs *args)
1019 {
1020         struct xdr_stream xdr;
1021
1022         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1023         encode_diropargs3(&xdr, args->fromfh, args->fromname, args->fromlen);
1024         encode_symlinkdata3(&xdr, args);
1025         return 0;
1026 }
1027
1028 /*
1029  * Encode MKNOD arguments
1030  */
1031 static int
1032 nfs3_xdr_mknodargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mknodargs *args)
1033 {
1034         p = xdr_encode_fhandle(p, args->fh);
1035         p = xdr_encode_array(p, args->name, args->len);
1036         *p++ = htonl(args->type);
1037         p = xdr_encode_sattr(p, args->sattr);
1038         if (args->type == NF3CHR || args->type == NF3BLK) {
1039                 *p++ = htonl(MAJOR(args->rdev));
1040                 *p++ = htonl(MINOR(args->rdev));
1041         }
1042
1043         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
1044         return 0;
1045 }
1046
1047 /*
1048  * 3.3.11  MKNOD3args
1049  *
1050  *      struct devicedata3 {
1051  *              sattr3          dev_attributes;
1052  *              specdata3       spec;
1053  *      };
1054  *
1055  *      union mknoddata3 switch (ftype3 type) {
1056  *      case NF3CHR:
1057  *      case NF3BLK:
1058  *              devicedata3     device;
1059  *      case NF3SOCK:
1060  *      case NF3FIFO:
1061  *              sattr3          pipe_attributes;
1062  *      default:
1063  *              void;
1064  *      };
1065  *
1066  *      struct MKNOD3args {
1067  *              diropargs3      where;
1068  *              mknoddata3      what;
1069  *      };
1070  */
1071 static void encode_devicedata3(struct xdr_stream *xdr,
1072                                const struct nfs3_mknodargs *args)
1073 {
1074         encode_sattr3(xdr, args->sattr);
1075         encode_specdata3(xdr, args->rdev);
1076 }
1077
1078 static void encode_mknoddata3(struct xdr_stream *xdr,
1079                               const struct nfs3_mknodargs *args)
1080 {
1081         encode_ftype3(xdr, args->type);
1082         switch (args->type) {
1083         case NF3CHR:
1084         case NF3BLK:
1085                 encode_devicedata3(xdr, args);
1086                 break;
1087         case NF3SOCK:
1088         case NF3FIFO:
1089                 encode_sattr3(xdr, args->sattr);
1090                 break;
1091         case NF3REG:
1092         case NF3DIR:
1093                 break;
1094         default:
1095                 BUG();
1096         }
1097 }
1098
1099 static int nfs3_xdr_enc_mknod3args(struct rpc_rqst *req, __be32 *p,
1100                                    const struct nfs3_mknodargs *args)
1101 {
1102         struct xdr_stream xdr;
1103
1104         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1105         encode_diropargs3(&xdr, args->fh, args->name, args->len);
1106         encode_mknoddata3(&xdr, args);
1107         return 0;
1108 }
1109
1110 /*
1111  * 3.3.12  REMOVE3args
1112  *
1113  *      struct REMOVE3args {
1114  *              diropargs3  object;
1115  *      };
1116  */
1117 static int nfs3_xdr_enc_remove3args(struct rpc_rqst *req, __be32 *p,
1118                                     const struct nfs_removeargs *args)
1119 {
1120         struct xdr_stream xdr;
1121
1122         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1123         encode_diropargs3(&xdr, args->fh, args->name.name, args->name.len);
1124         return 0;
1125 }
1126
1127 /*
1128  * Encode RENAME arguments
1129  */
1130 static int
1131 nfs3_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs_renameargs *args)
1132 {
1133         p = xdr_encode_fhandle(p, args->old_dir);
1134         p = xdr_encode_array(p, args->old_name->name, args->old_name->len);
1135         p = xdr_encode_fhandle(p, args->new_dir);
1136         p = xdr_encode_array(p, args->new_name->name, args->new_name->len);
1137         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
1138         return 0;
1139 }
1140
1141 /*
1142  * 3.3.14  RENAME3args
1143  *
1144  *      struct RENAME3args {
1145  *              diropargs3      from;
1146  *              diropargs3      to;
1147  *      };
1148  */
1149 static int nfs3_xdr_enc_rename3args(struct rpc_rqst *req, __be32 *p,
1150                                     const struct nfs_renameargs *args)
1151 {
1152         const struct qstr *old = args->old_name;
1153         const struct qstr *new = args->new_name;
1154         struct xdr_stream xdr;
1155
1156         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1157         encode_diropargs3(&xdr, args->old_dir, old->name, old->len);
1158         encode_diropargs3(&xdr, args->new_dir, new->name, new->len);
1159         return 0;
1160 }
1161
1162 /*
1163  * Encode LINK arguments
1164  */
1165 static int
1166 nfs3_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_linkargs *args)
1167 {
1168         p = xdr_encode_fhandle(p, args->fromfh);
1169         p = xdr_encode_fhandle(p, args->tofh);
1170         p = xdr_encode_array(p, args->toname, args->tolen);
1171         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
1172         return 0;
1173 }
1174
1175 /*
1176  * 3.3.15  LINK3args
1177  *
1178  *      struct LINK3args {
1179  *              nfs_fh3         file;
1180  *              diropargs3      link;
1181  *      };
1182  */
1183 static int nfs3_xdr_enc_link3args(struct rpc_rqst *req, __be32 *p,
1184                                   const struct nfs3_linkargs *args)
1185 {
1186         struct xdr_stream xdr;
1187
1188         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1189         encode_nfs_fh3(&xdr, args->fromfh);
1190         encode_diropargs3(&xdr, args->tofh, args->toname, args->tolen);
1191         return 0;
1192 }
1193
1194 /*
1195  * Encode arguments to readdir call
1196  */
1197 static int
1198 nfs3_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirargs *args)
1199 {
1200         struct rpc_auth *auth = req->rq_cred->cr_auth;
1201         unsigned int replen;
1202         u32 count = args->count;
1203
1204         p = xdr_encode_fhandle(p, args->fh);
1205         p = xdr_encode_hyper(p, args->cookie);
1206         *p++ = args->verf[0];
1207         *p++ = args->verf[1];
1208         if (args->plus) {
1209                 /* readdirplus: need dircount + buffer size.
1210                  * We just make sure we make dircount big enough */
1211                 *p++ = htonl(count >> 3);
1212         }
1213         *p++ = htonl(count);
1214         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
1215
1216         /* Inline the page array */
1217         replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readdirres_sz) << 2;
1218         xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0, count);
1219         return 0;
1220 }
1221
1222 /*
1223  * 3.3.16  READDIR3args
1224  *
1225  *      struct READDIR3args {
1226  *              nfs_fh3         dir;
1227  *              cookie3         cookie;
1228  *              cookieverf3     cookieverf;
1229  *              count3          count;
1230  *      };
1231  */
1232 static void encode_readdir3args(struct xdr_stream *xdr,
1233                                 const struct nfs3_readdirargs *args)
1234 {
1235         __be32 *p;
1236
1237         encode_nfs_fh3(xdr, args->fh);
1238
1239         p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4);
1240         p = xdr_encode_cookie3(p, args->cookie);
1241         p = xdr_encode_cookieverf3(p, args->verf);
1242         *p = cpu_to_be32(args->count);
1243 }
1244
1245 static int nfs3_xdr_enc_readdir3args(struct rpc_rqst *req, __be32 *p,
1246                                      const struct nfs3_readdirargs *args)
1247 {
1248         struct xdr_stream xdr;
1249
1250         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1251         encode_readdir3args(&xdr, args);
1252         prepare_reply_buffer(req, args->pages, 0,
1253                                 args->count, NFS3_readdirres_sz);
1254         return 0;
1255 }
1256
1257 /*
1258  * 3.3.17  READDIRPLUS3args
1259  *
1260  *      struct READDIRPLUS3args {
1261  *              nfs_fh3         dir;
1262  *              cookie3         cookie;
1263  *              cookieverf3     cookieverf;
1264  *              count3          dircount;
1265  *              count3          maxcount;
1266  *      };
1267  */
1268 static void encode_readdirplus3args(struct xdr_stream *xdr,
1269                                     const struct nfs3_readdirargs *args)
1270 {
1271         __be32 *p;
1272
1273         encode_nfs_fh3(xdr, args->fh);
1274
1275         p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4 + 4);
1276         p = xdr_encode_cookie3(p, args->cookie);
1277         p = xdr_encode_cookieverf3(p, args->verf);
1278
1279         /*
1280          * readdirplus: need dircount + buffer size.
1281          * We just make sure we make dircount big enough
1282          */
1283         *p++ = cpu_to_be32(args->count >> 3);
1284
1285         *p = cpu_to_be32(args->count);
1286 }
1287
1288 static int nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req, __be32 *p,
1289                                          const struct nfs3_readdirargs *args)
1290 {
1291         struct xdr_stream xdr;
1292
1293         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1294         encode_readdirplus3args(&xdr, args);
1295         prepare_reply_buffer(req, args->pages, 0,
1296                                 args->count, NFS3_readdirres_sz);
1297         return 0;
1298 }
1299
1300 /*
1301  * Decode the result of a readdir call.
1302  * We just check for syntactical correctness.
1303  */
1304 static int
1305 nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res)
1306 {
1307         struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
1308         struct kvec *iov = rcvbuf->head;
1309         struct page **page;
1310         size_t hdrlen;
1311         u32 recvd, pglen;
1312         int status;
1313
1314         status = ntohl(*p++);
1315         /* Decode post_op_attrs */
1316         p = xdr_decode_post_op_attr(p, res->dir_attr);
1317         if (status)
1318                 return nfs_stat_to_errno(status);
1319         /* Decode verifier cookie */
1320         if (res->verf) {
1321                 res->verf[0] = *p++;
1322                 res->verf[1] = *p++;
1323         } else {
1324                 p += 2;
1325         }
1326
1327         hdrlen = (u8 *) p - (u8 *) iov->iov_base;
1328         if (iov->iov_len < hdrlen) {
1329                 dprintk("NFS: READDIR reply header overflowed:"
1330                                 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1331                 return -errno_NFSERR_IO;
1332         } else if (iov->iov_len != hdrlen) {
1333                 dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
1334                 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
1335         }
1336
1337         pglen = rcvbuf->page_len;
1338         recvd = rcvbuf->len - hdrlen;
1339         if (pglen > recvd)
1340                 pglen = recvd;
1341         page = rcvbuf->pages;
1342
1343         return pglen;
1344 }
1345
1346 __be32 *
1347 nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_server *server, int plus)
1348 {
1349         __be32 *p;
1350         struct nfs_entry old = *entry;
1351
1352         p = xdr_inline_decode(xdr, 4);
1353         if (unlikely(!p))
1354                 goto out_overflow;
1355         if (!ntohl(*p++)) {
1356                 p = xdr_inline_decode(xdr, 4);
1357                 if (unlikely(!p))
1358                         goto out_overflow;
1359                 if (!ntohl(*p++))
1360                         return ERR_PTR(-EAGAIN);
1361                 entry->eof = 1;
1362                 return ERR_PTR(-EBADCOOKIE);
1363         }
1364
1365         p = xdr_inline_decode(xdr, 12);
1366         if (unlikely(!p))
1367                 goto out_overflow;
1368         p = xdr_decode_hyper(p, &entry->ino);
1369         entry->len  = ntohl(*p++);
1370
1371         p = xdr_inline_decode(xdr, entry->len + 8);
1372         if (unlikely(!p))
1373                 goto out_overflow;
1374         entry->name = (const char *) p;
1375         p += XDR_QUADLEN(entry->len);
1376         entry->prev_cookie = entry->cookie;
1377         p = xdr_decode_hyper(p, &entry->cookie);
1378
1379         entry->d_type = DT_UNKNOWN;
1380         if (plus) {
1381                 entry->fattr->valid = 0;
1382                 p = xdr_decode_post_op_attr_stream(xdr, entry->fattr);
1383                 if (IS_ERR(p))
1384                         goto out_overflow_exit;
1385                 entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
1386                 /* In fact, a post_op_fh3: */
1387                 p = xdr_inline_decode(xdr, 4);
1388                 if (unlikely(!p))
1389                         goto out_overflow;
1390                 if (*p++) {
1391                         p = xdr_decode_fhandle_stream(xdr, entry->fh);
1392                         if (IS_ERR(p))
1393                                 goto out_overflow_exit;
1394                         /* Ugh -- server reply was truncated */
1395                         if (p == NULL) {
1396                                 dprintk("NFS: FH truncated\n");
1397                                 *entry = old;
1398                                 return ERR_PTR(-EAGAIN);
1399                         }
1400                 } else
1401                         memset((u8*)(entry->fh), 0, sizeof(*entry->fh));
1402         }
1403
1404         p = xdr_inline_peek(xdr, 8);
1405         if (p != NULL)
1406                 entry->eof = !p[0] && p[1];
1407         else
1408                 entry->eof = 0;
1409
1410         return p;
1411
1412 out_overflow:
1413         print_overflow_msg(__func__, xdr);
1414 out_overflow_exit:
1415         return ERR_PTR(-EAGAIN);
1416 }
1417
1418 /*
1419  * Encode COMMIT arguments
1420  */
1421 static int
1422 nfs3_xdr_commitargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
1423 {
1424         p = xdr_encode_fhandle(p, args->fh);
1425         p = xdr_encode_hyper(p, args->offset);
1426         *p++ = htonl(args->count);
1427         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
1428         return 0;
1429 }
1430
1431 /*
1432  * 3.3.21  COMMIT3args
1433  *
1434  *      struct COMMIT3args {
1435  *              nfs_fh3         file;
1436  *              offset3         offset;
1437  *              count3          count;
1438  *      };
1439  */
1440 static void encode_commit3args(struct xdr_stream *xdr,
1441                                const struct nfs_writeargs *args)
1442 {
1443         __be32 *p;
1444
1445         encode_nfs_fh3(xdr, args->fh);
1446
1447         p = xdr_reserve_space(xdr, 8 + 4);
1448         p = xdr_encode_hyper(p, args->offset);
1449         *p = cpu_to_be32(args->count);
1450 }
1451
1452 static int nfs3_xdr_enc_commit3args(struct rpc_rqst *req, __be32 *p,
1453                                     const struct nfs_writeargs *args)
1454 {
1455         struct xdr_stream xdr;
1456
1457         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1458         encode_commit3args(&xdr, args);
1459         return 0;
1460 }
1461
1462 #ifdef CONFIG_NFS_V3_ACL
1463 /*
1464  * Encode GETACL arguments
1465  */
1466 static int
1467 nfs3_xdr_getaclargs(struct rpc_rqst *req, __be32 *p,
1468                     struct nfs3_getaclargs *args)
1469 {
1470         struct rpc_auth *auth = req->rq_cred->cr_auth;
1471         unsigned int replen;
1472
1473         p = xdr_encode_fhandle(p, args->fh);
1474         *p++ = htonl(args->mask);
1475         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
1476
1477         if (args->mask & (NFS_ACL | NFS_DFACL)) {
1478                 /* Inline the page array */
1479                 replen = (RPC_REPHDRSIZE + auth->au_rslack +
1480                           ACL3_getaclres_sz) << 2;
1481                 xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0,
1482                                  NFSACL_MAXPAGES << PAGE_SHIFT);
1483         }
1484         return 0;
1485 }
1486
1487 static int nfs3_xdr_enc_getacl3args(struct rpc_rqst *req, __be32 *p,
1488                                     const struct nfs3_getaclargs *args)
1489 {
1490         struct xdr_stream xdr;
1491
1492         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1493         encode_nfs_fh3(&xdr, args->fh);
1494         encode_uint32(&xdr, args->mask);
1495         if (args->mask & (NFS_ACL | NFS_DFACL))
1496                 prepare_reply_buffer(req, args->pages, 0,
1497                                         NFSACL_MAXPAGES << PAGE_SHIFT,
1498                                         ACL3_getaclres_sz);
1499         return 0;
1500 }
1501
1502 /*
1503  * Encode SETACL arguments
1504  */
1505 static int
1506 nfs3_xdr_setaclargs(struct rpc_rqst *req, __be32 *p,
1507                    struct nfs3_setaclargs *args)
1508 {
1509         struct xdr_buf *buf = &req->rq_snd_buf;
1510         unsigned int base;
1511         int err;
1512
1513         p = xdr_encode_fhandle(p, NFS_FH(args->inode));
1514         *p++ = htonl(args->mask);
1515         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
1516         base = req->rq_slen;
1517
1518         if (args->npages != 0)
1519                 xdr_encode_pages(buf, args->pages, 0, args->len);
1520         else
1521                 req->rq_slen = xdr_adjust_iovec(req->rq_svec,
1522                                 p + XDR_QUADLEN(args->len));
1523
1524         err = nfsacl_encode(buf, base, args->inode,
1525                             (args->mask & NFS_ACL) ?
1526                             args->acl_access : NULL, 1, 0);
1527         if (err > 0)
1528                 err = nfsacl_encode(buf, base + err, args->inode,
1529                                     (args->mask & NFS_DFACL) ?
1530                                     args->acl_default : NULL, 1,
1531                                     NFS_ACL_DEFAULT);
1532         return (err > 0) ? 0 : err;
1533 }
1534
1535 static int nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, __be32 *p,
1536                                     const struct nfs3_setaclargs *args)
1537 {
1538         struct xdr_stream xdr;
1539         unsigned int base;
1540         int error;
1541
1542         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1543         encode_nfs_fh3(&xdr, NFS_FH(args->inode));
1544         encode_uint32(&xdr, args->mask);
1545         if (args->npages != 0)
1546                 xdr_write_pages(&xdr, args->pages, 0, args->len);
1547
1548         base = req->rq_slen;
1549         error = nfsacl_encode(xdr.buf, base, args->inode,
1550                             (args->mask & NFS_ACL) ?
1551                             args->acl_access : NULL, 1, 0);
1552         BUG_ON(error < 0);
1553         error = nfsacl_encode(xdr.buf, base + error, args->inode,
1554                             (args->mask & NFS_DFACL) ?
1555                             args->acl_default : NULL, 1,
1556                             NFS_ACL_DEFAULT);
1557         BUG_ON(error < 0);
1558         return 0;
1559 }
1560
1561 #endif  /* CONFIG_NFS_V3_ACL */
1562
1563 /*
1564  * NFS XDR decode functions
1565  */
1566
1567 /*
1568  * Decode attrstat reply.
1569  */
1570 static int
1571 nfs3_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1572 {
1573         int     status;
1574
1575         if ((status = ntohl(*p++)))
1576                 return nfs_stat_to_errno(status);
1577         xdr_decode_fattr(p, fattr);
1578         return 0;
1579 }
1580
1581 /*
1582  * Decode status+wcc_data reply
1583  * SATTR, REMOVE, RMDIR
1584  */
1585 static int
1586 nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1587 {
1588         int     status;
1589
1590         if ((status = ntohl(*p++)))
1591                 status = nfs_stat_to_errno(status);
1592         xdr_decode_wcc_data(p, fattr);
1593         return status;
1594 }
1595
1596 static int
1597 nfs3_xdr_removeres(struct rpc_rqst *req, __be32 *p, struct nfs_removeres *res)
1598 {
1599         return nfs3_xdr_wccstat(req, p, res->dir_attr);
1600 }
1601
1602 /*
1603  * Decode LOOKUP reply
1604  */
1605 static int
1606 nfs3_xdr_lookupres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
1607 {
1608         int     status;
1609
1610         if ((status = ntohl(*p++))) {
1611                 status = nfs_stat_to_errno(status);
1612         } else {
1613                 if (!(p = xdr_decode_fhandle(p, res->fh)))
1614                         return -errno_NFSERR_IO;
1615                 p = xdr_decode_post_op_attr(p, res->fattr);
1616         }
1617         xdr_decode_post_op_attr(p, res->dir_attr);
1618         return status;
1619 }
1620
1621 /*
1622  * Decode ACCESS reply
1623  */
1624 static int
1625 nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res)
1626 {
1627         int     status = ntohl(*p++);
1628
1629         p = xdr_decode_post_op_attr(p, res->fattr);
1630         if (status)
1631                 return nfs_stat_to_errno(status);
1632         res->access = ntohl(*p++);
1633         return 0;
1634 }
1635
1636 static int
1637 nfs3_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readlinkargs *args)
1638 {
1639         struct rpc_auth *auth = req->rq_cred->cr_auth;
1640         unsigned int replen;
1641
1642         p = xdr_encode_fhandle(p, args->fh);
1643         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
1644
1645         /* Inline the page array */
1646         replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readlinkres_sz) << 2;
1647         xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, args->pgbase, args->pglen);
1648         return 0;
1649 }
1650
1651 /*
1652  * Decode READLINK reply
1653  */
1654 static int
1655 nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1656 {
1657         struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
1658         struct kvec *iov = rcvbuf->head;
1659         size_t hdrlen;
1660         u32 len, recvd;
1661         int     status;
1662
1663         status = ntohl(*p++);
1664         p = xdr_decode_post_op_attr(p, fattr);
1665
1666         if (status != 0)
1667                 return nfs_stat_to_errno(status);
1668
1669         /* Convert length of symlink */
1670         len = ntohl(*p++);
1671         if (len >= rcvbuf->page_len) {
1672                 dprintk("nfs: server returned giant symlink!\n");
1673                 return -ENAMETOOLONG;
1674         }
1675
1676         hdrlen = (u8 *) p - (u8 *) iov->iov_base;
1677         if (iov->iov_len < hdrlen) {
1678                 dprintk("NFS: READLINK reply header overflowed:"
1679                                 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1680                 return -errno_NFSERR_IO;
1681         } else if (iov->iov_len != hdrlen) {
1682                 dprintk("NFS: READLINK header is short. "
1683                         "iovec will be shifted.\n");
1684                 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
1685         }
1686         recvd = req->rq_rcv_buf.len - hdrlen;
1687         if (recvd < len) {
1688                 dprintk("NFS: server cheating in readlink reply: "
1689                                 "count %u > recvd %u\n", len, recvd);
1690                 return -EIO;
1691         }
1692
1693         xdr_terminate_string(rcvbuf, len);
1694         return 0;
1695 }
1696
1697 /*
1698  * Decode READ reply
1699  */
1700 static int
1701 nfs3_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
1702 {
1703         struct kvec *iov = req->rq_rcv_buf.head;
1704         size_t hdrlen;
1705         u32 count, ocount, recvd;
1706         int status;
1707
1708         status = ntohl(*p++);
1709         p = xdr_decode_post_op_attr(p, res->fattr);
1710
1711         if (status != 0)
1712                 return nfs_stat_to_errno(status);
1713
1714         /* Decode reply count and EOF flag. NFSv3 is somewhat redundant
1715          * in that it puts the count both in the res struct and in the
1716          * opaque data count. */
1717         count    = ntohl(*p++);
1718         res->eof = ntohl(*p++);
1719         ocount   = ntohl(*p++);
1720
1721         if (ocount != count) {
1722                 dprintk("NFS: READ count doesn't match RPC opaque count.\n");
1723                 return -errno_NFSERR_IO;
1724         }
1725
1726         hdrlen = (u8 *) p - (u8 *) iov->iov_base;
1727         if (iov->iov_len < hdrlen) {
1728                 dprintk("NFS: READ reply header overflowed:"
1729                                 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1730                 return -errno_NFSERR_IO;
1731         } else if (iov->iov_len != hdrlen) {
1732                 dprintk("NFS: READ header is short. iovec will be shifted.\n");
1733                 xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
1734         }
1735
1736         recvd = req->rq_rcv_buf.len - hdrlen;
1737         if (count > recvd) {
1738                 dprintk("NFS: server cheating in read reply: "
1739                         "count %u > recvd %u\n", count, recvd);
1740                 count = recvd;
1741                 res->eof = 0;
1742         }
1743
1744         if (count < res->count)
1745                 res->count = count;
1746
1747         return count;
1748 }
1749
1750 /*
1751  * Decode WRITE response
1752  */
1753 static int
1754 nfs3_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
1755 {
1756         int     status;
1757
1758         status = ntohl(*p++);
1759         p = xdr_decode_wcc_data(p, res->fattr);
1760
1761         if (status != 0)
1762                 return nfs_stat_to_errno(status);
1763
1764         res->count = ntohl(*p++);
1765         res->verf->committed = (enum nfs3_stable_how)ntohl(*p++);
1766         res->verf->verifier[0] = *p++;
1767         res->verf->verifier[1] = *p++;
1768
1769         return res->count;
1770 }
1771
1772 /*
1773  * Decode a CREATE response
1774  */
1775 static int
1776 nfs3_xdr_createres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
1777 {
1778         int     status;
1779
1780         status = ntohl(*p++);
1781         if (status == 0) {
1782                 if (*p++) {
1783                         if (!(p = xdr_decode_fhandle(p, res->fh)))
1784                                 return -errno_NFSERR_IO;
1785                         p = xdr_decode_post_op_attr(p, res->fattr);
1786                 } else {
1787                         memset(res->fh, 0, sizeof(*res->fh));
1788                         /* Do decode post_op_attr but set it to NULL */
1789                         p = xdr_decode_post_op_attr(p, res->fattr);
1790                         res->fattr->valid = 0;
1791                 }
1792         } else {
1793                 status = nfs_stat_to_errno(status);
1794         }
1795         p = xdr_decode_wcc_data(p, res->dir_attr);
1796         return status;
1797 }
1798
1799 /*
1800  * Decode RENAME reply
1801  */
1802 static int
1803 nfs3_xdr_renameres(struct rpc_rqst *req, __be32 *p, struct nfs_renameres *res)
1804 {
1805         int     status;
1806
1807         if ((status = ntohl(*p++)) != 0)
1808                 status = nfs_stat_to_errno(status);
1809         p = xdr_decode_wcc_data(p, res->old_fattr);
1810         p = xdr_decode_wcc_data(p, res->new_fattr);
1811         return status;
1812 }
1813
1814 /*
1815  * Decode LINK reply
1816  */
1817 static int
1818 nfs3_xdr_linkres(struct rpc_rqst *req, __be32 *p, struct nfs3_linkres *res)
1819 {
1820         int     status;
1821
1822         if ((status = ntohl(*p++)) != 0)
1823                 status = nfs_stat_to_errno(status);
1824         p = xdr_decode_post_op_attr(p, res->fattr);
1825         p = xdr_decode_wcc_data(p, res->dir_attr);
1826         return status;
1827 }
1828
1829 /*
1830  * Decode FSSTAT reply
1831  */
1832 static int
1833 nfs3_xdr_fsstatres(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *res)
1834 {
1835         int             status;
1836
1837         status = ntohl(*p++);
1838
1839         p = xdr_decode_post_op_attr(p, res->fattr);
1840         if (status != 0)
1841                 return nfs_stat_to_errno(status);
1842
1843         p = xdr_decode_hyper(p, &res->tbytes);
1844         p = xdr_decode_hyper(p, &res->fbytes);
1845         p = xdr_decode_hyper(p, &res->abytes);
1846         p = xdr_decode_hyper(p, &res->tfiles);
1847         p = xdr_decode_hyper(p, &res->ffiles);
1848         p = xdr_decode_hyper(p, &res->afiles);
1849
1850         /* ignore invarsec */
1851         return 0;
1852 }
1853
1854 /*
1855  * Decode FSINFO reply
1856  */
1857 static int
1858 nfs3_xdr_fsinfores(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *res)
1859 {
1860         int             status;
1861
1862         status = ntohl(*p++);
1863
1864         p = xdr_decode_post_op_attr(p, res->fattr);
1865         if (status != 0)
1866                 return nfs_stat_to_errno(status);
1867
1868         res->rtmax  = ntohl(*p++);
1869         res->rtpref = ntohl(*p++);
1870         res->rtmult = ntohl(*p++);
1871         res->wtmax  = ntohl(*p++);
1872         res->wtpref = ntohl(*p++);
1873         res->wtmult = ntohl(*p++);
1874         res->dtpref = ntohl(*p++);
1875         p = xdr_decode_hyper(p, &res->maxfilesize);
1876         p = xdr_decode_time3(p, &res->time_delta);
1877
1878         /* ignore properties */
1879         res->lease_time = 0;
1880         return 0;
1881 }
1882
1883 /*
1884  * Decode PATHCONF reply
1885  */
1886 static int
1887 nfs3_xdr_pathconfres(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *res)
1888 {
1889         int             status;
1890
1891         status = ntohl(*p++);
1892
1893         p = xdr_decode_post_op_attr(p, res->fattr);
1894         if (status != 0)
1895                 return nfs_stat_to_errno(status);
1896         res->max_link = ntohl(*p++);
1897         res->max_namelen = ntohl(*p++);
1898
1899         /* ignore remaining fields */
1900         return 0;
1901 }
1902
1903 /*
1904  * Decode COMMIT reply
1905  */
1906 static int
1907 nfs3_xdr_commitres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
1908 {
1909         int             status;
1910
1911         status = ntohl(*p++);
1912         p = xdr_decode_wcc_data(p, res->fattr);
1913         if (status != 0)
1914                 return nfs_stat_to_errno(status);
1915
1916         res->verf->verifier[0] = *p++;
1917         res->verf->verifier[1] = *p++;
1918         return 0;
1919 }
1920
1921 #ifdef CONFIG_NFS_V3_ACL
1922 /*
1923  * Decode GETACL reply
1924  */
1925 static int
1926 nfs3_xdr_getaclres(struct rpc_rqst *req, __be32 *p,
1927                    struct nfs3_getaclres *res)
1928 {
1929         struct xdr_buf *buf = &req->rq_rcv_buf;
1930         int status = ntohl(*p++);
1931         struct posix_acl **acl;
1932         unsigned int *aclcnt;
1933         int err, base;
1934
1935         if (status != 0)
1936                 return nfs_stat_to_errno(status);
1937         p = xdr_decode_post_op_attr(p, res->fattr);
1938         res->mask = ntohl(*p++);
1939         if (res->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
1940                 return -EINVAL;
1941         base = (char *)p - (char *)req->rq_rcv_buf.head->iov_base;
1942
1943         acl = (res->mask & NFS_ACL) ? &res->acl_access : NULL;
1944         aclcnt = (res->mask & NFS_ACLCNT) ? &res->acl_access_count : NULL;
1945         err = nfsacl_decode(buf, base, aclcnt, acl);
1946
1947         acl = (res->mask & NFS_DFACL) ? &res->acl_default : NULL;
1948         aclcnt = (res->mask & NFS_DFACLCNT) ? &res->acl_default_count : NULL;
1949         if (err > 0)
1950                 err = nfsacl_decode(buf, base + err, aclcnt, acl);
1951         return (err > 0) ? 0 : err;
1952 }
1953
1954 /*
1955  * Decode setacl reply.
1956  */
1957 static int
1958 nfs3_xdr_setaclres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1959 {
1960         int status = ntohl(*p++);
1961
1962         if (status)
1963                 return nfs_stat_to_errno(status);
1964         xdr_decode_post_op_attr(p, fattr);
1965         return 0;
1966 }
1967 #endif  /* CONFIG_NFS_V3_ACL */
1968
1969 #define PROC(proc, argtype, restype, timer)                             \
1970 [NFS3PROC_##proc] = {                                                   \
1971         .p_proc      = NFS3PROC_##proc,                                 \
1972         .p_encode    = (kxdrproc_t) nfs3_xdr_##argtype,                 \
1973         .p_decode    = (kxdrproc_t) nfs3_xdr_##restype,                 \
1974         .p_arglen    = NFS3_##argtype##_sz,                             \
1975         .p_replen    = NFS3_##restype##_sz,                             \
1976         .p_timer     = timer,                                           \
1977         .p_statidx   = NFS3PROC_##proc,                                 \
1978         .p_name      = #proc,                                           \
1979         }
1980
1981 struct rpc_procinfo     nfs3_procedures[] = {
1982   PROC(GETATTR,         fhandle,        attrstat, 1),
1983   PROC(SETATTR,         sattrargs,      wccstat, 0),
1984   PROC(LOOKUP,          diropargs,      lookupres, 2),
1985   PROC(ACCESS,          accessargs,     accessres, 1),
1986   PROC(READLINK,        readlinkargs,   readlinkres, 3),
1987   PROC(READ,            readargs,       readres, 3),
1988   PROC(WRITE,           writeargs,      writeres, 4),
1989   PROC(CREATE,          createargs,     createres, 0),
1990   PROC(MKDIR,           mkdirargs,      createres, 0),
1991   PROC(SYMLINK,         symlinkargs,    createres, 0),
1992   PROC(MKNOD,           mknodargs,      createres, 0),
1993   PROC(REMOVE,          removeargs,     removeres, 0),
1994   PROC(RMDIR,           diropargs,      wccstat, 0),
1995   PROC(RENAME,          renameargs,     renameres, 0),
1996   PROC(LINK,            linkargs,       linkres, 0),
1997   PROC(READDIR,         readdirargs,    readdirres, 3),
1998   PROC(READDIRPLUS,     readdirargs,    readdirres, 3),
1999   PROC(FSSTAT,          fhandle,        fsstatres, 0),
2000   PROC(FSINFO,          fhandle,        fsinfores, 0),
2001   PROC(PATHCONF,        fhandle,        pathconfres, 0),
2002   PROC(COMMIT,          commitargs,     commitres, 5),
2003 };
2004
2005 struct rpc_version              nfs_version3 = {
2006         .number                 = 3,
2007         .nrprocs                = ARRAY_SIZE(nfs3_procedures),
2008         .procs                  = nfs3_procedures
2009 };
2010
2011 #ifdef CONFIG_NFS_V3_ACL
2012 static struct rpc_procinfo      nfs3_acl_procedures[] = {
2013         [ACLPROC3_GETACL] = {
2014                 .p_proc = ACLPROC3_GETACL,
2015                 .p_encode = (kxdrproc_t) nfs3_xdr_getaclargs,
2016                 .p_decode = (kxdrproc_t) nfs3_xdr_getaclres,
2017                 .p_arglen = ACL3_getaclargs_sz,
2018                 .p_replen = ACL3_getaclres_sz,
2019                 .p_timer = 1,
2020                 .p_name = "GETACL",
2021         },
2022         [ACLPROC3_SETACL] = {
2023                 .p_proc = ACLPROC3_SETACL,
2024                 .p_encode = (kxdrproc_t) nfs3_xdr_setaclargs,
2025                 .p_decode = (kxdrproc_t) nfs3_xdr_setaclres,
2026                 .p_arglen = ACL3_setaclargs_sz,
2027                 .p_replen = ACL3_setaclres_sz,
2028                 .p_timer = 0,
2029                 .p_name = "SETACL",
2030         },
2031 };
2032
2033 struct rpc_version              nfsacl_version3 = {
2034         .number                 = 3,
2035         .nrprocs                = sizeof(nfs3_acl_procedures)/
2036                                   sizeof(nfs3_acl_procedures[0]),
2037         .procs                  = nfs3_acl_procedures,
2038 };
2039 #endif  /* CONFIG_NFS_V3_ACL */