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