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