]> git.karo-electronics.de Git - mv-sheeva.git/blob - fs/nfs/nfs2xdr.c
NFS: Replace old NFSv2 decoder functions with xdr_stream-based ones
[mv-sheeva.git] / fs / nfs / nfs2xdr.c
1 /*
2  * linux/fs/nfs/nfs2xdr.c
3  *
4  * XDR functions to encode/decode NFS RPC arguments and results.
5  *
6  * Copyright (C) 1992, 1993, 1994  Rick Sladkey
7  * Copyright (C) 1996 Olaf Kirch
8  * 04 Aug 1998  Ion Badulescu <ionut@cs.columbia.edu>
9  *              FIFO's need special handling in NFSv2
10  */
11
12 #include <linux/param.h>
13 #include <linux/time.h>
14 #include <linux/mm.h>
15 #include <linux/errno.h>
16 #include <linux/string.h>
17 #include <linux/in.h>
18 #include <linux/pagemap.h>
19 #include <linux/proc_fs.h>
20 #include <linux/sunrpc/clnt.h>
21 #include <linux/nfs.h>
22 #include <linux/nfs2.h>
23 #include <linux/nfs_fs.h>
24 #include "internal.h"
25
26 #define NFSDBG_FACILITY         NFSDBG_XDR
27
28 /* Mapping from NFS error code to "errno" error code. */
29 #define errno_NFSERR_IO         EIO
30
31 /*
32  * Declare the space requirements for NFS arguments and replies as
33  * number of 32bit-words
34  */
35 #define NFS_fhandle_sz          (8)
36 #define NFS_sattr_sz            (8)
37 #define NFS_filename_sz         (1+(NFS2_MAXNAMLEN>>2))
38 #define NFS_path_sz             (1+(NFS2_MAXPATHLEN>>2))
39 #define NFS_fattr_sz            (17)
40 #define NFS_info_sz             (5)
41 #define NFS_entry_sz            (NFS_filename_sz+3)
42
43 #define NFS_diropargs_sz        (NFS_fhandle_sz+NFS_filename_sz)
44 #define NFS_removeargs_sz       (NFS_fhandle_sz+NFS_filename_sz)
45 #define NFS_sattrargs_sz        (NFS_fhandle_sz+NFS_sattr_sz)
46 #define NFS_readlinkargs_sz     (NFS_fhandle_sz)
47 #define NFS_readargs_sz         (NFS_fhandle_sz+3)
48 #define NFS_writeargs_sz        (NFS_fhandle_sz+4)
49 #define NFS_createargs_sz       (NFS_diropargs_sz+NFS_sattr_sz)
50 #define NFS_renameargs_sz       (NFS_diropargs_sz+NFS_diropargs_sz)
51 #define NFS_linkargs_sz         (NFS_fhandle_sz+NFS_diropargs_sz)
52 #define NFS_symlinkargs_sz      (NFS_diropargs_sz+1+NFS_sattr_sz)
53 #define NFS_readdirargs_sz      (NFS_fhandle_sz+2)
54
55 #define NFS_attrstat_sz         (1+NFS_fattr_sz)
56 #define NFS_diropres_sz         (1+NFS_fhandle_sz+NFS_fattr_sz)
57 #define NFS_readlinkres_sz      (2)
58 #define NFS_readres_sz          (1+NFS_fattr_sz+1)
59 #define NFS_writeres_sz         (NFS_attrstat_sz)
60 #define NFS_stat_sz             (1)
61 #define NFS_readdirres_sz       (1)
62 #define NFS_statfsres_sz        (1+NFS_info_sz)
63
64
65 /*
66  * While encoding arguments, set up the reply buffer in advance to
67  * receive reply data directly into the page cache.
68  */
69 static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
70                                  unsigned int base, unsigned int len,
71                                  unsigned int bufsize)
72 {
73         struct rpc_auth *auth = req->rq_cred->cr_auth;
74         unsigned int replen;
75
76         replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
77         xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
78 }
79
80 /*
81  * Handle decode buffer overflows out-of-line.
82  */
83 static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
84 {
85         dprintk("NFS: %s prematurely hit the end of our receive buffer. "
86                 "Remaining buffer length is %tu words.\n",
87                 func, xdr->end - xdr->p);
88 }
89
90
91 /*
92  * Common NFS XDR functions as inlines
93  */
94 static inline __be32*
95 xdr_decode_time(__be32 *p, struct timespec *timep)
96 {
97         timep->tv_sec = ntohl(*p++);
98         /* Convert microseconds into nanoseconds */
99         timep->tv_nsec = ntohl(*p++) * 1000;
100         return p;
101 }
102
103 static __be32 *
104 xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
105 {
106         u32 rdev, type;
107         type = ntohl(*p++);
108         fattr->mode = ntohl(*p++);
109         fattr->nlink = ntohl(*p++);
110         fattr->uid = ntohl(*p++);
111         fattr->gid = ntohl(*p++);
112         fattr->size = ntohl(*p++);
113         fattr->du.nfs2.blocksize = ntohl(*p++);
114         rdev = ntohl(*p++);
115         fattr->du.nfs2.blocks = ntohl(*p++);
116         fattr->fsid.major = ntohl(*p++);
117         fattr->fsid.minor = 0;
118         fattr->fileid = ntohl(*p++);
119         p = xdr_decode_time(p, &fattr->atime);
120         p = xdr_decode_time(p, &fattr->mtime);
121         p = xdr_decode_time(p, &fattr->ctime);
122         fattr->valid |= NFS_ATTR_FATTR_V2;
123         fattr->rdev = new_decode_dev(rdev);
124         if (type == NFCHR && rdev == NFS2_FIFO_DEV) {
125                 fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
126                 fattr->rdev = 0;
127         }
128         return p;
129 }
130
131 /*
132  * Encode/decode NFSv2 basic data types
133  *
134  * Basic NFSv2 data types are defined in section 2.3 of RFC 1094:
135  * "NFS: Network File System Protocol Specification".
136  *
137  * Not all basic data types have their own encoding and decoding
138  * functions.  For run-time efficiency, some data types are encoded
139  * or decoded inline.
140  */
141
142 /*
143  *      typedef opaque  nfsdata<>;
144  */
145 static int decode_nfsdata(struct xdr_stream *xdr, struct nfs_readres *result)
146 {
147         u32 recvd, count;
148         size_t hdrlen;
149         __be32 *p;
150
151         p = xdr_inline_decode(xdr, 4);
152         if (unlikely(p == NULL))
153                 goto out_overflow;
154         count = be32_to_cpup(p);
155         hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
156         recvd = xdr->buf->len - hdrlen;
157         if (unlikely(count > recvd))
158                 goto out_cheating;
159 out:
160         xdr_read_pages(xdr, count);
161         result->eof = 0;        /* NFSv2 does not pass EOF flag on the wire. */
162         result->count = count;
163         return count;
164 out_cheating:
165         dprintk("NFS: server cheating in read result: "
166                 "count %u > recvd %u\n", count, recvd);
167         count = recvd;
168         goto out;
169 out_overflow:
170         print_overflow_msg(__func__, xdr);
171         return -EIO;
172 }
173
174 /*
175  *      enum stat {
176  *              NFS_OK = 0,
177  *              NFSERR_PERM = 1,
178  *              NFSERR_NOENT = 2,
179  *              NFSERR_IO = 5,
180  *              NFSERR_NXIO = 6,
181  *              NFSERR_ACCES = 13,
182  *              NFSERR_EXIST = 17,
183  *              NFSERR_NODEV = 19,
184  *              NFSERR_NOTDIR = 20,
185  *              NFSERR_ISDIR = 21,
186  *              NFSERR_FBIG = 27,
187  *              NFSERR_NOSPC = 28,
188  *              NFSERR_ROFS = 30,
189  *              NFSERR_NAMETOOLONG = 63,
190  *              NFSERR_NOTEMPTY = 66,
191  *              NFSERR_DQUOT = 69,
192  *              NFSERR_STALE = 70,
193  *              NFSERR_WFLUSH = 99
194  *      };
195  */
196 static int decode_stat(struct xdr_stream *xdr, enum nfs_stat *status)
197 {
198         __be32 *p;
199
200         p = xdr_inline_decode(xdr, 4);
201         if (unlikely(p == NULL))
202                 goto out_overflow;
203         *status = be32_to_cpup(p);
204         return 0;
205 out_overflow:
206         print_overflow_msg(__func__, xdr);
207         return -EIO;
208 }
209
210 /*
211  * 2.3.3.  fhandle
212  *
213  *      typedef opaque fhandle[FHSIZE];
214  */
215 static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh)
216 {
217         __be32 *p;
218
219         BUG_ON(fh->size != NFS2_FHSIZE);
220         p = xdr_reserve_space(xdr, NFS2_FHSIZE);
221         memcpy(p, fh->data, NFS2_FHSIZE);
222 }
223
224 static int decode_fhandle(struct xdr_stream *xdr, struct nfs_fh *fh)
225 {
226         __be32 *p;
227
228         p = xdr_inline_decode(xdr, NFS2_FHSIZE);
229         if (unlikely(p == NULL))
230                 goto out_overflow;
231         fh->size = NFS2_FHSIZE;
232         memcpy(fh->data, p, NFS2_FHSIZE);
233         return 0;
234 out_overflow:
235         print_overflow_msg(__func__, xdr);
236         return -EIO;
237 }
238
239 /*
240  * 2.3.4.  timeval
241  *
242  *      struct timeval {
243  *              unsigned int seconds;
244  *              unsigned int useconds;
245  *      };
246  */
247 static __be32 *xdr_encode_time(__be32 *p, const struct timespec *timep)
248 {
249         *p++ = cpu_to_be32(timep->tv_sec);
250         if (timep->tv_nsec != 0)
251                 *p++ = cpu_to_be32(timep->tv_nsec / NSEC_PER_USEC);
252         else
253                 *p++ = cpu_to_be32(0);
254         return p;
255 }
256
257 /*
258  * Passing the invalid value useconds=1000000 is a Sun convention for
259  * "set to current server time".  It's needed to make permissions checks
260  * for the "touch" program across v2 mounts to Solaris and Irix servers
261  * work correctly.  See description of sattr in section 6.1 of "NFS
262  * Illustrated" by Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5.
263  */
264 static __be32 *xdr_encode_current_server_time(__be32 *p,
265                                               const struct timespec *timep)
266 {
267         *p++ = cpu_to_be32(timep->tv_sec);
268         *p++ = cpu_to_be32(1000000);
269         return p;
270 }
271
272 /*
273  * 2.3.5.  fattr
274  *
275  *      struct fattr {
276  *              ftype           type;
277  *              unsigned int    mode;
278  *              unsigned int    nlink;
279  *              unsigned int    uid;
280  *              unsigned int    gid;
281  *              unsigned int    size;
282  *              unsigned int    blocksize;
283  *              unsigned int    rdev;
284  *              unsigned int    blocks;
285  *              unsigned int    fsid;
286  *              unsigned int    fileid;
287  *              timeval         atime;
288  *              timeval         mtime;
289  *              timeval         ctime;
290  *      };
291  *
292  */
293 static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
294 {
295         __be32 *p;
296
297         p = xdr_inline_decode(xdr, NFS_fattr_sz << 2);
298         if (unlikely(p == NULL))
299                 goto out_overflow;
300         xdr_decode_fattr(p, fattr);
301         return 0;
302 out_overflow:
303         print_overflow_msg(__func__, xdr);
304         return -EIO;
305 }
306
307 /*
308  * 2.3.6.  sattr
309  *
310  *      struct sattr {
311  *              unsigned int    mode;
312  *              unsigned int    uid;
313  *              unsigned int    gid;
314  *              unsigned int    size;
315  *              timeval         atime;
316  *              timeval         mtime;
317  *      };
318  */
319
320 #define NFS2_SATTR_NOT_SET      (0xffffffff)
321
322 static __be32 *xdr_time_not_set(__be32 *p)
323 {
324         *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
325         *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
326         return p;
327 }
328
329 static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr)
330 {
331         __be32 *p;
332
333         p = xdr_reserve_space(xdr, NFS_sattr_sz << 2);
334
335         if (attr->ia_valid & ATTR_MODE)
336                 *p++ = cpu_to_be32(attr->ia_mode);
337         else
338                 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
339         if (attr->ia_valid & ATTR_UID)
340                 *p++ = cpu_to_be32(attr->ia_uid);
341         else
342                 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
343         if (attr->ia_valid & ATTR_GID)
344                 *p++ = cpu_to_be32(attr->ia_gid);
345         else
346                 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
347         if (attr->ia_valid & ATTR_SIZE)
348                 *p++ = cpu_to_be32((u32)attr->ia_size);
349         else
350                 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
351
352         if (attr->ia_valid & ATTR_ATIME_SET)
353                 p = xdr_encode_time(p, &attr->ia_atime);
354         else if (attr->ia_valid & ATTR_ATIME)
355                 p = xdr_encode_current_server_time(p, &attr->ia_atime);
356         else
357                 p = xdr_time_not_set(p);
358         if (attr->ia_valid & ATTR_MTIME_SET)
359                 xdr_encode_time(p, &attr->ia_mtime);
360         else if (attr->ia_valid & ATTR_MTIME)
361                 xdr_encode_current_server_time(p, &attr->ia_mtime);
362         else
363                 xdr_time_not_set(p);
364 }
365
366 /*
367  * 2.3.7.  filename
368  *
369  *      typedef string filename<MAXNAMLEN>;
370  */
371 static void encode_filename(struct xdr_stream *xdr,
372                             const char *name, u32 length)
373 {
374         __be32 *p;
375
376         BUG_ON(length > NFS2_MAXNAMLEN);
377         p = xdr_reserve_space(xdr, 4 + length);
378         xdr_encode_opaque(p, name, length);
379 }
380
381 static int decode_filename_inline(struct xdr_stream *xdr,
382                                   const char **name, u32 *length)
383 {
384         __be32 *p;
385         u32 count;
386
387         p = xdr_inline_decode(xdr, 4);
388         if (unlikely(p == NULL))
389                 goto out_overflow;
390         count = be32_to_cpup(p);
391         if (count > NFS3_MAXNAMLEN)
392                 goto out_nametoolong;
393         p = xdr_inline_decode(xdr, count);
394         if (unlikely(p == NULL))
395                 goto out_overflow;
396         *name = (const char *)p;
397         *length = count;
398         return 0;
399 out_nametoolong:
400         dprintk("NFS: returned filename too long: %u\n", count);
401         return -ENAMETOOLONG;
402 out_overflow:
403         print_overflow_msg(__func__, xdr);
404         return -EIO;
405 }
406
407 /*
408  * 2.3.8.  path
409  *
410  *      typedef string path<MAXPATHLEN>;
411  */
412 static void encode_path(struct xdr_stream *xdr, struct page **pages, u32 length)
413 {
414         __be32 *p;
415
416         BUG_ON(length > NFS2_MAXPATHLEN);
417         p = xdr_reserve_space(xdr, 4);
418         *p = cpu_to_be32(length);
419         xdr_write_pages(xdr, pages, 0, length);
420 }
421
422 static int decode_path(struct xdr_stream *xdr)
423 {
424         u32 length, recvd;
425         size_t hdrlen;
426         __be32 *p;
427
428         p = xdr_inline_decode(xdr, 4);
429         if (unlikely(p == NULL))
430                 goto out_overflow;
431         length = be32_to_cpup(p);
432         if (unlikely(length >= xdr->buf->page_len || length > NFS_MAXPATHLEN))
433                 goto out_size;
434         hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
435         recvd = xdr->buf->len - hdrlen;
436         if (unlikely(length > recvd))
437                 goto out_cheating;
438
439         xdr_read_pages(xdr, length);
440         xdr_terminate_string(xdr->buf, length);
441         return 0;
442 out_size:
443         dprintk("NFS: returned pathname too long: %u\n", length);
444         return -ENAMETOOLONG;
445 out_cheating:
446         dprintk("NFS: server cheating in pathname result: "
447                 "length %u > received %u\n", length, recvd);
448         return -EIO;
449 out_overflow:
450         print_overflow_msg(__func__, xdr);
451         return -EIO;
452 }
453
454 /*
455  * 2.3.9.  attrstat
456  *
457  *      union attrstat switch (stat status) {
458  *      case NFS_OK:
459  *              fattr attributes;
460  *      default:
461  *              void;
462  *      };
463  */
464 static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result)
465 {
466         enum nfs_stat status;
467         int error;
468
469         error = decode_stat(xdr, &status);
470         if (unlikely(error))
471                 goto out;
472         if (status != NFS_OK)
473                 goto out_default;
474         error = decode_fattr(xdr, result);
475 out:
476         return error;
477 out_default:
478         return nfs_stat_to_errno(status);
479 }
480
481 /*
482  * 2.3.10.  diropargs
483  *
484  *      struct diropargs {
485  *              fhandle  dir;
486  *              filename name;
487  *      };
488  */
489 static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh,
490                              const char *name, u32 length)
491 {
492         encode_fhandle(xdr, fh);
493         encode_filename(xdr, name, length);
494 }
495
496 /*
497  * 2.3.11.  diropres
498  *
499  *      union diropres switch (stat status) {
500  *      case NFS_OK:
501  *              struct {
502  *                      fhandle file;
503  *                      fattr   attributes;
504  *              } diropok;
505  *      default:
506  *              void;
507  *      };
508  */
509 static int decode_diropok(struct xdr_stream *xdr, struct nfs_diropok *result)
510 {
511         int error;
512
513         error = decode_fhandle(xdr, result->fh);
514         if (unlikely(error))
515                 goto out;
516         error = decode_fattr(xdr, result->fattr);
517 out:
518         return error;
519 }
520
521 static int decode_diropres(struct xdr_stream *xdr, struct nfs_diropok *result)
522 {
523         enum nfs_stat status;
524         int error;
525
526         error = decode_stat(xdr, &status);
527         if (unlikely(error))
528                 goto out;
529         if (status != NFS_OK)
530                 goto out_default;
531         error = decode_diropok(xdr, result);
532 out:
533         return error;
534 out_default:
535         return nfs_stat_to_errno(status);
536 }
537
538
539 /*
540  * NFSv2 XDR encode functions
541  *
542  * NFSv2 argument types are defined in section 2.2 of RFC 1094:
543  * "NFS: Network File System Protocol Specification".
544  */
545
546 static int nfs2_xdr_enc_fhandle(struct rpc_rqst *req, __be32 *p,
547                                 const struct nfs_fh *fh)
548 {
549         struct xdr_stream xdr;
550
551         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
552         encode_fhandle(&xdr, fh);
553         return 0;
554 }
555
556 /*
557  * 2.2.3.  sattrargs
558  *
559  *      struct sattrargs {
560  *              fhandle file;
561  *              sattr attributes;
562  *      };
563  */
564 static int nfs2_xdr_enc_sattrargs(struct rpc_rqst *req, __be32 *p,
565                                   const struct nfs_sattrargs *args)
566 {
567         struct xdr_stream xdr;
568
569         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
570         encode_fhandle(&xdr, args->fh);
571         encode_sattr(&xdr, args->sattr);
572         return 0;
573 }
574
575 static int nfs2_xdr_enc_diropargs(struct rpc_rqst *req, __be32 *p,
576                                   const struct nfs_diropargs *args)
577 {
578         struct xdr_stream xdr;
579
580         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
581         encode_diropargs(&xdr, args->fh, args->name, args->len);
582         return 0;
583 }
584
585 static int nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req, __be32 *p,
586                                      const struct nfs_readlinkargs *args)
587 {
588         struct xdr_stream xdr;
589
590         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
591         encode_fhandle(&xdr, args->fh);
592         prepare_reply_buffer(req, args->pages, args->pgbase,
593                                         args->pglen, NFS_readlinkres_sz);
594         return 0;
595 }
596
597 /*
598  * 2.2.7.  readargs
599  *
600  *      struct readargs {
601  *              fhandle file;
602  *              unsigned offset;
603  *              unsigned count;
604  *              unsigned totalcount;
605  *      };
606  */
607 static void encode_readargs(struct xdr_stream *xdr,
608                             const struct nfs_readargs *args)
609 {
610         u32 offset = args->offset;
611         u32 count = args->count;
612         __be32 *p;
613
614         encode_fhandle(xdr, args->fh);
615
616         p = xdr_reserve_space(xdr, 4 + 4 + 4);
617         *p++ = cpu_to_be32(offset);
618         *p++ = cpu_to_be32(count);
619         *p = cpu_to_be32(count);
620 }
621
622 static int nfs2_xdr_enc_readargs(struct rpc_rqst *req, __be32 *p,
623                                  const struct nfs_readargs *args)
624 {
625         struct xdr_stream xdr;
626
627         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
628         encode_readargs(&xdr, args);
629         prepare_reply_buffer(req, args->pages, args->pgbase,
630                                         args->count, NFS_readres_sz);
631         req->rq_rcv_buf.flags |= XDRBUF_READ;
632         return 0;
633 }
634
635 /*
636  * 2.2.9.  writeargs
637  *
638  *      struct writeargs {
639  *              fhandle file;
640  *              unsigned beginoffset;
641  *              unsigned offset;
642  *              unsigned totalcount;
643  *              nfsdata data;
644  *      };
645  */
646 static void encode_writeargs(struct xdr_stream *xdr,
647                              const struct nfs_writeargs *args)
648 {
649         u32 offset = args->offset;
650         u32 count = args->count;
651         __be32 *p;
652
653         encode_fhandle(xdr, args->fh);
654
655         p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4);
656         *p++ = cpu_to_be32(offset);
657         *p++ = cpu_to_be32(offset);
658         *p++ = cpu_to_be32(count);
659
660         /* nfsdata */
661         *p = cpu_to_be32(count);
662         xdr_write_pages(xdr, args->pages, args->pgbase, count);
663 }
664
665 static int nfs2_xdr_enc_writeargs(struct rpc_rqst *req, __be32 *p,
666                                   const struct nfs_writeargs *args)
667 {
668         struct xdr_stream xdr;
669
670         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
671         encode_writeargs(&xdr, args);
672         xdr.buf->flags |= XDRBUF_WRITE;
673         return 0;
674 }
675
676 /*
677  * 2.2.10.  createargs
678  *
679  *      struct createargs {
680  *              diropargs where;
681  *              sattr attributes;
682  *      };
683  */
684 static int nfs2_xdr_enc_createargs(struct rpc_rqst *req, __be32 *p,
685                                    const struct nfs_createargs *args)
686 {
687         struct xdr_stream xdr;
688
689         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
690         encode_diropargs(&xdr, args->fh, args->name, args->len);
691         encode_sattr(&xdr, args->sattr);
692         return 0;
693 }
694
695 static int nfs2_xdr_enc_removeargs(struct rpc_rqst *req, __be32 *p,
696                                    const struct nfs_removeargs *args)
697 {
698         struct xdr_stream xdr;
699
700         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
701         encode_diropargs(&xdr, args->fh, args->name.name, args->name.len);
702         return 0;
703 }
704
705 /*
706  * 2.2.12.  renameargs
707  *
708  *      struct renameargs {
709  *              diropargs from;
710  *              diropargs to;
711  *      };
712  */
713 static int nfs2_xdr_enc_renameargs(struct rpc_rqst *req, __be32 *p,
714                                    const struct nfs_renameargs *args)
715 {
716         const struct qstr *old = args->old_name;
717         const struct qstr *new = args->new_name;
718         struct xdr_stream xdr;
719
720         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
721         encode_diropargs(&xdr, args->old_dir, old->name, old->len);
722         encode_diropargs(&xdr, args->new_dir, new->name, new->len);
723         return 0;
724 }
725
726 /*
727  * 2.2.13.  linkargs
728  *
729  *      struct linkargs {
730  *              fhandle from;
731  *              diropargs to;
732  *      };
733  */
734 static int nfs2_xdr_enc_linkargs(struct rpc_rqst *req, __be32 *p,
735                                  const struct nfs_linkargs *args)
736 {
737         struct xdr_stream xdr;
738
739         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
740         encode_fhandle(&xdr, args->fromfh);
741         encode_diropargs(&xdr, args->tofh, args->toname, args->tolen);
742         return 0;
743 }
744
745 /*
746  * 2.2.14.  symlinkargs
747  *
748  *      struct symlinkargs {
749  *              diropargs from;
750  *              path to;
751  *              sattr attributes;
752  *      };
753  */
754 static int nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req, __be32 *p,
755                                     const struct nfs_symlinkargs *args)
756 {
757         struct xdr_stream xdr;
758
759         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
760         encode_diropargs(&xdr, args->fromfh, args->fromname, args->fromlen);
761         encode_path(&xdr, args->pages, args->pathlen);
762         encode_sattr(&xdr, args->sattr);
763         return 0;
764 }
765
766 /*
767  * 2.2.17.  readdirargs
768  *
769  *      struct readdirargs {
770  *              fhandle dir;
771  *              nfscookie cookie;
772  *              unsigned count;
773  *      };
774  */
775 static void encode_readdirargs(struct xdr_stream *xdr,
776                                const struct nfs_readdirargs *args)
777 {
778         __be32 *p;
779
780         encode_fhandle(xdr, args->fh);
781
782         p = xdr_reserve_space(xdr, 4 + 4);
783         *p++ = cpu_to_be32(args->cookie);
784         *p = cpu_to_be32(args->count);
785 }
786
787 static int nfs2_xdr_enc_readdirargs(struct rpc_rqst *req, __be32 *p,
788                                     const struct nfs_readdirargs *args)
789 {
790         struct xdr_stream xdr;
791
792         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
793         encode_readdirargs(&xdr, args);
794         prepare_reply_buffer(req, args->pages, 0,
795                                         args->count, NFS_readdirres_sz);
796         return 0;
797 }
798
799 /*
800  * NFSv2 XDR decode functions
801  *
802  * NFSv2 result types are defined in section 2.2 of RFC 1094:
803  * "NFS: Network File System Protocol Specification".
804  */
805
806 static int nfs2_xdr_dec_stat(struct rpc_rqst *req, __be32 *p,
807                              void *__unused)
808 {
809         struct xdr_stream xdr;
810         enum nfs_stat status;
811         int error;
812
813         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
814         error = decode_stat(&xdr, &status);
815         if (unlikely(error))
816                 goto out;
817         if (status != NFS_OK)
818                 goto out_default;
819 out:
820         return error;
821 out_default:
822         return nfs_stat_to_errno(status);
823 }
824
825 static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, __be32 *p,
826                                  struct nfs_fattr *result)
827 {
828         struct xdr_stream xdr;
829
830         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
831         return decode_attrstat(&xdr, result);
832 }
833
834 static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, __be32 *p,
835                                  struct nfs_diropok *result)
836 {
837         struct xdr_stream xdr;
838
839         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
840         return decode_diropres(&xdr, result);
841 }
842
843 /*
844  * 2.2.6.  readlinkres
845  *
846  *      union readlinkres switch (stat status) {
847  *      case NFS_OK:
848  *              path data;
849  *      default:
850  *              void;
851  *      };
852  */
853 static int nfs2_xdr_dec_readlinkres(struct rpc_rqst *req, __be32 *p,
854                                     void *__unused)
855 {
856         struct xdr_stream xdr;
857         enum nfs_stat status;
858         int error;
859
860         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
861         error = decode_stat(&xdr, &status);
862         if (unlikely(error))
863                 goto out;
864         if (status != NFS_OK)
865                 goto out_default;
866         error = decode_path(&xdr);
867 out:
868         return error;
869 out_default:
870         return nfs_stat_to_errno(status);
871 }
872
873 /*
874  * 2.2.7.  readres
875  *
876  *      union readres switch (stat status) {
877  *      case NFS_OK:
878  *              fattr attributes;
879  *              nfsdata data;
880  *      default:
881  *              void;
882  *      };
883  */
884 static int nfs2_xdr_dec_readres(struct rpc_rqst *req, __be32 *p,
885                                 struct nfs_readres *result)
886 {
887         struct xdr_stream xdr;
888         enum nfs_stat status;
889         int error;
890
891         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
892         error = decode_stat(&xdr, &status);
893         if (unlikely(error))
894                 goto out;
895         if (status != NFS_OK)
896                 goto out_default;
897         error = decode_fattr(&xdr, result->fattr);
898         if (unlikely(error))
899                 goto out;
900         error = decode_nfsdata(&xdr, result);
901 out:
902         return error;
903 out_default:
904         return nfs_stat_to_errno(status);
905 }
906
907 static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, __be32 *p,
908                                  struct nfs_writeres *result)
909 {
910         struct xdr_stream xdr;
911
912         /* All NFSv2 writes are "file sync" writes */
913         result->verf->committed = NFS_FILE_SYNC;
914
915         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
916         return decode_attrstat(&xdr, result->fattr);
917 }
918
919 /**
920  * nfs2_decode_dirent - Decode a single NFSv2 directory entry stored in
921  *                      the local page cache.
922  * @xdr: XDR stream where entry resides
923  * @entry: buffer to fill in with entry data
924  * @server: nfs_server data for this directory
925  * @plus: boolean indicating whether this should be a readdirplus entry
926  *
927  * Returns the position of the next item in the buffer, or an ERR_PTR.
928  *
929  * This function is not invoked during READDIR reply decoding, but
930  * rather whenever an application invokes the getdents(2) system call
931  * on a directory already in our cache.
932  *
933  * 2.2.17.  entry
934  *
935  *      struct entry {
936  *              unsigned        fileid;
937  *              filename        name;
938  *              nfscookie       cookie;
939  *              entry           *nextentry;
940  *      };
941  */
942 __be32 *nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
943                            struct nfs_server *server, int plus)
944 {
945         __be32 *p;
946         int error;
947
948         p = xdr_inline_decode(xdr, 4);
949         if (unlikely(p == NULL))
950                 goto out_overflow;
951         if (*p++ == xdr_zero) {
952                 p = xdr_inline_decode(xdr, 4);
953                 if (unlikely(p == NULL))
954                         goto out_overflow;
955                 if (*p++ == xdr_zero)
956                         return ERR_PTR(-EAGAIN);
957                 entry->eof = 1;
958                 return ERR_PTR(-EBADCOOKIE);
959         }
960
961         p = xdr_inline_decode(xdr, 4);
962         if (unlikely(p == NULL))
963                 goto out_overflow;
964         entry->ino = be32_to_cpup(p);
965
966         error = decode_filename_inline(xdr, &entry->name, &entry->len);
967         if (unlikely(error))
968                 return ERR_PTR(error);
969
970         /*
971          * The type (size and byte order) of nfscookie isn't defined in
972          * RFC 1094.  This implementation assumes that it's an XDR uint32.
973          */
974         entry->prev_cookie = entry->cookie;
975         p = xdr_inline_decode(xdr, 4);
976         if (unlikely(p == NULL))
977                 goto out_overflow;
978         entry->cookie = be32_to_cpup(p);
979
980         entry->d_type = DT_UNKNOWN;
981
982         /* Peek at the next entry to see if we're at EOD */
983         p = xdr_inline_peek(xdr, 4 + 4);
984         entry->eof = 0;
985         if (p != NULL)
986                 entry->eof = (p[0] == xdr_zero) && (p[1] != xdr_zero);
987         return p;
988
989 out_overflow:
990         print_overflow_msg(__func__, xdr);
991         return ERR_PTR(-EAGAIN);
992 }
993
994 /*
995  * 2.2.17.  readdirres
996  *
997  *      union readdirres switch (stat status) {
998  *      case NFS_OK:
999  *              struct {
1000  *                      entry *entries;
1001  *                      bool eof;
1002  *              } readdirok;
1003  *      default:
1004  *              void;
1005  *      };
1006  *
1007  * Read the directory contents into the page cache, but don't
1008  * touch them.  The actual decoding is done by nfs2_decode_dirent()
1009  * during subsequent nfs_readdir() calls.
1010  */
1011 static int decode_readdirok(struct xdr_stream *xdr)
1012 {
1013         u32 recvd, pglen;
1014         size_t hdrlen;
1015
1016         pglen = xdr->buf->page_len;
1017         hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
1018         recvd = xdr->buf->len - hdrlen;
1019         if (unlikely(pglen > recvd))
1020                 goto out_cheating;
1021 out:
1022         xdr_read_pages(xdr, pglen);
1023         return pglen;
1024 out_cheating:
1025         dprintk("NFS: server cheating in readdir result: "
1026                 "pglen %u > recvd %u\n", pglen, recvd);
1027         pglen = recvd;
1028         goto out;
1029 }
1030
1031 static int nfs2_xdr_dec_readdirres(struct rpc_rqst *req, __be32 *p,
1032                                    void *__unused)
1033 {
1034         struct xdr_stream xdr;
1035         enum nfs_stat status;
1036         int error;
1037
1038         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1039         error = decode_stat(&xdr, &status);
1040         if (unlikely(error))
1041                 goto out;
1042         if (status != NFS_OK)
1043                 goto out_default;
1044         error = decode_readdirok(&xdr);
1045 out:
1046         return error;
1047 out_default:
1048         return nfs_stat_to_errno(status);
1049 }
1050
1051 /*
1052  * 2.2.18.  statfsres
1053  *
1054  *      union statfsres (stat status) {
1055  *      case NFS_OK:
1056  *              struct {
1057  *                      unsigned tsize;
1058  *                      unsigned bsize;
1059  *                      unsigned blocks;
1060  *                      unsigned bfree;
1061  *                      unsigned bavail;
1062  *              } info;
1063  *      default:
1064  *              void;
1065  *      };
1066  */
1067 static int decode_info(struct xdr_stream *xdr, struct nfs2_fsstat *result)
1068 {
1069         __be32 *p;
1070
1071         p = xdr_inline_decode(xdr, NFS_info_sz << 2);
1072         if (unlikely(p == NULL))
1073                 goto out_overflow;
1074         result->tsize  = be32_to_cpup(p++);
1075         result->bsize  = be32_to_cpup(p++);
1076         result->blocks = be32_to_cpup(p++);
1077         result->bfree  = be32_to_cpup(p++);
1078         result->bavail = be32_to_cpup(p);
1079         return 0;
1080 out_overflow:
1081         print_overflow_msg(__func__, xdr);
1082         return -EIO;
1083 }
1084
1085 static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, __be32 *p,
1086                                   struct nfs2_fsstat *result)
1087 {
1088         struct xdr_stream xdr;
1089         enum nfs_stat status;
1090         int error;
1091
1092         xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1093         error = decode_stat(&xdr, &status);
1094         if (unlikely(error))
1095                 goto out;
1096         if (status != NFS_OK)
1097                 goto out_default;
1098         error = decode_info(&xdr, result);
1099 out:
1100         return error;
1101 out_default:
1102         return nfs_stat_to_errno(status);
1103 }
1104
1105
1106 /*
1107  * We need to translate between nfs status return values and
1108  * the local errno values which may not be the same.
1109  */
1110 static const struct {
1111         int stat;
1112         int errno;
1113 } nfs_errtbl[] = {
1114         { NFS_OK,               0               },
1115         { NFSERR_PERM,          -EPERM          },
1116         { NFSERR_NOENT,         -ENOENT         },
1117         { NFSERR_IO,            -errno_NFSERR_IO},
1118         { NFSERR_NXIO,          -ENXIO          },
1119 /*      { NFSERR_EAGAIN,        -EAGAIN         }, */
1120         { NFSERR_ACCES,         -EACCES         },
1121         { NFSERR_EXIST,         -EEXIST         },
1122         { NFSERR_XDEV,          -EXDEV          },
1123         { NFSERR_NODEV,         -ENODEV         },
1124         { NFSERR_NOTDIR,        -ENOTDIR        },
1125         { NFSERR_ISDIR,         -EISDIR         },
1126         { NFSERR_INVAL,         -EINVAL         },
1127         { NFSERR_FBIG,          -EFBIG          },
1128         { NFSERR_NOSPC,         -ENOSPC         },
1129         { NFSERR_ROFS,          -EROFS          },
1130         { NFSERR_MLINK,         -EMLINK         },
1131         { NFSERR_NAMETOOLONG,   -ENAMETOOLONG   },
1132         { NFSERR_NOTEMPTY,      -ENOTEMPTY      },
1133         { NFSERR_DQUOT,         -EDQUOT         },
1134         { NFSERR_STALE,         -ESTALE         },
1135         { NFSERR_REMOTE,        -EREMOTE        },
1136 #ifdef EWFLUSH
1137         { NFSERR_WFLUSH,        -EWFLUSH        },
1138 #endif
1139         { NFSERR_BADHANDLE,     -EBADHANDLE     },
1140         { NFSERR_NOT_SYNC,      -ENOTSYNC       },
1141         { NFSERR_BAD_COOKIE,    -EBADCOOKIE     },
1142         { NFSERR_NOTSUPP,       -ENOTSUPP       },
1143         { NFSERR_TOOSMALL,      -ETOOSMALL      },
1144         { NFSERR_SERVERFAULT,   -EREMOTEIO      },
1145         { NFSERR_BADTYPE,       -EBADTYPE       },
1146         { NFSERR_JUKEBOX,       -EJUKEBOX       },
1147         { -1,                   -EIO            }
1148 };
1149
1150 /**
1151  * nfs_stat_to_errno - convert an NFS status code to a local errno
1152  * @status: NFS status code to convert
1153  *
1154  * Returns a local errno value, or -EIO if the NFS status code is
1155  * not recognized.  This function is used jointly by NFSv2 and NFSv3.
1156  */
1157 int nfs_stat_to_errno(enum nfs_stat status)
1158 {
1159         int i;
1160
1161         for (i = 0; nfs_errtbl[i].stat != -1; i++) {
1162                 if (nfs_errtbl[i].stat == (int)status)
1163                         return nfs_errtbl[i].errno;
1164         }
1165         dprintk("NFS: Unrecognized nfs status value: %u\n", status);
1166         return nfs_errtbl[i].errno;
1167 }
1168
1169 #define PROC(proc, argtype, restype, timer)                             \
1170 [NFSPROC_##proc] = {                                                    \
1171         .p_proc     =  NFSPROC_##proc,                                  \
1172         .p_encode   =  (kxdrproc_t)nfs2_xdr_enc_##argtype,              \
1173         .p_decode   =  (kxdrproc_t)nfs2_xdr_dec_##restype,              \
1174         .p_arglen   =  NFS_##argtype##_sz,                              \
1175         .p_replen   =  NFS_##restype##_sz,                              \
1176         .p_timer    =  timer,                                           \
1177         .p_statidx  =  NFSPROC_##proc,                                  \
1178         .p_name     =  #proc,                                           \
1179         }
1180 struct rpc_procinfo     nfs_procedures[] = {
1181     PROC(GETATTR,       fhandle,        attrstat, 1),
1182     PROC(SETATTR,       sattrargs,      attrstat, 0),
1183     PROC(LOOKUP,        diropargs,      diropres, 2),
1184     PROC(READLINK,      readlinkargs,   readlinkres, 3),
1185     PROC(READ,          readargs,       readres, 3),
1186     PROC(WRITE,         writeargs,      writeres, 4),
1187     PROC(CREATE,        createargs,     diropres, 0),
1188     PROC(REMOVE,        removeargs,     stat, 0),
1189     PROC(RENAME,        renameargs,     stat, 0),
1190     PROC(LINK,          linkargs,       stat, 0),
1191     PROC(SYMLINK,       symlinkargs,    stat, 0),
1192     PROC(MKDIR,         createargs,     diropres, 0),
1193     PROC(RMDIR,         diropargs,      stat, 0),
1194     PROC(READDIR,       readdirargs,    readdirres, 3),
1195     PROC(STATFS,        fhandle,        statfsres, 0),
1196 };
1197
1198 struct rpc_version              nfs_version2 = {
1199         .number                 = 2,
1200         .nrprocs                = ARRAY_SIZE(nfs_procedures),
1201         .procs                  = nfs_procedures
1202 };