f5ea9dcf08d63f6f95bebff7e0cd96499a5748a1
[pandora-kernel.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 /*
82  * Common NFS XDR functions as inlines
83  */
84 static inline __be32 *
85 xdr_decode_fhandle(__be32 *p, struct nfs_fh *fhandle)
86 {
87         /* NFSv2 handles have a fixed length */
88         fhandle->size = NFS2_FHSIZE;
89         memcpy(fhandle->data, p, NFS2_FHSIZE);
90         return p + XDR_QUADLEN(NFS2_FHSIZE);
91 }
92
93 static inline __be32*
94 xdr_encode_time(__be32 *p, const struct timespec *timep)
95 {
96         *p++ = htonl(timep->tv_sec);
97         /* Convert nanoseconds into microseconds */
98         *p++ = htonl(timep->tv_nsec ? timep->tv_nsec / 1000 : 0);
99         return p;
100 }
101
102 static inline __be32*
103 xdr_encode_current_server_time(__be32 *p, const struct timespec *timep)
104 {
105         /*
106          * Passing the invalid value useconds=1000000 is a
107          * Sun convention for "set to current server time".
108          * It's needed to make permissions checks for the
109          * "touch" program across v2 mounts to Solaris and
110          * Irix boxes work correctly. See description of
111          * sattr in section 6.1 of "NFS Illustrated" by
112          * Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5
113          */
114         *p++ = htonl(timep->tv_sec);
115         *p++ = htonl(1000000);
116         return p;
117 }
118
119 static inline __be32*
120 xdr_decode_time(__be32 *p, struct timespec *timep)
121 {
122         timep->tv_sec = ntohl(*p++);
123         /* Convert microseconds into nanoseconds */
124         timep->tv_nsec = ntohl(*p++) * 1000;
125         return p;
126 }
127
128 static __be32 *
129 xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
130 {
131         u32 rdev, type;
132         type = ntohl(*p++);
133         fattr->mode = ntohl(*p++);
134         fattr->nlink = ntohl(*p++);
135         fattr->uid = ntohl(*p++);
136         fattr->gid = ntohl(*p++);
137         fattr->size = ntohl(*p++);
138         fattr->du.nfs2.blocksize = ntohl(*p++);
139         rdev = ntohl(*p++);
140         fattr->du.nfs2.blocks = ntohl(*p++);
141         fattr->fsid.major = ntohl(*p++);
142         fattr->fsid.minor = 0;
143         fattr->fileid = ntohl(*p++);
144         p = xdr_decode_time(p, &fattr->atime);
145         p = xdr_decode_time(p, &fattr->mtime);
146         p = xdr_decode_time(p, &fattr->ctime);
147         fattr->valid |= NFS_ATTR_FATTR_V2;
148         fattr->rdev = new_decode_dev(rdev);
149         if (type == NFCHR && rdev == NFS2_FIFO_DEV) {
150                 fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
151                 fattr->rdev = 0;
152         }
153         return p;
154 }
155
156 /*
157  * Encode/decode NFSv2 basic data types
158  *
159  * Basic NFSv2 data types are defined in section 2.3 of RFC 1094:
160  * "NFS: Network File System Protocol Specification".
161  *
162  * Not all basic data types have their own encoding and decoding
163  * functions.  For run-time efficiency, some data types are encoded
164  * or decoded inline.
165  */
166
167 /*
168  * 2.3.3.  fhandle
169  *
170  *      typedef opaque fhandle[FHSIZE];
171  */
172 static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh)
173 {
174         __be32 *p;
175
176         BUG_ON(fh->size != NFS2_FHSIZE);
177         p = xdr_reserve_space(xdr, NFS2_FHSIZE);
178         memcpy(p, fh->data, NFS2_FHSIZE);
179 }
180
181 /*
182  * 2.3.6.  sattr
183  *
184  *      struct sattr {
185  *              unsigned int    mode;
186  *              unsigned int    uid;
187  *              unsigned int    gid;
188  *              unsigned int    size;
189  *              timeval         atime;
190  *              timeval         mtime;
191  *      };
192  */
193
194 #define NFS2_SATTR_NOT_SET      (0xffffffff)
195
196 static __be32 *xdr_time_not_set(__be32 *p)
197 {
198         *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
199         *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
200         return p;
201 }
202
203 static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr)
204 {
205         __be32 *p;
206
207         p = xdr_reserve_space(xdr, NFS_sattr_sz << 2);
208
209         if (attr->ia_valid & ATTR_MODE)
210                 *p++ = cpu_to_be32(attr->ia_mode);
211         else
212                 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
213         if (attr->ia_valid & ATTR_UID)
214                 *p++ = cpu_to_be32(attr->ia_uid);
215         else
216                 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
217         if (attr->ia_valid & ATTR_GID)
218                 *p++ = cpu_to_be32(attr->ia_gid);
219         else
220                 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
221         if (attr->ia_valid & ATTR_SIZE)
222                 *p++ = cpu_to_be32((u32)attr->ia_size);
223         else
224                 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
225
226         if (attr->ia_valid & ATTR_ATIME_SET)
227                 p = xdr_encode_time(p, &attr->ia_atime);
228         else if (attr->ia_valid & ATTR_ATIME)
229                 p = xdr_encode_current_server_time(p, &attr->ia_atime);
230         else
231                 p = xdr_time_not_set(p);
232         if (attr->ia_valid & ATTR_MTIME_SET)
233                 xdr_encode_time(p, &attr->ia_mtime);
234         else if (attr->ia_valid & ATTR_MTIME)
235                 xdr_encode_current_server_time(p, &attr->ia_mtime);
236         else
237                 xdr_time_not_set(p);
238 }
239
240 /*
241  * 2.3.7.  filename
242  *
243  *      typedef string filename<MAXNAMLEN>;
244  */
245 static void encode_filename(struct xdr_stream *xdr,
246                             const char *name, u32 length)
247 {
248         __be32 *p;
249
250         BUG_ON(length > NFS2_MAXNAMLEN);
251         p = xdr_reserve_space(xdr, 4 + length);
252         xdr_encode_opaque(p, name, length);
253 }
254
255 /*
256  * 2.3.8.  path
257  *
258  *      typedef string path<MAXPATHLEN>;
259  */
260 static void encode_path(struct xdr_stream *xdr, struct page **pages, u32 length)
261 {
262         __be32 *p;
263
264         BUG_ON(length > NFS2_MAXPATHLEN);
265         p = xdr_reserve_space(xdr, 4);
266         *p = cpu_to_be32(length);
267         xdr_write_pages(xdr, pages, 0, length);
268 }
269
270 /*
271  * 2.3.10.  diropargs
272  *
273  *      struct diropargs {
274  *              fhandle  dir;
275  *              filename name;
276  *      };
277  */
278 static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh,
279                              const char *name, u32 length)
280 {
281         encode_fhandle(xdr, fh);
282         encode_filename(xdr, name, length);
283 }
284
285
286 /*
287  * NFSv2 XDR encode functions
288  *
289  * NFSv2 argument types are defined in section 2.2 of RFC 1094:
290  * "NFS: Network File System Protocol Specification".
291  */
292
293 static int nfs2_xdr_enc_fhandle(struct rpc_rqst *req, __be32 *p,
294                                 const struct nfs_fh *fh)
295 {
296         struct xdr_stream xdr;
297
298         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
299         encode_fhandle(&xdr, fh);
300         return 0;
301 }
302
303 /*
304  * 2.2.3.  sattrargs
305  *
306  *      struct sattrargs {
307  *              fhandle file;
308  *              sattr attributes;
309  *      };
310  */
311 static int nfs2_xdr_enc_sattrargs(struct rpc_rqst *req, __be32 *p,
312                                   const struct nfs_sattrargs *args)
313 {
314         struct xdr_stream xdr;
315
316         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
317         encode_fhandle(&xdr, args->fh);
318         encode_sattr(&xdr, args->sattr);
319         return 0;
320 }
321
322 static int nfs2_xdr_enc_diropargs(struct rpc_rqst *req, __be32 *p,
323                                   const struct nfs_diropargs *args)
324 {
325         struct xdr_stream xdr;
326
327         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
328         encode_diropargs(&xdr, args->fh, args->name, args->len);
329         return 0;
330 }
331
332 static int nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req, __be32 *p,
333                                      const struct nfs_readlinkargs *args)
334 {
335         struct xdr_stream xdr;
336
337         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
338         encode_fhandle(&xdr, args->fh);
339         prepare_reply_buffer(req, args->pages, args->pgbase,
340                                         args->pglen, NFS_readlinkres_sz);
341         return 0;
342 }
343
344 /*
345  * 2.2.7.  readargs
346  *
347  *      struct readargs {
348  *              fhandle file;
349  *              unsigned offset;
350  *              unsigned count;
351  *              unsigned totalcount;
352  *      };
353  */
354 static void encode_readargs(struct xdr_stream *xdr,
355                             const struct nfs_readargs *args)
356 {
357         u32 offset = args->offset;
358         u32 count = args->count;
359         __be32 *p;
360
361         encode_fhandle(xdr, args->fh);
362
363         p = xdr_reserve_space(xdr, 4 + 4 + 4);
364         *p++ = cpu_to_be32(offset);
365         *p++ = cpu_to_be32(count);
366         *p = cpu_to_be32(count);
367 }
368
369 static int nfs2_xdr_enc_readargs(struct rpc_rqst *req, __be32 *p,
370                                  const struct nfs_readargs *args)
371 {
372         struct xdr_stream xdr;
373
374         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
375         encode_readargs(&xdr, args);
376         prepare_reply_buffer(req, args->pages, args->pgbase,
377                                         args->count, NFS_readres_sz);
378         req->rq_rcv_buf.flags |= XDRBUF_READ;
379         return 0;
380 }
381
382 /*
383  * Decode READ reply
384  */
385 static int
386 nfs_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
387 {
388         struct kvec *iov = req->rq_rcv_buf.head;
389         size_t hdrlen;
390         u32 count, recvd;
391         int status;
392
393         if ((status = ntohl(*p++)))
394                 return nfs_stat_to_errno(status);
395         p = xdr_decode_fattr(p, res->fattr);
396
397         count = ntohl(*p++);
398         res->eof = 0;
399         hdrlen = (u8 *) p - (u8 *) iov->iov_base;
400         if (iov->iov_len < hdrlen) {
401                 dprintk("NFS: READ reply header overflowed:"
402                                 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
403                 return -errno_NFSERR_IO;
404         } else if (iov->iov_len != hdrlen) {
405                 dprintk("NFS: READ header is short. iovec will be shifted.\n");
406                 xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
407         }
408
409         recvd = req->rq_rcv_buf.len - hdrlen;
410         if (count > recvd) {
411                 dprintk("NFS: server cheating in read reply: "
412                         "count %u > recvd %u\n", count, recvd);
413                 count = recvd;
414         }
415
416         dprintk("RPC:      readres OK count %u\n", count);
417         if (count < res->count)
418                 res->count = count;
419
420         return count;
421 }
422
423
424 /*
425  * 2.2.9.  writeargs
426  *
427  *      struct writeargs {
428  *              fhandle file;
429  *              unsigned beginoffset;
430  *              unsigned offset;
431  *              unsigned totalcount;
432  *              nfsdata data;
433  *      };
434  */
435 static void encode_writeargs(struct xdr_stream *xdr,
436                              const struct nfs_writeargs *args)
437 {
438         u32 offset = args->offset;
439         u32 count = args->count;
440         __be32 *p;
441
442         encode_fhandle(xdr, args->fh);
443
444         p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4);
445         *p++ = cpu_to_be32(offset);
446         *p++ = cpu_to_be32(offset);
447         *p++ = cpu_to_be32(count);
448
449         /* nfsdata */
450         *p = cpu_to_be32(count);
451         xdr_write_pages(xdr, args->pages, args->pgbase, count);
452 }
453
454 static int nfs2_xdr_enc_writeargs(struct rpc_rqst *req, __be32 *p,
455                                   const struct nfs_writeargs *args)
456 {
457         struct xdr_stream xdr;
458
459         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
460         encode_writeargs(&xdr, args);
461         xdr.buf->flags |= XDRBUF_WRITE;
462         return 0;
463 }
464
465 /*
466  * 2.2.10.  createargs
467  *
468  *      struct createargs {
469  *              diropargs where;
470  *              sattr attributes;
471  *      };
472  */
473 static int nfs2_xdr_enc_createargs(struct rpc_rqst *req, __be32 *p,
474                                    const struct nfs_createargs *args)
475 {
476         struct xdr_stream xdr;
477
478         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
479         encode_diropargs(&xdr, args->fh, args->name, args->len);
480         encode_sattr(&xdr, args->sattr);
481         return 0;
482 }
483
484 static int nfs2_xdr_enc_removeargs(struct rpc_rqst *req, __be32 *p,
485                                    const struct nfs_removeargs *args)
486 {
487         struct xdr_stream xdr;
488
489         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
490         encode_diropargs(&xdr, args->fh, args->name.name, args->name.len);
491         return 0;
492 }
493
494 /*
495  * 2.2.12.  renameargs
496  *
497  *      struct renameargs {
498  *              diropargs from;
499  *              diropargs to;
500  *      };
501  */
502 static int nfs2_xdr_enc_renameargs(struct rpc_rqst *req, __be32 *p,
503                                    const struct nfs_renameargs *args)
504 {
505         const struct qstr *old = args->old_name;
506         const struct qstr *new = args->new_name;
507         struct xdr_stream xdr;
508
509         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
510         encode_diropargs(&xdr, args->old_dir, old->name, old->len);
511         encode_diropargs(&xdr, args->new_dir, new->name, new->len);
512         return 0;
513 }
514
515 /*
516  * 2.2.13.  linkargs
517  *
518  *      struct linkargs {
519  *              fhandle from;
520  *              diropargs to;
521  *      };
522  */
523 static int nfs2_xdr_enc_linkargs(struct rpc_rqst *req, __be32 *p,
524                                  const struct nfs_linkargs *args)
525 {
526         struct xdr_stream xdr;
527
528         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
529         encode_fhandle(&xdr, args->fromfh);
530         encode_diropargs(&xdr, args->tofh, args->toname, args->tolen);
531         return 0;
532 }
533
534 /*
535  * 2.2.14.  symlinkargs
536  *
537  *      struct symlinkargs {
538  *              diropargs from;
539  *              path to;
540  *              sattr attributes;
541  *      };
542  */
543 static int nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req, __be32 *p,
544                                     const struct nfs_symlinkargs *args)
545 {
546         struct xdr_stream xdr;
547
548         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
549         encode_diropargs(&xdr, args->fromfh, args->fromname, args->fromlen);
550         encode_path(&xdr, args->pages, args->pathlen);
551         encode_sattr(&xdr, args->sattr);
552         return 0;
553 }
554
555 /*
556  * 2.2.17.  readdirargs
557  *
558  *      struct readdirargs {
559  *              fhandle dir;
560  *              nfscookie cookie;
561  *              unsigned count;
562  *      };
563  */
564 static void encode_readdirargs(struct xdr_stream *xdr,
565                                const struct nfs_readdirargs *args)
566 {
567         __be32 *p;
568
569         encode_fhandle(xdr, args->fh);
570
571         p = xdr_reserve_space(xdr, 4 + 4);
572         *p++ = cpu_to_be32(args->cookie);
573         *p = cpu_to_be32(args->count);
574 }
575
576 static int nfs2_xdr_enc_readdirargs(struct rpc_rqst *req, __be32 *p,
577                                     const struct nfs_readdirargs *args)
578 {
579         struct xdr_stream xdr;
580
581         xdr_init_encode(&xdr, &req->rq_snd_buf, p);
582         encode_readdirargs(&xdr, args);
583         prepare_reply_buffer(req, args->pages, 0,
584                                         args->count, NFS_readdirres_sz);
585         return 0;
586 }
587
588 /*
589  * Decode the result of a readdir call.
590  * We're not really decoding anymore, we just leave the buffer untouched
591  * and only check that it is syntactically correct.
592  * The real decoding happens in nfs_decode_entry below, called directly
593  * from nfs_readdir for each entry.
594  */
595 static int
596 nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
597 {
598         struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
599         struct kvec *iov = rcvbuf->head;
600         struct page **page;
601         size_t hdrlen;
602         unsigned int pglen, recvd;
603         int status;
604
605         if ((status = ntohl(*p++)))
606                 return nfs_stat_to_errno(status);
607
608         hdrlen = (u8 *) p - (u8 *) iov->iov_base;
609         if (iov->iov_len < hdrlen) {
610                 dprintk("NFS: READDIR reply header overflowed:"
611                                 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
612                 return -errno_NFSERR_IO;
613         } else if (iov->iov_len != hdrlen) {
614                 dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
615                 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
616         }
617
618         pglen = rcvbuf->page_len;
619         recvd = rcvbuf->len - hdrlen;
620         if (pglen > recvd)
621                 pglen = recvd;
622         page = rcvbuf->pages;
623         return pglen;
624 }
625
626 static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
627 {
628         dprintk("nfs: %s: prematurely hit end of receive buffer. "
629                 "Remaining buffer length is %tu words.\n",
630                 func, xdr->end - xdr->p);
631 }
632
633 __be32 *
634 nfs_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_server *server, int plus)
635 {
636         __be32 *p;
637         p = xdr_inline_decode(xdr, 4);
638         if (unlikely(!p))
639                 goto out_overflow;
640         if (!ntohl(*p++)) {
641                 p = xdr_inline_decode(xdr, 4);
642                 if (unlikely(!p))
643                         goto out_overflow;
644                 if (!ntohl(*p++))
645                         return ERR_PTR(-EAGAIN);
646                 entry->eof = 1;
647                 return ERR_PTR(-EBADCOOKIE);
648         }
649
650         p = xdr_inline_decode(xdr, 8);
651         if (unlikely(!p))
652                 goto out_overflow;
653
654         entry->ino        = ntohl(*p++);
655         entry->len        = ntohl(*p++);
656
657         p = xdr_inline_decode(xdr, entry->len + 4);
658         if (unlikely(!p))
659                 goto out_overflow;
660         entry->name       = (const char *) p;
661         p                += XDR_QUADLEN(entry->len);
662         entry->prev_cookie        = entry->cookie;
663         entry->cookie     = ntohl(*p++);
664
665         entry->d_type = DT_UNKNOWN;
666
667         p = xdr_inline_peek(xdr, 8);
668         if (p != NULL)
669                 entry->eof = !p[0] && p[1];
670         else
671                 entry->eof = 0;
672
673         return p;
674
675 out_overflow:
676         print_overflow_msg(__func__, xdr);
677         return ERR_PTR(-EAGAIN);
678 }
679
680 /*
681  * NFS XDR decode functions
682  */
683 /*
684  * Decode simple status reply
685  */
686 static int
687 nfs_xdr_stat(struct rpc_rqst *req, __be32 *p, void *dummy)
688 {
689         int     status;
690
691         if ((status = ntohl(*p++)) != 0)
692                 status = nfs_stat_to_errno(status);
693         return status;
694 }
695
696 /*
697  * Decode attrstat reply
698  * GETATTR, SETATTR, WRITE
699  */
700 static int
701 nfs_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
702 {
703         int     status;
704
705         if ((status = ntohl(*p++)))
706                 return nfs_stat_to_errno(status);
707         xdr_decode_fattr(p, fattr);
708         return 0;
709 }
710
711 /*
712  * Decode diropres reply
713  * LOOKUP, CREATE, MKDIR
714  */
715 static int
716 nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res)
717 {
718         int     status;
719
720         if ((status = ntohl(*p++)))
721                 return nfs_stat_to_errno(status);
722         p = xdr_decode_fhandle(p, res->fh);
723         xdr_decode_fattr(p, res->fattr);
724         return 0;
725 }
726
727 /*
728  * Decode READLINK reply
729  */
730 static int
731 nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy)
732 {
733         struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
734         struct kvec *iov = rcvbuf->head;
735         size_t hdrlen;
736         u32 len, recvd;
737         int     status;
738
739         if ((status = ntohl(*p++)))
740                 return nfs_stat_to_errno(status);
741         /* Convert length of symlink */
742         len = ntohl(*p++);
743         if (len >= rcvbuf->page_len) {
744                 dprintk("nfs: server returned giant symlink!\n");
745                 return -ENAMETOOLONG;
746         }
747         hdrlen = (u8 *) p - (u8 *) iov->iov_base;
748         if (iov->iov_len < hdrlen) {
749                 dprintk("NFS: READLINK reply header overflowed:"
750                                 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
751                 return -errno_NFSERR_IO;
752         } else if (iov->iov_len != hdrlen) {
753                 dprintk("NFS: READLINK header is short. iovec will be shifted.\n");
754                 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
755         }
756         recvd = req->rq_rcv_buf.len - hdrlen;
757         if (recvd < len) {
758                 dprintk("NFS: server cheating in readlink reply: "
759                                 "count %u > recvd %u\n", len, recvd);
760                 return -EIO;
761         }
762
763         xdr_terminate_string(rcvbuf, len);
764         return 0;
765 }
766
767 /*
768  * Decode WRITE reply
769  */
770 static int
771 nfs_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
772 {
773         res->verf->committed = NFS_FILE_SYNC;
774         return nfs_xdr_attrstat(req, p, res->fattr);
775 }
776
777 /*
778  * Decode STATFS reply
779  */
780 static int
781 nfs_xdr_statfsres(struct rpc_rqst *req, __be32 *p, struct nfs2_fsstat *res)
782 {
783         int     status;
784
785         if ((status = ntohl(*p++)))
786                 return nfs_stat_to_errno(status);
787
788         res->tsize  = ntohl(*p++);
789         res->bsize  = ntohl(*p++);
790         res->blocks = ntohl(*p++);
791         res->bfree  = ntohl(*p++);
792         res->bavail = ntohl(*p++);
793         return 0;
794 }
795
796 /*
797  * We need to translate between nfs status return values and
798  * the local errno values which may not be the same.
799  */
800 static struct {
801         int stat;
802         int errno;
803 } nfs_errtbl[] = {
804         { NFS_OK,               0               },
805         { NFSERR_PERM,          -EPERM          },
806         { NFSERR_NOENT,         -ENOENT         },
807         { NFSERR_IO,            -errno_NFSERR_IO},
808         { NFSERR_NXIO,          -ENXIO          },
809 /*      { NFSERR_EAGAIN,        -EAGAIN         }, */
810         { NFSERR_ACCES,         -EACCES         },
811         { NFSERR_EXIST,         -EEXIST         },
812         { NFSERR_XDEV,          -EXDEV          },
813         { NFSERR_NODEV,         -ENODEV         },
814         { NFSERR_NOTDIR,        -ENOTDIR        },
815         { NFSERR_ISDIR,         -EISDIR         },
816         { NFSERR_INVAL,         -EINVAL         },
817         { NFSERR_FBIG,          -EFBIG          },
818         { NFSERR_NOSPC,         -ENOSPC         },
819         { NFSERR_ROFS,          -EROFS          },
820         { NFSERR_MLINK,         -EMLINK         },
821         { NFSERR_NAMETOOLONG,   -ENAMETOOLONG   },
822         { NFSERR_NOTEMPTY,      -ENOTEMPTY      },
823         { NFSERR_DQUOT,         -EDQUOT         },
824         { NFSERR_STALE,         -ESTALE         },
825         { NFSERR_REMOTE,        -EREMOTE        },
826 #ifdef EWFLUSH
827         { NFSERR_WFLUSH,        -EWFLUSH        },
828 #endif
829         { NFSERR_BADHANDLE,     -EBADHANDLE     },
830         { NFSERR_NOT_SYNC,      -ENOTSYNC       },
831         { NFSERR_BAD_COOKIE,    -EBADCOOKIE     },
832         { NFSERR_NOTSUPP,       -ENOTSUPP       },
833         { NFSERR_TOOSMALL,      -ETOOSMALL      },
834         { NFSERR_SERVERFAULT,   -EREMOTEIO      },
835         { NFSERR_BADTYPE,       -EBADTYPE       },
836         { NFSERR_JUKEBOX,       -EJUKEBOX       },
837         { -1,                   -EIO            }
838 };
839
840 /*
841  * Convert an NFS error code to a local one.
842  * This one is used jointly by NFSv2 and NFSv3.
843  */
844 int
845 nfs_stat_to_errno(int stat)
846 {
847         int i;
848
849         for (i = 0; nfs_errtbl[i].stat != -1; i++) {
850                 if (nfs_errtbl[i].stat == stat)
851                         return nfs_errtbl[i].errno;
852         }
853         dprintk("nfs_stat_to_errno: bad nfs status return value: %d\n", stat);
854         return nfs_errtbl[i].errno;
855 }
856
857 #define PROC(proc, argtype, restype, timer)                             \
858 [NFSPROC_##proc] = {                                                    \
859         .p_proc     =  NFSPROC_##proc,                                  \
860         .p_encode   =  (kxdrproc_t)nfs2_xdr_enc_##argtype,              \
861         .p_decode   =  (kxdrproc_t) nfs_xdr_##restype,                  \
862         .p_arglen   =  NFS_##argtype##_sz,                              \
863         .p_replen   =  NFS_##restype##_sz,                              \
864         .p_timer    =  timer,                                           \
865         .p_statidx  =  NFSPROC_##proc,                                  \
866         .p_name     =  #proc,                                           \
867         }
868 struct rpc_procinfo     nfs_procedures[] = {
869     PROC(GETATTR,       fhandle,        attrstat, 1),
870     PROC(SETATTR,       sattrargs,      attrstat, 0),
871     PROC(LOOKUP,        diropargs,      diropres, 2),
872     PROC(READLINK,      readlinkargs,   readlinkres, 3),
873     PROC(READ,          readargs,       readres, 3),
874     PROC(WRITE,         writeargs,      writeres, 4),
875     PROC(CREATE,        createargs,     diropres, 0),
876     PROC(REMOVE,        removeargs,     stat, 0),
877     PROC(RENAME,        renameargs,     stat, 0),
878     PROC(LINK,          linkargs,       stat, 0),
879     PROC(SYMLINK,       symlinkargs,    stat, 0),
880     PROC(MKDIR,         createargs,     diropres, 0),
881     PROC(RMDIR,         diropargs,      stat, 0),
882     PROC(READDIR,       readdirargs,    readdirres, 3),
883     PROC(STATFS,        fhandle,        statfsres, 0),
884 };
885
886 struct rpc_version              nfs_version2 = {
887         .number                 = 2,
888         .nrprocs                = ARRAY_SIZE(nfs_procedures),
889         .procs                  = nfs_procedures
890 };