Merge commit 'v2.6.30-rc5' into next
[linux-2.6] / 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/slab.h>
13 #include <linux/utsname.h>
14 #include <linux/errno.h>
15 #include <linux/string.h>
16 #include <linux/in.h>
17 #include <linux/pagemap.h>
18 #include <linux/proc_fs.h>
19 #include <linux/kdev_t.h>
20 #include <linux/sunrpc/clnt.h>
21 #include <linux/nfs.h>
22 #include <linux/nfs3.h>
23 #include <linux/nfs_fs.h>
24 #include <linux/nfsacl.h>
25 #include "internal.h"
26
27 #define NFSDBG_FACILITY         NFSDBG_XDR
28
29 /* Mapping from NFS error code to "errno" error code. */
30 #define errno_NFSERR_IO         EIO
31
32 /*
33  * Declare the space requirements for NFS arguments and replies as
34  * number of 32bit-words
35  */
36 #define NFS3_fhandle_sz         (1+16)
37 #define NFS3_fh_sz              (NFS3_fhandle_sz)       /* shorthand */
38 #define NFS3_sattr_sz           (15)
39 #define NFS3_filename_sz        (1+(NFS3_MAXNAMLEN>>2))
40 #define NFS3_path_sz            (1+(NFS3_MAXPATHLEN>>2))
41 #define NFS3_fattr_sz           (21)
42 #define NFS3_wcc_attr_sz                (6)
43 #define NFS3_pre_op_attr_sz     (1+NFS3_wcc_attr_sz)
44 #define NFS3_post_op_attr_sz    (1+NFS3_fattr_sz)
45 #define NFS3_wcc_data_sz                (NFS3_pre_op_attr_sz+NFS3_post_op_attr_sz)
46 #define NFS3_fsstat_sz          
47 #define NFS3_fsinfo_sz          
48 #define NFS3_pathconf_sz                
49 #define NFS3_entry_sz           (NFS3_filename_sz+3)
50
51 #define NFS3_sattrargs_sz       (NFS3_fh_sz+NFS3_sattr_sz+3)
52 #define NFS3_diropargs_sz       (NFS3_fh_sz+NFS3_filename_sz)
53 #define NFS3_removeargs_sz      (NFS3_fh_sz+NFS3_filename_sz)
54 #define NFS3_accessargs_sz      (NFS3_fh_sz+1)
55 #define NFS3_readlinkargs_sz    (NFS3_fh_sz)
56 #define NFS3_readargs_sz        (NFS3_fh_sz+3)
57 #define NFS3_writeargs_sz       (NFS3_fh_sz+5)
58 #define NFS3_createargs_sz      (NFS3_diropargs_sz+NFS3_sattr_sz)
59 #define NFS3_mkdirargs_sz       (NFS3_diropargs_sz+NFS3_sattr_sz)
60 #define NFS3_symlinkargs_sz     (NFS3_diropargs_sz+1+NFS3_sattr_sz)
61 #define NFS3_mknodargs_sz       (NFS3_diropargs_sz+2+NFS3_sattr_sz)
62 #define NFS3_renameargs_sz      (NFS3_diropargs_sz+NFS3_diropargs_sz)
63 #define NFS3_linkargs_sz                (NFS3_fh_sz+NFS3_diropargs_sz)
64 #define NFS3_readdirargs_sz     (NFS3_fh_sz+2)
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 /*
106  * Common NFS XDR functions as inlines
107  */
108 static inline __be32 *
109 xdr_encode_fhandle(__be32 *p, const struct nfs_fh *fh)
110 {
111         return xdr_encode_array(p, fh->data, fh->size);
112 }
113
114 static inline __be32 *
115 xdr_decode_fhandle(__be32 *p, struct nfs_fh *fh)
116 {
117         if ((fh->size = ntohl(*p++)) <= NFS3_FHSIZE) {
118                 memcpy(fh->data, p, fh->size);
119                 return p + XDR_QUADLEN(fh->size);
120         }
121         return NULL;
122 }
123
124 /*
125  * Encode/decode time.
126  */
127 static inline __be32 *
128 xdr_encode_time3(__be32 *p, struct timespec *timep)
129 {
130         *p++ = htonl(timep->tv_sec);
131         *p++ = htonl(timep->tv_nsec);
132         return p;
133 }
134
135 static inline __be32 *
136 xdr_decode_time3(__be32 *p, struct timespec *timep)
137 {
138         timep->tv_sec = ntohl(*p++);
139         timep->tv_nsec = ntohl(*p++);
140         return p;
141 }
142
143 static __be32 *
144 xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
145 {
146         unsigned int    type, major, minor;
147         umode_t         fmode;
148
149         type = ntohl(*p++);
150         if (type > NF3FIFO)
151                 type = NF3NON;
152         fmode = nfs_type2fmt[type];
153         fattr->mode = (ntohl(*p++) & ~S_IFMT) | fmode;
154         fattr->nlink = ntohl(*p++);
155         fattr->uid = ntohl(*p++);
156         fattr->gid = ntohl(*p++);
157         p = xdr_decode_hyper(p, &fattr->size);
158         p = xdr_decode_hyper(p, &fattr->du.nfs3.used);
159
160         /* Turn remote device info into Linux-specific dev_t */
161         major = ntohl(*p++);
162         minor = ntohl(*p++);
163         fattr->rdev = MKDEV(major, minor);
164         if (MAJOR(fattr->rdev) != major || MINOR(fattr->rdev) != minor)
165                 fattr->rdev = 0;
166
167         p = xdr_decode_hyper(p, &fattr->fsid.major);
168         fattr->fsid.minor = 0;
169         p = xdr_decode_hyper(p, &fattr->fileid);
170         p = xdr_decode_time3(p, &fattr->atime);
171         p = xdr_decode_time3(p, &fattr->mtime);
172         p = xdr_decode_time3(p, &fattr->ctime);
173
174         /* Update the mode bits */
175         fattr->valid |= NFS_ATTR_FATTR_V3;
176         return p;
177 }
178
179 static inline __be32 *
180 xdr_encode_sattr(__be32 *p, struct iattr *attr)
181 {
182         if (attr->ia_valid & ATTR_MODE) {
183                 *p++ = xdr_one;
184                 *p++ = htonl(attr->ia_mode & S_IALLUGO);
185         } else {
186                 *p++ = xdr_zero;
187         }
188         if (attr->ia_valid & ATTR_UID) {
189                 *p++ = xdr_one;
190                 *p++ = htonl(attr->ia_uid);
191         } else {
192                 *p++ = xdr_zero;
193         }
194         if (attr->ia_valid & ATTR_GID) {
195                 *p++ = xdr_one;
196                 *p++ = htonl(attr->ia_gid);
197         } else {
198                 *p++ = xdr_zero;
199         }
200         if (attr->ia_valid & ATTR_SIZE) {
201                 *p++ = xdr_one;
202                 p = xdr_encode_hyper(p, (__u64) attr->ia_size);
203         } else {
204                 *p++ = xdr_zero;
205         }
206         if (attr->ia_valid & ATTR_ATIME_SET) {
207                 *p++ = xdr_two;
208                 p = xdr_encode_time3(p, &attr->ia_atime);
209         } else if (attr->ia_valid & ATTR_ATIME) {
210                 *p++ = xdr_one;
211         } else {
212                 *p++ = xdr_zero;
213         }
214         if (attr->ia_valid & ATTR_MTIME_SET) {
215                 *p++ = xdr_two;
216                 p = xdr_encode_time3(p, &attr->ia_mtime);
217         } else if (attr->ia_valid & ATTR_MTIME) {
218                 *p++ = xdr_one;
219         } else {
220                 *p++ = xdr_zero;
221         }
222         return p;
223 }
224
225 static inline __be32 *
226 xdr_decode_wcc_attr(__be32 *p, struct nfs_fattr *fattr)
227 {
228         p = xdr_decode_hyper(p, &fattr->pre_size);
229         p = xdr_decode_time3(p, &fattr->pre_mtime);
230         p = xdr_decode_time3(p, &fattr->pre_ctime);
231         fattr->valid |= NFS_ATTR_FATTR_PRESIZE
232                 | NFS_ATTR_FATTR_PREMTIME
233                 | NFS_ATTR_FATTR_PRECTIME;
234         return p;
235 }
236
237 static inline __be32 *
238 xdr_decode_post_op_attr(__be32 *p, struct nfs_fattr *fattr)
239 {
240         if (*p++)
241                 p = xdr_decode_fattr(p, fattr);
242         return p;
243 }
244
245 static inline __be32 *
246 xdr_decode_pre_op_attr(__be32 *p, struct nfs_fattr *fattr)
247 {
248         if (*p++)
249                 return xdr_decode_wcc_attr(p, fattr);
250         return p;
251 }
252
253
254 static inline __be32 *
255 xdr_decode_wcc_data(__be32 *p, struct nfs_fattr *fattr)
256 {
257         p = xdr_decode_pre_op_attr(p, fattr);
258         return xdr_decode_post_op_attr(p, fattr);
259 }
260
261 /*
262  * NFS encode functions
263  */
264
265 /*
266  * Encode file handle argument
267  */
268 static int
269 nfs3_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh)
270 {
271         p = xdr_encode_fhandle(p, fh);
272         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
273         return 0;
274 }
275
276 /*
277  * Encode SETATTR arguments
278  */
279 static int
280 nfs3_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs3_sattrargs *args)
281 {
282         p = xdr_encode_fhandle(p, args->fh);
283         p = xdr_encode_sattr(p, args->sattr);
284         *p++ = htonl(args->guard);
285         if (args->guard)
286                 p = xdr_encode_time3(p, &args->guardtime);
287         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
288         return 0;
289 }
290
291 /*
292  * Encode directory ops argument
293  */
294 static int
295 nfs3_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs3_diropargs *args)
296 {
297         p = xdr_encode_fhandle(p, args->fh);
298         p = xdr_encode_array(p, args->name, args->len);
299         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
300         return 0;
301 }
302
303 /*
304  * Encode REMOVE argument
305  */
306 static int
307 nfs3_xdr_removeargs(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args)
308 {
309         p = xdr_encode_fhandle(p, args->fh);
310         p = xdr_encode_array(p, args->name.name, args->name.len);
311         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
312         return 0;
313 }
314
315 /*
316  * Encode access() argument
317  */
318 static int
319 nfs3_xdr_accessargs(struct rpc_rqst *req, __be32 *p, struct nfs3_accessargs *args)
320 {
321         p = xdr_encode_fhandle(p, args->fh);
322         *p++ = htonl(args->access);
323         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
324         return 0;
325 }
326
327 /*
328  * Arguments to a READ call. Since we read data directly into the page
329  * cache, we also set up the reply iovec here so that iov[1] points
330  * exactly to the page we want to fetch.
331  */
332 static int
333 nfs3_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
334 {
335         struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
336         unsigned int replen;
337         u32 count = args->count;
338
339         p = xdr_encode_fhandle(p, args->fh);
340         p = xdr_encode_hyper(p, args->offset);
341         *p++ = htonl(count);
342         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
343
344         /* Inline the page array */
345         replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readres_sz) << 2;
346         xdr_inline_pages(&req->rq_rcv_buf, replen,
347                          args->pages, args->pgbase, count);
348         req->rq_rcv_buf.flags |= XDRBUF_READ;
349         return 0;
350 }
351
352 /*
353  * Write arguments. Splice the buffer to be written into the iovec.
354  */
355 static int
356 nfs3_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
357 {
358         struct xdr_buf *sndbuf = &req->rq_snd_buf;
359         u32 count = args->count;
360
361         p = xdr_encode_fhandle(p, args->fh);
362         p = xdr_encode_hyper(p, args->offset);
363         *p++ = htonl(count);
364         *p++ = htonl(args->stable);
365         *p++ = htonl(count);
366         sndbuf->len = xdr_adjust_iovec(sndbuf->head, p);
367
368         /* Copy the page array */
369         xdr_encode_pages(sndbuf, args->pages, args->pgbase, count);
370         sndbuf->flags |= XDRBUF_WRITE;
371         return 0;
372 }
373
374 /*
375  * Encode CREATE arguments
376  */
377 static int
378 nfs3_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs3_createargs *args)
379 {
380         p = xdr_encode_fhandle(p, args->fh);
381         p = xdr_encode_array(p, args->name, args->len);
382
383         *p++ = htonl(args->createmode);
384         if (args->createmode == NFS3_CREATE_EXCLUSIVE) {
385                 *p++ = args->verifier[0];
386                 *p++ = args->verifier[1];
387         } else
388                 p = xdr_encode_sattr(p, args->sattr);
389
390         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
391         return 0;
392 }
393
394 /*
395  * Encode MKDIR arguments
396  */
397 static int
398 nfs3_xdr_mkdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mkdirargs *args)
399 {
400         p = xdr_encode_fhandle(p, args->fh);
401         p = xdr_encode_array(p, args->name, args->len);
402         p = xdr_encode_sattr(p, args->sattr);
403         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
404         return 0;
405 }
406
407 /*
408  * Encode SYMLINK arguments
409  */
410 static int
411 nfs3_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_symlinkargs *args)
412 {
413         p = xdr_encode_fhandle(p, args->fromfh);
414         p = xdr_encode_array(p, args->fromname, args->fromlen);
415         p = xdr_encode_sattr(p, args->sattr);
416         *p++ = htonl(args->pathlen);
417         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
418
419         /* Copy the page */
420         xdr_encode_pages(&req->rq_snd_buf, args->pages, 0, args->pathlen);
421         return 0;
422 }
423
424 /*
425  * Encode MKNOD arguments
426  */
427 static int
428 nfs3_xdr_mknodargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mknodargs *args)
429 {
430         p = xdr_encode_fhandle(p, args->fh);
431         p = xdr_encode_array(p, args->name, args->len);
432         *p++ = htonl(args->type);
433         p = xdr_encode_sattr(p, args->sattr);
434         if (args->type == NF3CHR || args->type == NF3BLK) {
435                 *p++ = htonl(MAJOR(args->rdev));
436                 *p++ = htonl(MINOR(args->rdev));
437         }
438
439         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
440         return 0;
441 }
442
443 /*
444  * Encode RENAME arguments
445  */
446 static int
447 nfs3_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs3_renameargs *args)
448 {
449         p = xdr_encode_fhandle(p, args->fromfh);
450         p = xdr_encode_array(p, args->fromname, args->fromlen);
451         p = xdr_encode_fhandle(p, args->tofh);
452         p = xdr_encode_array(p, args->toname, args->tolen);
453         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
454         return 0;
455 }
456
457 /*
458  * Encode LINK arguments
459  */
460 static int
461 nfs3_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_linkargs *args)
462 {
463         p = xdr_encode_fhandle(p, args->fromfh);
464         p = xdr_encode_fhandle(p, args->tofh);
465         p = xdr_encode_array(p, args->toname, args->tolen);
466         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
467         return 0;
468 }
469
470 /*
471  * Encode arguments to readdir call
472  */
473 static int
474 nfs3_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirargs *args)
475 {
476         struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
477         unsigned int replen;
478         u32 count = args->count;
479
480         p = xdr_encode_fhandle(p, args->fh);
481         p = xdr_encode_hyper(p, args->cookie);
482         *p++ = args->verf[0];
483         *p++ = args->verf[1];
484         if (args->plus) {
485                 /* readdirplus: need dircount + buffer size.
486                  * We just make sure we make dircount big enough */
487                 *p++ = htonl(count >> 3);
488         }
489         *p++ = htonl(count);
490         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
491
492         /* Inline the page array */
493         replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readdirres_sz) << 2;
494         xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0, count);
495         return 0;
496 }
497
498 /*
499  * Decode the result of a readdir call.
500  * We just check for syntactical correctness.
501  */
502 static int
503 nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res)
504 {
505         struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
506         struct kvec *iov = rcvbuf->head;
507         struct page **page;
508         size_t hdrlen;
509         u32 len, recvd, pglen;
510         int status, nr = 0;
511         __be32 *entry, *end, *kaddr;
512
513         status = ntohl(*p++);
514         /* Decode post_op_attrs */
515         p = xdr_decode_post_op_attr(p, res->dir_attr);
516         if (status)
517                 return nfs_stat_to_errno(status);
518         /* Decode verifier cookie */
519         if (res->verf) {
520                 res->verf[0] = *p++;
521                 res->verf[1] = *p++;
522         } else {
523                 p += 2;
524         }
525
526         hdrlen = (u8 *) p - (u8 *) iov->iov_base;
527         if (iov->iov_len < hdrlen) {
528                 dprintk("NFS: READDIR reply header overflowed:"
529                                 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
530                 return -errno_NFSERR_IO;
531         } else if (iov->iov_len != hdrlen) {
532                 dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
533                 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
534         }
535
536         pglen = rcvbuf->page_len;
537         recvd = rcvbuf->len - hdrlen;
538         if (pglen > recvd)
539                 pglen = recvd;
540         page = rcvbuf->pages;
541         kaddr = p = kmap_atomic(*page, KM_USER0);
542         end = (__be32 *)((char *)p + pglen);
543         entry = p;
544
545         /* Make sure the packet actually has a value_follows and EOF entry */
546         if ((entry + 1) > end)
547                 goto short_pkt;
548
549         for (; *p++; nr++) {
550                 if (p + 3 > end)
551                         goto short_pkt;
552                 p += 2;                         /* inode # */
553                 len = ntohl(*p++);              /* string length */
554                 p += XDR_QUADLEN(len) + 2;      /* name + cookie */
555                 if (len > NFS3_MAXNAMLEN) {
556                         dprintk("NFS: giant filename in readdir (len 0x%x)!\n",
557                                                 len);
558                         goto err_unmap;
559                 }
560
561                 if (res->plus) {
562                         /* post_op_attr */
563                         if (p + 2 > end)
564                                 goto short_pkt;
565                         if (*p++) {
566                                 p += 21;
567                                 if (p + 1 > end)
568                                         goto short_pkt;
569                         }
570                         /* post_op_fh3 */
571                         if (*p++) {
572                                 if (p + 1 > end)
573                                         goto short_pkt;
574                                 len = ntohl(*p++);
575                                 if (len > NFS3_FHSIZE) {
576                                         dprintk("NFS: giant filehandle in "
577                                                 "readdir (len 0x%x)!\n", len);
578                                         goto err_unmap;
579                                 }
580                                 p += XDR_QUADLEN(len);
581                         }
582                 }
583
584                 if (p + 2 > end)
585                         goto short_pkt;
586                 entry = p;
587         }
588
589         /*
590          * Apparently some server sends responses that are a valid size, but
591          * contain no entries, and have value_follows==0 and EOF==0. For
592          * those, just set the EOF marker.
593          */
594         if (!nr && entry[1] == 0) {
595                 dprintk("NFS: readdir reply truncated!\n");
596                 entry[1] = 1;
597         }
598  out:
599         kunmap_atomic(kaddr, KM_USER0);
600         return nr;
601  short_pkt:
602         /*
603          * When we get a short packet there are 2 possibilities. We can
604          * return an error, or fix up the response to look like a valid
605          * response and return what we have so far. If there are no
606          * entries and the packet was short, then return -EIO. If there
607          * are valid entries in the response, return them and pretend that
608          * the call was successful, but incomplete. The caller can retry the
609          * readdir starting at the last cookie.
610          */
611         entry[0] = entry[1] = 0;
612         if (!nr)
613                 nr = -errno_NFSERR_IO;
614         goto out;
615 err_unmap:
616         nr = -errno_NFSERR_IO;
617         goto out;
618 }
619
620 __be32 *
621 nfs3_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus)
622 {
623         struct nfs_entry old = *entry;
624
625         if (!*p++) {
626                 if (!*p)
627                         return ERR_PTR(-EAGAIN);
628                 entry->eof = 1;
629                 return ERR_PTR(-EBADCOOKIE);
630         }
631
632         p = xdr_decode_hyper(p, &entry->ino);
633         entry->len  = ntohl(*p++);
634         entry->name = (const char *) p;
635         p += XDR_QUADLEN(entry->len);
636         entry->prev_cookie = entry->cookie;
637         p = xdr_decode_hyper(p, &entry->cookie);
638
639         if (plus) {
640                 entry->fattr->valid = 0;
641                 p = xdr_decode_post_op_attr(p, entry->fattr);
642                 /* In fact, a post_op_fh3: */
643                 if (*p++) {
644                         p = xdr_decode_fhandle(p, entry->fh);
645                         /* Ugh -- server reply was truncated */
646                         if (p == NULL) {
647                                 dprintk("NFS: FH truncated\n");
648                                 *entry = old;
649                                 return ERR_PTR(-EAGAIN);
650                         }
651                 } else
652                         memset((u8*)(entry->fh), 0, sizeof(*entry->fh));
653         }
654
655         entry->eof = !p[0] && p[1];
656         return p;
657 }
658
659 /*
660  * Encode COMMIT arguments
661  */
662 static int
663 nfs3_xdr_commitargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
664 {
665         p = xdr_encode_fhandle(p, args->fh);
666         p = xdr_encode_hyper(p, args->offset);
667         *p++ = htonl(args->count);
668         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
669         return 0;
670 }
671
672 #ifdef CONFIG_NFS_V3_ACL
673 /*
674  * Encode GETACL arguments
675  */
676 static int
677 nfs3_xdr_getaclargs(struct rpc_rqst *req, __be32 *p,
678                     struct nfs3_getaclargs *args)
679 {
680         struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
681         unsigned int replen;
682
683         p = xdr_encode_fhandle(p, args->fh);
684         *p++ = htonl(args->mask);
685         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
686
687         if (args->mask & (NFS_ACL | NFS_DFACL)) {
688                 /* Inline the page array */
689                 replen = (RPC_REPHDRSIZE + auth->au_rslack +
690                           ACL3_getaclres_sz) << 2;
691                 xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0,
692                                  NFSACL_MAXPAGES << PAGE_SHIFT);
693         }
694         return 0;
695 }
696
697 /*
698  * Encode SETACL arguments
699  */
700 static int
701 nfs3_xdr_setaclargs(struct rpc_rqst *req, __be32 *p,
702                    struct nfs3_setaclargs *args)
703 {
704         struct xdr_buf *buf = &req->rq_snd_buf;
705         unsigned int base;
706         int err;
707
708         p = xdr_encode_fhandle(p, NFS_FH(args->inode));
709         *p++ = htonl(args->mask);
710         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
711         base = req->rq_slen;
712
713         if (args->npages != 0)
714                 xdr_encode_pages(buf, args->pages, 0, args->len);
715         else
716                 req->rq_slen = xdr_adjust_iovec(req->rq_svec,
717                                 p + XDR_QUADLEN(args->len));
718
719         err = nfsacl_encode(buf, base, args->inode,
720                             (args->mask & NFS_ACL) ?
721                             args->acl_access : NULL, 1, 0);
722         if (err > 0)
723                 err = nfsacl_encode(buf, base + err, args->inode,
724                                     (args->mask & NFS_DFACL) ?
725                                     args->acl_default : NULL, 1,
726                                     NFS_ACL_DEFAULT);
727         return (err > 0) ? 0 : err;
728 }
729 #endif  /* CONFIG_NFS_V3_ACL */
730
731 /*
732  * NFS XDR decode functions
733  */
734
735 /*
736  * Decode attrstat reply.
737  */
738 static int
739 nfs3_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
740 {
741         int     status;
742
743         if ((status = ntohl(*p++)))
744                 return nfs_stat_to_errno(status);
745         xdr_decode_fattr(p, fattr);
746         return 0;
747 }
748
749 /*
750  * Decode status+wcc_data reply
751  * SATTR, REMOVE, RMDIR
752  */
753 static int
754 nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
755 {
756         int     status;
757
758         if ((status = ntohl(*p++)))
759                 status = nfs_stat_to_errno(status);
760         xdr_decode_wcc_data(p, fattr);
761         return status;
762 }
763
764 static int
765 nfs3_xdr_removeres(struct rpc_rqst *req, __be32 *p, struct nfs_removeres *res)
766 {
767         return nfs3_xdr_wccstat(req, p, &res->dir_attr);
768 }
769
770 /*
771  * Decode LOOKUP reply
772  */
773 static int
774 nfs3_xdr_lookupres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
775 {
776         int     status;
777
778         if ((status = ntohl(*p++))) {
779                 status = nfs_stat_to_errno(status);
780         } else {
781                 if (!(p = xdr_decode_fhandle(p, res->fh)))
782                         return -errno_NFSERR_IO;
783                 p = xdr_decode_post_op_attr(p, res->fattr);
784         }
785         xdr_decode_post_op_attr(p, res->dir_attr);
786         return status;
787 }
788
789 /*
790  * Decode ACCESS reply
791  */
792 static int
793 nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res)
794 {
795         int     status = ntohl(*p++);
796
797         p = xdr_decode_post_op_attr(p, res->fattr);
798         if (status)
799                 return nfs_stat_to_errno(status);
800         res->access = ntohl(*p++);
801         return 0;
802 }
803
804 static int
805 nfs3_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readlinkargs *args)
806 {
807         struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
808         unsigned int replen;
809
810         p = xdr_encode_fhandle(p, args->fh);
811         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
812
813         /* Inline the page array */
814         replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readlinkres_sz) << 2;
815         xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, args->pgbase, args->pglen);
816         return 0;
817 }
818
819 /*
820  * Decode READLINK reply
821  */
822 static int
823 nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
824 {
825         struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
826         struct kvec *iov = rcvbuf->head;
827         size_t hdrlen;
828         u32 len, recvd;
829         char    *kaddr;
830         int     status;
831
832         status = ntohl(*p++);
833         p = xdr_decode_post_op_attr(p, fattr);
834
835         if (status != 0)
836                 return nfs_stat_to_errno(status);
837
838         /* Convert length of symlink */
839         len = ntohl(*p++);
840         if (len >= rcvbuf->page_len) {
841                 dprintk("nfs: server returned giant symlink!\n");
842                 return -ENAMETOOLONG;
843         }
844
845         hdrlen = (u8 *) p - (u8 *) iov->iov_base;
846         if (iov->iov_len < hdrlen) {
847                 dprintk("NFS: READLINK reply header overflowed:"
848                                 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
849                 return -errno_NFSERR_IO;
850         } else if (iov->iov_len != hdrlen) {
851                 dprintk("NFS: READLINK header is short. "
852                         "iovec will be shifted.\n");
853                 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
854         }
855         recvd = req->rq_rcv_buf.len - hdrlen;
856         if (recvd < len) {
857                 dprintk("NFS: server cheating in readlink reply: "
858                                 "count %u > recvd %u\n", len, recvd);
859                 return -EIO;
860         }
861
862         /* NULL terminate the string we got */
863         kaddr = (char*)kmap_atomic(rcvbuf->pages[0], KM_USER0);
864         kaddr[len+rcvbuf->page_base] = '\0';
865         kunmap_atomic(kaddr, KM_USER0);
866         return 0;
867 }
868
869 /*
870  * Decode READ reply
871  */
872 static int
873 nfs3_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
874 {
875         struct kvec *iov = req->rq_rcv_buf.head;
876         size_t hdrlen;
877         u32 count, ocount, recvd;
878         int status;
879
880         status = ntohl(*p++);
881         p = xdr_decode_post_op_attr(p, res->fattr);
882
883         if (status != 0)
884                 return nfs_stat_to_errno(status);
885
886         /* Decode reply count and EOF flag. NFSv3 is somewhat redundant
887          * in that it puts the count both in the res struct and in the
888          * opaque data count. */
889         count    = ntohl(*p++);
890         res->eof = ntohl(*p++);
891         ocount   = ntohl(*p++);
892
893         if (ocount != count) {
894                 dprintk("NFS: READ count doesn't match RPC opaque count.\n");
895                 return -errno_NFSERR_IO;
896         }
897
898         hdrlen = (u8 *) p - (u8 *) iov->iov_base;
899         if (iov->iov_len < hdrlen) {
900                 dprintk("NFS: READ reply header overflowed:"
901                                 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
902                 return -errno_NFSERR_IO;
903         } else if (iov->iov_len != hdrlen) {
904                 dprintk("NFS: READ header is short. iovec will be shifted.\n");
905                 xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
906         }
907
908         recvd = req->rq_rcv_buf.len - hdrlen;
909         if (count > recvd) {
910                 dprintk("NFS: server cheating in read reply: "
911                         "count %u > recvd %u\n", count, recvd);
912                 count = recvd;
913                 res->eof = 0;
914         }
915
916         if (count < res->count)
917                 res->count = count;
918
919         return count;
920 }
921
922 /*
923  * Decode WRITE response
924  */
925 static int
926 nfs3_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
927 {
928         int     status;
929
930         status = ntohl(*p++);
931         p = xdr_decode_wcc_data(p, res->fattr);
932
933         if (status != 0)
934                 return nfs_stat_to_errno(status);
935
936         res->count = ntohl(*p++);
937         res->verf->committed = (enum nfs3_stable_how)ntohl(*p++);
938         res->verf->verifier[0] = *p++;
939         res->verf->verifier[1] = *p++;
940
941         return res->count;
942 }
943
944 /*
945  * Decode a CREATE response
946  */
947 static int
948 nfs3_xdr_createres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
949 {
950         int     status;
951
952         status = ntohl(*p++);
953         if (status == 0) {
954                 if (*p++) {
955                         if (!(p = xdr_decode_fhandle(p, res->fh)))
956                                 return -errno_NFSERR_IO;
957                         p = xdr_decode_post_op_attr(p, res->fattr);
958                 } else {
959                         memset(res->fh, 0, sizeof(*res->fh));
960                         /* Do decode post_op_attr but set it to NULL */
961                         p = xdr_decode_post_op_attr(p, res->fattr);
962                         res->fattr->valid = 0;
963                 }
964         } else {
965                 status = nfs_stat_to_errno(status);
966         }
967         p = xdr_decode_wcc_data(p, res->dir_attr);
968         return status;
969 }
970
971 /*
972  * Decode RENAME reply
973  */
974 static int
975 nfs3_xdr_renameres(struct rpc_rqst *req, __be32 *p, struct nfs3_renameres *res)
976 {
977         int     status;
978
979         if ((status = ntohl(*p++)) != 0)
980                 status = nfs_stat_to_errno(status);
981         p = xdr_decode_wcc_data(p, res->fromattr);
982         p = xdr_decode_wcc_data(p, res->toattr);
983         return status;
984 }
985
986 /*
987  * Decode LINK reply
988  */
989 static int
990 nfs3_xdr_linkres(struct rpc_rqst *req, __be32 *p, struct nfs3_linkres *res)
991 {
992         int     status;
993
994         if ((status = ntohl(*p++)) != 0)
995                 status = nfs_stat_to_errno(status);
996         p = xdr_decode_post_op_attr(p, res->fattr);
997         p = xdr_decode_wcc_data(p, res->dir_attr);
998         return status;
999 }
1000
1001 /*
1002  * Decode FSSTAT reply
1003  */
1004 static int
1005 nfs3_xdr_fsstatres(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *res)
1006 {
1007         int             status;
1008
1009         status = ntohl(*p++);
1010
1011         p = xdr_decode_post_op_attr(p, res->fattr);
1012         if (status != 0)
1013                 return nfs_stat_to_errno(status);
1014
1015         p = xdr_decode_hyper(p, &res->tbytes);
1016         p = xdr_decode_hyper(p, &res->fbytes);
1017         p = xdr_decode_hyper(p, &res->abytes);
1018         p = xdr_decode_hyper(p, &res->tfiles);
1019         p = xdr_decode_hyper(p, &res->ffiles);
1020         p = xdr_decode_hyper(p, &res->afiles);
1021
1022         /* ignore invarsec */
1023         return 0;
1024 }
1025
1026 /*
1027  * Decode FSINFO reply
1028  */
1029 static int
1030 nfs3_xdr_fsinfores(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *res)
1031 {
1032         int             status;
1033
1034         status = ntohl(*p++);
1035
1036         p = xdr_decode_post_op_attr(p, res->fattr);
1037         if (status != 0)
1038                 return nfs_stat_to_errno(status);
1039
1040         res->rtmax  = ntohl(*p++);
1041         res->rtpref = ntohl(*p++);
1042         res->rtmult = ntohl(*p++);
1043         res->wtmax  = ntohl(*p++);
1044         res->wtpref = ntohl(*p++);
1045         res->wtmult = ntohl(*p++);
1046         res->dtpref = ntohl(*p++);
1047         p = xdr_decode_hyper(p, &res->maxfilesize);
1048
1049         /* ignore time_delta and properties */
1050         res->lease_time = 0;
1051         return 0;
1052 }
1053
1054 /*
1055  * Decode PATHCONF reply
1056  */
1057 static int
1058 nfs3_xdr_pathconfres(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *res)
1059 {
1060         int             status;
1061
1062         status = ntohl(*p++);
1063
1064         p = xdr_decode_post_op_attr(p, res->fattr);
1065         if (status != 0)
1066                 return nfs_stat_to_errno(status);
1067         res->max_link = ntohl(*p++);
1068         res->max_namelen = ntohl(*p++);
1069
1070         /* ignore remaining fields */
1071         return 0;
1072 }
1073
1074 /*
1075  * Decode COMMIT reply
1076  */
1077 static int
1078 nfs3_xdr_commitres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
1079 {
1080         int             status;
1081
1082         status = ntohl(*p++);
1083         p = xdr_decode_wcc_data(p, res->fattr);
1084         if (status != 0)
1085                 return nfs_stat_to_errno(status);
1086
1087         res->verf->verifier[0] = *p++;
1088         res->verf->verifier[1] = *p++;
1089         return 0;
1090 }
1091
1092 #ifdef CONFIG_NFS_V3_ACL
1093 /*
1094  * Decode GETACL reply
1095  */
1096 static int
1097 nfs3_xdr_getaclres(struct rpc_rqst *req, __be32 *p,
1098                    struct nfs3_getaclres *res)
1099 {
1100         struct xdr_buf *buf = &req->rq_rcv_buf;
1101         int status = ntohl(*p++);
1102         struct posix_acl **acl;
1103         unsigned int *aclcnt;
1104         int err, base;
1105
1106         if (status != 0)
1107                 return nfs_stat_to_errno(status);
1108         p = xdr_decode_post_op_attr(p, res->fattr);
1109         res->mask = ntohl(*p++);
1110         if (res->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
1111                 return -EINVAL;
1112         base = (char *)p - (char *)req->rq_rcv_buf.head->iov_base;
1113
1114         acl = (res->mask & NFS_ACL) ? &res->acl_access : NULL;
1115         aclcnt = (res->mask & NFS_ACLCNT) ? &res->acl_access_count : NULL;
1116         err = nfsacl_decode(buf, base, aclcnt, acl);
1117
1118         acl = (res->mask & NFS_DFACL) ? &res->acl_default : NULL;
1119         aclcnt = (res->mask & NFS_DFACLCNT) ? &res->acl_default_count : NULL;
1120         if (err > 0)
1121                 err = nfsacl_decode(buf, base + err, aclcnt, acl);
1122         return (err > 0) ? 0 : err;
1123 }
1124
1125 /*
1126  * Decode setacl reply.
1127  */
1128 static int
1129 nfs3_xdr_setaclres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1130 {
1131         int status = ntohl(*p++);
1132
1133         if (status)
1134                 return nfs_stat_to_errno(status);
1135         xdr_decode_post_op_attr(p, fattr);
1136         return 0;
1137 }
1138 #endif  /* CONFIG_NFS_V3_ACL */
1139
1140 #define PROC(proc, argtype, restype, timer)                             \
1141 [NFS3PROC_##proc] = {                                                   \
1142         .p_proc      = NFS3PROC_##proc,                                 \
1143         .p_encode    = (kxdrproc_t) nfs3_xdr_##argtype,                 \
1144         .p_decode    = (kxdrproc_t) nfs3_xdr_##restype,                 \
1145         .p_arglen    = NFS3_##argtype##_sz,                             \
1146         .p_replen    = NFS3_##restype##_sz,                             \
1147         .p_timer     = timer,                                           \
1148         .p_statidx   = NFS3PROC_##proc,                                 \
1149         .p_name      = #proc,                                           \
1150         }
1151
1152 struct rpc_procinfo     nfs3_procedures[] = {
1153   PROC(GETATTR,         fhandle,        attrstat, 1),
1154   PROC(SETATTR,         sattrargs,      wccstat, 0),
1155   PROC(LOOKUP,          diropargs,      lookupres, 2),
1156   PROC(ACCESS,          accessargs,     accessres, 1),
1157   PROC(READLINK,        readlinkargs,   readlinkres, 3),
1158   PROC(READ,            readargs,       readres, 3),
1159   PROC(WRITE,           writeargs,      writeres, 4),
1160   PROC(CREATE,          createargs,     createres, 0),
1161   PROC(MKDIR,           mkdirargs,      createres, 0),
1162   PROC(SYMLINK,         symlinkargs,    createres, 0),
1163   PROC(MKNOD,           mknodargs,      createres, 0),
1164   PROC(REMOVE,          removeargs,     removeres, 0),
1165   PROC(RMDIR,           diropargs,      wccstat, 0),
1166   PROC(RENAME,          renameargs,     renameres, 0),
1167   PROC(LINK,            linkargs,       linkres, 0),
1168   PROC(READDIR,         readdirargs,    readdirres, 3),
1169   PROC(READDIRPLUS,     readdirargs,    readdirres, 3),
1170   PROC(FSSTAT,          fhandle,        fsstatres, 0),
1171   PROC(FSINFO,          fhandle,        fsinfores, 0),
1172   PROC(PATHCONF,        fhandle,        pathconfres, 0),
1173   PROC(COMMIT,          commitargs,     commitres, 5),
1174 };
1175
1176 struct rpc_version              nfs_version3 = {
1177         .number                 = 3,
1178         .nrprocs                = ARRAY_SIZE(nfs3_procedures),
1179         .procs                  = nfs3_procedures
1180 };
1181
1182 #ifdef CONFIG_NFS_V3_ACL
1183 static struct rpc_procinfo      nfs3_acl_procedures[] = {
1184         [ACLPROC3_GETACL] = {
1185                 .p_proc = ACLPROC3_GETACL,
1186                 .p_encode = (kxdrproc_t) nfs3_xdr_getaclargs,
1187                 .p_decode = (kxdrproc_t) nfs3_xdr_getaclres,
1188                 .p_arglen = ACL3_getaclargs_sz,
1189                 .p_replen = ACL3_getaclres_sz,
1190                 .p_timer = 1,
1191                 .p_name = "GETACL",
1192         },
1193         [ACLPROC3_SETACL] = {
1194                 .p_proc = ACLPROC3_SETACL,
1195                 .p_encode = (kxdrproc_t) nfs3_xdr_setaclargs,
1196                 .p_decode = (kxdrproc_t) nfs3_xdr_setaclres,
1197                 .p_arglen = ACL3_setaclargs_sz,
1198                 .p_replen = ACL3_setaclres_sz,
1199                 .p_timer = 0,
1200                 .p_name = "SETACL",
1201         },
1202 };
1203
1204 struct rpc_version              nfsacl_version3 = {
1205         .number                 = 3,
1206         .nrprocs                = sizeof(nfs3_acl_procedures)/
1207                                   sizeof(nfs3_acl_procedures[0]),
1208         .procs                  = nfs3_acl_procedures,
1209 };
1210 #endif  /* CONFIG_NFS_V3_ACL */