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