GNU Linux-libre 4.4.289-gnu1
[releases.git] / fs / nfsd / nfs3xdr.c
1 /*
2  * XDR support for nfsd/protocol version 3.
3  *
4  * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
5  *
6  * 2003-08-09 Jamie Lokier: Use htonl() for nanoseconds, not htons()!
7  */
8
9 #include <linux/namei.h>
10 #include <linux/sunrpc/svc_xprt.h>
11 #include "xdr3.h"
12 #include "auth.h"
13 #include "netns.h"
14 #include "vfs.h"
15
16 #define NFSDDBG_FACILITY                NFSDDBG_XDR
17
18
19 /*
20  * Mapping of S_IF* types to NFS file types
21  */
22 static u32      nfs3_ftypes[] = {
23         NF3NON,  NF3FIFO, NF3CHR, NF3BAD,
24         NF3DIR,  NF3BAD,  NF3BLK, NF3BAD,
25         NF3REG,  NF3BAD,  NF3LNK, NF3BAD,
26         NF3SOCK, NF3BAD,  NF3LNK, NF3BAD,
27 };
28
29 /*
30  * XDR functions for basic NFS types
31  */
32 static __be32 *
33 encode_time3(__be32 *p, struct timespec *time)
34 {
35         *p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec);
36         return p;
37 }
38
39 static __be32 *
40 decode_time3(__be32 *p, struct timespec *time)
41 {
42         time->tv_sec = ntohl(*p++);
43         time->tv_nsec = ntohl(*p++);
44         return p;
45 }
46
47 static __be32 *
48 decode_fh(__be32 *p, struct svc_fh *fhp)
49 {
50         unsigned int size;
51         fh_init(fhp, NFS3_FHSIZE);
52         size = ntohl(*p++);
53         if (size > NFS3_FHSIZE)
54                 return NULL;
55
56         memcpy(&fhp->fh_handle.fh_base, p, size);
57         fhp->fh_handle.fh_size = size;
58         return p + XDR_QUADLEN(size);
59 }
60
61 /* Helper function for NFSv3 ACL code */
62 __be32 *nfs3svc_decode_fh(__be32 *p, struct svc_fh *fhp)
63 {
64         return decode_fh(p, fhp);
65 }
66
67 static __be32 *
68 encode_fh(__be32 *p, struct svc_fh *fhp)
69 {
70         unsigned int size = fhp->fh_handle.fh_size;
71         *p++ = htonl(size);
72         if (size) p[XDR_QUADLEN(size)-1]=0;
73         memcpy(p, &fhp->fh_handle.fh_base, size);
74         return p + XDR_QUADLEN(size);
75 }
76
77 /*
78  * Decode a file name and make sure that the path contains
79  * no slashes or null bytes.
80  */
81 static __be32 *
82 decode_filename(__be32 *p, char **namp, unsigned int *lenp)
83 {
84         char            *name;
85         unsigned int    i;
86
87         if ((p = xdr_decode_string_inplace(p, namp, lenp, NFS3_MAXNAMLEN)) != NULL) {
88                 for (i = 0, name = *namp; i < *lenp; i++, name++) {
89                         if (*name == '\0' || *name == '/')
90                                 return NULL;
91                 }
92         }
93
94         return p;
95 }
96
97 static __be32 *
98 decode_sattr3(__be32 *p, struct iattr *iap)
99 {
100         u32     tmp;
101
102         iap->ia_valid = 0;
103
104         if (*p++) {
105                 iap->ia_valid |= ATTR_MODE;
106                 iap->ia_mode = ntohl(*p++);
107         }
108         if (*p++) {
109                 iap->ia_uid = make_kuid(&init_user_ns, ntohl(*p++));
110                 if (uid_valid(iap->ia_uid))
111                         iap->ia_valid |= ATTR_UID;
112         }
113         if (*p++) {
114                 iap->ia_gid = make_kgid(&init_user_ns, ntohl(*p++));
115                 if (gid_valid(iap->ia_gid))
116                         iap->ia_valid |= ATTR_GID;
117         }
118         if (*p++) {
119                 u64     newsize;
120
121                 iap->ia_valid |= ATTR_SIZE;
122                 p = xdr_decode_hyper(p, &newsize);
123                 iap->ia_size = min_t(u64, newsize, NFS_OFFSET_MAX);
124         }
125         if ((tmp = ntohl(*p++)) == 1) { /* set to server time */
126                 iap->ia_valid |= ATTR_ATIME;
127         } else if (tmp == 2) {          /* set to client time */
128                 iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET;
129                 iap->ia_atime.tv_sec = ntohl(*p++);
130                 iap->ia_atime.tv_nsec = ntohl(*p++);
131         }
132         if ((tmp = ntohl(*p++)) == 1) { /* set to server time */
133                 iap->ia_valid |= ATTR_MTIME;
134         } else if (tmp == 2) {          /* set to client time */
135                 iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET;
136                 iap->ia_mtime.tv_sec = ntohl(*p++);
137                 iap->ia_mtime.tv_nsec = ntohl(*p++);
138         }
139         return p;
140 }
141
142 static __be32 *encode_fsid(__be32 *p, struct svc_fh *fhp)
143 {
144         u64 f;
145         switch(fsid_source(fhp)) {
146         default:
147         case FSIDSOURCE_DEV:
148                 p = xdr_encode_hyper(p, (u64)huge_encode_dev
149                                      (d_inode(fhp->fh_dentry)->i_sb->s_dev));
150                 break;
151         case FSIDSOURCE_FSID:
152                 p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
153                 break;
154         case FSIDSOURCE_UUID:
155                 f = ((u64*)fhp->fh_export->ex_uuid)[0];
156                 f ^= ((u64*)fhp->fh_export->ex_uuid)[1];
157                 p = xdr_encode_hyper(p, f);
158                 break;
159         }
160         return p;
161 }
162
163 static __be32 *
164 encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
165               struct kstat *stat)
166 {
167         *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
168         *p++ = htonl((u32) (stat->mode & S_IALLUGO));
169         *p++ = htonl((u32) stat->nlink);
170         *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
171         *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
172         if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
173                 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
174         } else {
175                 p = xdr_encode_hyper(p, (u64) stat->size);
176         }
177         p = xdr_encode_hyper(p, ((u64)stat->blocks) << 9);
178         *p++ = htonl((u32) MAJOR(stat->rdev));
179         *p++ = htonl((u32) MINOR(stat->rdev));
180         p = encode_fsid(p, fhp);
181         p = xdr_encode_hyper(p, stat->ino);
182         p = encode_time3(p, &stat->atime);
183         p = encode_time3(p, &stat->mtime);
184         p = encode_time3(p, &stat->ctime);
185
186         return p;
187 }
188
189 static __be32 *
190 encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
191 {
192         /* Attributes to follow */
193         *p++ = xdr_one;
194         return encode_fattr3(rqstp, p, fhp, &fhp->fh_post_attr);
195 }
196
197 /*
198  * Encode post-operation attributes.
199  * The inode may be NULL if the call failed because of a stale file
200  * handle. In this case, no attributes are returned.
201  */
202 static __be32 *
203 encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
204 {
205         struct dentry *dentry = fhp->fh_dentry;
206         if (dentry && d_really_is_positive(dentry)) {
207                 __be32 err;
208                 struct kstat stat;
209
210                 err = fh_getattr(fhp, &stat);
211                 if (!err) {
212                         *p++ = xdr_one;         /* attributes follow */
213                         lease_get_mtime(d_inode(dentry), &stat.mtime);
214                         return encode_fattr3(rqstp, p, fhp, &stat);
215                 }
216         }
217         *p++ = xdr_zero;
218         return p;
219 }
220
221 /* Helper for NFSv3 ACLs */
222 __be32 *
223 nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
224 {
225         return encode_post_op_attr(rqstp, p, fhp);
226 }
227
228 /*
229  * Enocde weak cache consistency data
230  */
231 static __be32 *
232 encode_wcc_data(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
233 {
234         struct dentry   *dentry = fhp->fh_dentry;
235
236         if (dentry && d_really_is_positive(dentry) && fhp->fh_post_saved) {
237                 if (fhp->fh_pre_saved) {
238                         *p++ = xdr_one;
239                         p = xdr_encode_hyper(p, (u64) fhp->fh_pre_size);
240                         p = encode_time3(p, &fhp->fh_pre_mtime);
241                         p = encode_time3(p, &fhp->fh_pre_ctime);
242                 } else {
243                         *p++ = xdr_zero;
244                 }
245                 return encode_saved_post_attr(rqstp, p, fhp);
246         }
247         /* no pre- or post-attrs */
248         *p++ = xdr_zero;
249         return encode_post_op_attr(rqstp, p, fhp);
250 }
251
252 /*
253  * Fill in the post_op attr for the wcc data
254  */
255 void fill_post_wcc(struct svc_fh *fhp)
256 {
257         __be32 err;
258
259         if (fhp->fh_post_saved)
260                 printk("nfsd: inode locked twice during operation.\n");
261
262         err = fh_getattr(fhp, &fhp->fh_post_attr);
263         fhp->fh_post_change = d_inode(fhp->fh_dentry)->i_version;
264         if (err) {
265                 fhp->fh_post_saved = false;
266                 /* Grab the ctime anyway - set_change_info might use it */
267                 fhp->fh_post_attr.ctime = d_inode(fhp->fh_dentry)->i_ctime;
268         } else
269                 fhp->fh_post_saved = true;
270 }
271
272 /*
273  * XDR decode functions
274  */
275 int
276 nfs3svc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p, struct nfsd_fhandle *args)
277 {
278         p = decode_fh(p, &args->fh);
279         if (!p)
280                 return 0;
281         return xdr_argsize_check(rqstp, p);
282 }
283
284 int
285 nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p,
286                                         struct nfsd3_sattrargs *args)
287 {
288         p = decode_fh(p, &args->fh);
289         if (!p)
290                 return 0;
291         p = decode_sattr3(p, &args->attrs);
292
293         if ((args->check_guard = ntohl(*p++)) != 0) { 
294                 struct timespec time; 
295                 p = decode_time3(p, &time);
296                 args->guardtime = time.tv_sec;
297         }
298
299         return xdr_argsize_check(rqstp, p);
300 }
301
302 int
303 nfs3svc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p,
304                                         struct nfsd3_diropargs *args)
305 {
306         if (!(p = decode_fh(p, &args->fh))
307          || !(p = decode_filename(p, &args->name, &args->len)))
308                 return 0;
309
310         return xdr_argsize_check(rqstp, p);
311 }
312
313 int
314 nfs3svc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p,
315                                         struct nfsd3_accessargs *args)
316 {
317         p = decode_fh(p, &args->fh);
318         if (!p)
319                 return 0;
320         args->access = ntohl(*p++);
321
322         return xdr_argsize_check(rqstp, p);
323 }
324
325 int
326 nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
327                                         struct nfsd3_readargs *args)
328 {
329         unsigned int len;
330         int v;
331         u32 max_blocksize = svc_max_payload(rqstp);
332
333         p = decode_fh(p, &args->fh);
334         if (!p)
335                 return 0;
336         p = xdr_decode_hyper(p, &args->offset);
337
338         args->count = ntohl(*p++);
339         len = min(args->count, max_blocksize);
340
341         /* set up the kvec */
342         v=0;
343         while (len > 0) {
344                 struct page *p = *(rqstp->rq_next_page++);
345
346                 rqstp->rq_vec[v].iov_base = page_address(p);
347                 rqstp->rq_vec[v].iov_len = min_t(unsigned int, len, PAGE_SIZE);
348                 len -= rqstp->rq_vec[v].iov_len;
349                 v++;
350         }
351         args->vlen = v;
352         return xdr_argsize_check(rqstp, p);
353 }
354
355 int
356 nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
357                                         struct nfsd3_writeargs *args)
358 {
359         unsigned int len, v, hdr, dlen;
360         u32 max_blocksize = svc_max_payload(rqstp);
361         struct kvec *head = rqstp->rq_arg.head;
362
363         p = decode_fh(p, &args->fh);
364         if (!p)
365                 return 0;
366         p = xdr_decode_hyper(p, &args->offset);
367
368         args->count = ntohl(*p++);
369         args->stable = ntohl(*p++);
370         len = args->len = ntohl(*p++);
371         if ((void *)p > head->iov_base + head->iov_len)
372                 return 0;
373         /*
374          * The count must equal the amount of data passed.
375          */
376         if (args->count != args->len)
377                 return 0;
378
379         /*
380          * Check to make sure that we got the right number of
381          * bytes.
382          */
383         hdr = (void*)p - head->iov_base;
384         dlen = head->iov_len + rqstp->rq_arg.page_len - hdr;
385         /*
386          * Round the length of the data which was specified up to
387          * the next multiple of XDR units and then compare that
388          * against the length which was actually received.
389          * Note that when RPCSEC/GSS (for example) is used, the
390          * data buffer can be padded so dlen might be larger
391          * than required.  It must never be smaller.
392          */
393         if (dlen < XDR_QUADLEN(len)*4)
394                 return 0;
395
396         if (args->count > max_blocksize) {
397                 args->count = max_blocksize;
398                 len = args->len = max_blocksize;
399         }
400         rqstp->rq_vec[0].iov_base = (void*)p;
401         rqstp->rq_vec[0].iov_len = head->iov_len - hdr;
402         v = 0;
403         while (len > rqstp->rq_vec[v].iov_len) {
404                 len -= rqstp->rq_vec[v].iov_len;
405                 v++;
406                 rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_pages[v]);
407                 rqstp->rq_vec[v].iov_len = PAGE_SIZE;
408         }
409         rqstp->rq_vec[v].iov_len = len;
410         args->vlen = v + 1;
411         return 1;
412 }
413
414 int
415 nfs3svc_decode_createargs(struct svc_rqst *rqstp, __be32 *p,
416                                         struct nfsd3_createargs *args)
417 {
418         if (!(p = decode_fh(p, &args->fh))
419          || !(p = decode_filename(p, &args->name, &args->len)))
420                 return 0;
421
422         switch (args->createmode = ntohl(*p++)) {
423         case NFS3_CREATE_UNCHECKED:
424         case NFS3_CREATE_GUARDED:
425                 p = decode_sattr3(p, &args->attrs);
426                 break;
427         case NFS3_CREATE_EXCLUSIVE:
428                 args->verf = p;
429                 p += 2;
430                 break;
431         default:
432                 return 0;
433         }
434
435         return xdr_argsize_check(rqstp, p);
436 }
437 int
438 nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p,
439                                         struct nfsd3_createargs *args)
440 {
441         if (!(p = decode_fh(p, &args->fh)) ||
442             !(p = decode_filename(p, &args->name, &args->len)))
443                 return 0;
444         p = decode_sattr3(p, &args->attrs);
445
446         return xdr_argsize_check(rqstp, p);
447 }
448
449 int
450 nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p,
451                                         struct nfsd3_symlinkargs *args)
452 {
453         unsigned int len, avail;
454         char *old, *new;
455         struct kvec *vec;
456
457         if (!(p = decode_fh(p, &args->ffh)) ||
458             !(p = decode_filename(p, &args->fname, &args->flen))
459                 )
460                 return 0;
461         p = decode_sattr3(p, &args->attrs);
462
463         /* now decode the pathname, which might be larger than the first page.
464          * As we have to check for nul's anyway, we copy it into a new page
465          * This page appears in the rq_res.pages list, but as pages_len is always
466          * 0, it won't get in the way
467          */
468         len = ntohl(*p++);
469         if (len == 0 || len > NFS3_MAXPATHLEN || len >= PAGE_SIZE)
470                 return 0;
471         args->tname = new = page_address(*(rqstp->rq_next_page++));
472         args->tlen = len;
473         /* first copy and check from the first page */
474         old = (char*)p;
475         vec = &rqstp->rq_arg.head[0];
476         if ((void *)old > vec->iov_base + vec->iov_len)
477                 return 0;
478         avail = vec->iov_len - (old - (char*)vec->iov_base);
479         while (len && avail && *old) {
480                 *new++ = *old++;
481                 len--;
482                 avail--;
483         }
484         /* now copy next page if there is one */
485         if (len && !avail && rqstp->rq_arg.page_len) {
486                 avail = min_t(unsigned int, rqstp->rq_arg.page_len, PAGE_SIZE);
487                 old = page_address(rqstp->rq_arg.pages[0]);
488         }
489         while (len && avail && *old) {
490                 *new++ = *old++;
491                 len--;
492                 avail--;
493         }
494         *new = '\0';
495         if (len)
496                 return 0;
497
498         return 1;
499 }
500
501 int
502 nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, __be32 *p,
503                                         struct nfsd3_mknodargs *args)
504 {
505         if (!(p = decode_fh(p, &args->fh))
506          || !(p = decode_filename(p, &args->name, &args->len)))
507                 return 0;
508
509         args->ftype = ntohl(*p++);
510
511         if (args->ftype == NF3BLK  || args->ftype == NF3CHR
512          || args->ftype == NF3SOCK || args->ftype == NF3FIFO)
513                 p = decode_sattr3(p, &args->attrs);
514
515         if (args->ftype == NF3BLK || args->ftype == NF3CHR) {
516                 args->major = ntohl(*p++);
517                 args->minor = ntohl(*p++);
518         }
519
520         return xdr_argsize_check(rqstp, p);
521 }
522
523 int
524 nfs3svc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p,
525                                         struct nfsd3_renameargs *args)
526 {
527         if (!(p = decode_fh(p, &args->ffh))
528          || !(p = decode_filename(p, &args->fname, &args->flen))
529          || !(p = decode_fh(p, &args->tfh))
530          || !(p = decode_filename(p, &args->tname, &args->tlen)))
531                 return 0;
532
533         return xdr_argsize_check(rqstp, p);
534 }
535
536 int
537 nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p,
538                                         struct nfsd3_readlinkargs *args)
539 {
540         p = decode_fh(p, &args->fh);
541         if (!p)
542                 return 0;
543         args->buffer = page_address(*(rqstp->rq_next_page++));
544
545         return xdr_argsize_check(rqstp, p);
546 }
547
548 int
549 nfs3svc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p,
550                                         struct nfsd3_linkargs *args)
551 {
552         if (!(p = decode_fh(p, &args->ffh))
553          || !(p = decode_fh(p, &args->tfh))
554          || !(p = decode_filename(p, &args->tname, &args->tlen)))
555                 return 0;
556
557         return xdr_argsize_check(rqstp, p);
558 }
559
560 int
561 nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p,
562                                         struct nfsd3_readdirargs *args)
563 {
564         p = decode_fh(p, &args->fh);
565         if (!p)
566                 return 0;
567         p = xdr_decode_hyper(p, &args->cookie);
568         args->verf   = p; p += 2;
569         args->dircount = ~0;
570         args->count  = ntohl(*p++);
571         args->count  = min_t(u32, args->count, PAGE_SIZE);
572         args->buffer = page_address(*(rqstp->rq_next_page++));
573
574         return xdr_argsize_check(rqstp, p);
575 }
576
577 int
578 nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p,
579                                         struct nfsd3_readdirargs *args)
580 {
581         int len;
582         u32 max_blocksize = svc_max_payload(rqstp);
583
584         p = decode_fh(p, &args->fh);
585         if (!p)
586                 return 0;
587         p = xdr_decode_hyper(p, &args->cookie);
588         args->verf     = p; p += 2;
589         args->dircount = ntohl(*p++);
590         args->count    = ntohl(*p++);
591
592         len = args->count = min(args->count, max_blocksize);
593         while (len > 0) {
594                 struct page *p = *(rqstp->rq_next_page++);
595                 if (!args->buffer)
596                         args->buffer = page_address(p);
597                 len -= PAGE_SIZE;
598         }
599
600         return xdr_argsize_check(rqstp, p);
601 }
602
603 int
604 nfs3svc_decode_commitargs(struct svc_rqst *rqstp, __be32 *p,
605                                         struct nfsd3_commitargs *args)
606 {
607         p = decode_fh(p, &args->fh);
608         if (!p)
609                 return 0;
610         p = xdr_decode_hyper(p, &args->offset);
611         args->count = ntohl(*p++);
612
613         return xdr_argsize_check(rqstp, p);
614 }
615
616 /*
617  * XDR encode functions
618  */
619 /*
620  * There must be an encoding function for void results so svc_process
621  * will work properly.
622  */
623 int
624 nfs3svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy)
625 {
626         return xdr_ressize_check(rqstp, p);
627 }
628
629 /* GETATTR */
630 int
631 nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p,
632                                         struct nfsd3_attrstat *resp)
633 {
634         if (resp->status == 0) {
635                 lease_get_mtime(d_inode(resp->fh.fh_dentry),
636                                 &resp->stat.mtime);
637                 p = encode_fattr3(rqstp, p, &resp->fh, &resp->stat);
638         }
639         return xdr_ressize_check(rqstp, p);
640 }
641
642 /* SETATTR, REMOVE, RMDIR */
643 int
644 nfs3svc_encode_wccstat(struct svc_rqst *rqstp, __be32 *p,
645                                         struct nfsd3_attrstat *resp)
646 {
647         p = encode_wcc_data(rqstp, p, &resp->fh);
648         return xdr_ressize_check(rqstp, p);
649 }
650
651 /* LOOKUP */
652 int
653 nfs3svc_encode_diropres(struct svc_rqst *rqstp, __be32 *p,
654                                         struct nfsd3_diropres *resp)
655 {
656         if (resp->status == 0) {
657                 p = encode_fh(p, &resp->fh);
658                 p = encode_post_op_attr(rqstp, p, &resp->fh);
659         }
660         p = encode_post_op_attr(rqstp, p, &resp->dirfh);
661         return xdr_ressize_check(rqstp, p);
662 }
663
664 /* ACCESS */
665 int
666 nfs3svc_encode_accessres(struct svc_rqst *rqstp, __be32 *p,
667                                         struct nfsd3_accessres *resp)
668 {
669         p = encode_post_op_attr(rqstp, p, &resp->fh);
670         if (resp->status == 0)
671                 *p++ = htonl(resp->access);
672         return xdr_ressize_check(rqstp, p);
673 }
674
675 /* READLINK */
676 int
677 nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p,
678                                         struct nfsd3_readlinkres *resp)
679 {
680         p = encode_post_op_attr(rqstp, p, &resp->fh);
681         if (resp->status == 0) {
682                 *p++ = htonl(resp->len);
683                 xdr_ressize_check(rqstp, p);
684                 rqstp->rq_res.page_len = resp->len;
685                 if (resp->len & 3) {
686                         /* need to pad the tail */
687                         rqstp->rq_res.tail[0].iov_base = p;
688                         *p = 0;
689                         rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3);
690                 }
691                 return 1;
692         } else
693                 return xdr_ressize_check(rqstp, p);
694 }
695
696 /* READ */
697 int
698 nfs3svc_encode_readres(struct svc_rqst *rqstp, __be32 *p,
699                                         struct nfsd3_readres *resp)
700 {
701         p = encode_post_op_attr(rqstp, p, &resp->fh);
702         if (resp->status == 0) {
703                 *p++ = htonl(resp->count);
704                 *p++ = htonl(resp->eof);
705                 *p++ = htonl(resp->count);      /* xdr opaque count */
706                 xdr_ressize_check(rqstp, p);
707                 /* now update rqstp->rq_res to reflect data as well */
708                 rqstp->rq_res.page_len = resp->count;
709                 if (resp->count & 3) {
710                         /* need to pad the tail */
711                         rqstp->rq_res.tail[0].iov_base = p;
712                         *p = 0;
713                         rqstp->rq_res.tail[0].iov_len = 4 - (resp->count & 3);
714                 }
715                 return 1;
716         } else
717                 return xdr_ressize_check(rqstp, p);
718 }
719
720 /* WRITE */
721 int
722 nfs3svc_encode_writeres(struct svc_rqst *rqstp, __be32 *p,
723                                         struct nfsd3_writeres *resp)
724 {
725         struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
726
727         p = encode_wcc_data(rqstp, p, &resp->fh);
728         if (resp->status == 0) {
729                 *p++ = htonl(resp->count);
730                 *p++ = htonl(resp->committed);
731                 *p++ = htonl(nn->nfssvc_boot.tv_sec);
732                 *p++ = htonl(nn->nfssvc_boot.tv_usec);
733         }
734         return xdr_ressize_check(rqstp, p);
735 }
736
737 /* CREATE, MKDIR, SYMLINK, MKNOD */
738 int
739 nfs3svc_encode_createres(struct svc_rqst *rqstp, __be32 *p,
740                                         struct nfsd3_diropres *resp)
741 {
742         if (resp->status == 0) {
743                 *p++ = xdr_one;
744                 p = encode_fh(p, &resp->fh);
745                 p = encode_post_op_attr(rqstp, p, &resp->fh);
746         }
747         p = encode_wcc_data(rqstp, p, &resp->dirfh);
748         return xdr_ressize_check(rqstp, p);
749 }
750
751 /* RENAME */
752 int
753 nfs3svc_encode_renameres(struct svc_rqst *rqstp, __be32 *p,
754                                         struct nfsd3_renameres *resp)
755 {
756         p = encode_wcc_data(rqstp, p, &resp->ffh);
757         p = encode_wcc_data(rqstp, p, &resp->tfh);
758         return xdr_ressize_check(rqstp, p);
759 }
760
761 /* LINK */
762 int
763 nfs3svc_encode_linkres(struct svc_rqst *rqstp, __be32 *p,
764                                         struct nfsd3_linkres *resp)
765 {
766         p = encode_post_op_attr(rqstp, p, &resp->fh);
767         p = encode_wcc_data(rqstp, p, &resp->tfh);
768         return xdr_ressize_check(rqstp, p);
769 }
770
771 /* READDIR */
772 int
773 nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p,
774                                         struct nfsd3_readdirres *resp)
775 {
776         p = encode_post_op_attr(rqstp, p, &resp->fh);
777
778         if (resp->status == 0) {
779                 /* stupid readdir cookie */
780                 memcpy(p, resp->verf, 8); p += 2;
781                 xdr_ressize_check(rqstp, p);
782                 if (rqstp->rq_res.head[0].iov_len + (2<<2) > PAGE_SIZE)
783                         return 1; /*No room for trailer */
784                 rqstp->rq_res.page_len = (resp->count) << 2;
785
786                 /* add the 'tail' to the end of the 'head' page - page 0. */
787                 rqstp->rq_res.tail[0].iov_base = p;
788                 *p++ = 0;               /* no more entries */
789                 *p++ = htonl(resp->common.err == nfserr_eof);
790                 rqstp->rq_res.tail[0].iov_len = 2<<2;
791                 return 1;
792         } else
793                 return xdr_ressize_check(rqstp, p);
794 }
795
796 static __be32 *
797 encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name,
798              int namlen, u64 ino)
799 {
800         *p++ = xdr_one;                          /* mark entry present */
801         p    = xdr_encode_hyper(p, ino);         /* file id */
802         p    = xdr_encode_array(p, name, namlen);/* name length & name */
803
804         cd->offset = p;                         /* remember pointer */
805         p = xdr_encode_hyper(p, NFS_OFFSET_MAX);/* offset of next entry */
806
807         return p;
808 }
809
810 static __be32
811 compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
812                  const char *name, int namlen, u64 ino)
813 {
814         struct svc_export       *exp;
815         struct dentry           *dparent, *dchild;
816         __be32 rv = nfserr_noent;
817
818         dparent = cd->fh.fh_dentry;
819         exp  = cd->fh.fh_export;
820
821         if (isdotent(name, namlen)) {
822                 if (namlen == 2) {
823                         dchild = dget_parent(dparent);
824                         /*
825                          * Don't return filehandle for ".." if we're at
826                          * the filesystem or export root:
827                          */
828                         if (dchild == dparent)
829                                 goto out;
830                         if (dparent == exp->ex_path.dentry)
831                                 goto out;
832                 } else
833                         dchild = dget(dparent);
834         } else
835                 dchild = lookup_one_len(name, dparent, namlen);
836         if (IS_ERR(dchild))
837                 return rv;
838         if (d_mountpoint(dchild))
839                 goto out;
840         if (d_really_is_negative(dchild))
841                 goto out;
842         if (dchild->d_inode->i_ino != ino)
843                 goto out;
844         rv = fh_compose(fhp, exp, dchild, &cd->fh);
845 out:
846         dput(dchild);
847         return rv;
848 }
849
850 static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen, u64 ino)
851 {
852         struct svc_fh   *fh = &cd->scratch;
853         __be32 err;
854
855         fh_init(fh, NFS3_FHSIZE);
856         err = compose_entry_fh(cd, fh, name, namlen, ino);
857         if (err) {
858                 *p++ = 0;
859                 *p++ = 0;
860                 goto out;
861         }
862         p = encode_post_op_attr(cd->rqstp, p, fh);
863         *p++ = xdr_one;                 /* yes, a file handle follows */
864         p = encode_fh(p, fh);
865 out:
866         fh_put(fh);
867         return p;
868 }
869
870 /*
871  * Encode a directory entry. This one works for both normal readdir
872  * and readdirplus.
873  * The normal readdir reply requires 2 (fileid) + 1 (stringlen)
874  * + string + 2 (cookie) + 1 (next) words, i.e. 6 + strlen.
875  * 
876  * The readdirplus baggage is 1+21 words for post_op_attr, plus the
877  * file handle.
878  */
879
880 #define NFS3_ENTRY_BAGGAGE      (2 + 1 + 2 + 1)
881 #define NFS3_ENTRYPLUS_BAGGAGE  (1 + 21 + 1 + (NFS3_FHSIZE >> 2))
882 static int
883 encode_entry(struct readdir_cd *ccd, const char *name, int namlen,
884              loff_t offset, u64 ino, unsigned int d_type, int plus)
885 {
886         struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres,
887                                                         common);
888         __be32          *p = cd->buffer;
889         caddr_t         curr_page_addr = NULL;
890         struct page **  page;
891         int             slen;           /* string (name) length */
892         int             elen;           /* estimated entry length in words */
893         int             num_entry_words = 0;    /* actual number of words */
894
895         if (cd->offset) {
896                 u64 offset64 = offset;
897
898                 if (unlikely(cd->offset1)) {
899                         /* we ended up with offset on a page boundary */
900                         *cd->offset = htonl(offset64 >> 32);
901                         *cd->offset1 = htonl(offset64 & 0xffffffff);
902                         cd->offset1 = NULL;
903                 } else {
904                         xdr_encode_hyper(cd->offset, offset64);
905                 }
906                 cd->offset = NULL;
907         }
908
909         /*
910         dprintk("encode_entry(%.*s @%ld%s)\n",
911                 namlen, name, (long) offset, plus? " plus" : "");
912          */
913
914         /* truncate filename if too long */
915         namlen = min(namlen, NFS3_MAXNAMLEN);
916
917         slen = XDR_QUADLEN(namlen);
918         elen = slen + NFS3_ENTRY_BAGGAGE
919                 + (plus? NFS3_ENTRYPLUS_BAGGAGE : 0);
920
921         if (cd->buflen < elen) {
922                 cd->common.err = nfserr_toosmall;
923                 return -EINVAL;
924         }
925
926         /* determine which page in rq_respages[] we are currently filling */
927         for (page = cd->rqstp->rq_respages + 1;
928                                 page < cd->rqstp->rq_next_page; page++) {
929                 curr_page_addr = page_address(*page);
930
931                 if (((caddr_t)cd->buffer >= curr_page_addr) &&
932                     ((caddr_t)cd->buffer <  curr_page_addr + PAGE_SIZE))
933                         break;
934         }
935
936         if ((caddr_t)(cd->buffer + elen) < (curr_page_addr + PAGE_SIZE)) {
937                 /* encode entry in current page */
938
939                 p = encode_entry_baggage(cd, p, name, namlen, ino);
940
941                 if (plus)
942                         p = encode_entryplus_baggage(cd, p, name, namlen, ino);
943                 num_entry_words = p - cd->buffer;
944         } else if (*(page+1) != NULL) {
945                 /* temporarily encode entry into next page, then move back to
946                  * current and next page in rq_respages[] */
947                 __be32 *p1, *tmp;
948                 int len1, len2;
949
950                 /* grab next page for temporary storage of entry */
951                 p1 = tmp = page_address(*(page+1));
952
953                 p1 = encode_entry_baggage(cd, p1, name, namlen, ino);
954
955                 if (plus)
956                         p1 = encode_entryplus_baggage(cd, p1, name, namlen, ino);
957
958                 /* determine entry word length and lengths to go in pages */
959                 num_entry_words = p1 - tmp;
960                 len1 = curr_page_addr + PAGE_SIZE - (caddr_t)cd->buffer;
961                 if ((num_entry_words << 2) < len1) {
962                         /* the actual number of words in the entry is less
963                          * than elen and can still fit in the current page
964                          */
965                         memmove(p, tmp, num_entry_words << 2);
966                         p += num_entry_words;
967
968                         /* update offset */
969                         cd->offset = cd->buffer + (cd->offset - tmp);
970                 } else {
971                         unsigned int offset_r = (cd->offset - tmp) << 2;
972
973                         /* update pointer to offset location.
974                          * This is a 64bit quantity, so we need to
975                          * deal with 3 cases:
976                          *  -   entirely in first page
977                          *  -   entirely in second page
978                          *  -   4 bytes in each page
979                          */
980                         if (offset_r + 8 <= len1) {
981                                 cd->offset = p + (cd->offset - tmp);
982                         } else if (offset_r >= len1) {
983                                 cd->offset -= len1 >> 2;
984                         } else {
985                                 /* sitting on the fence */
986                                 BUG_ON(offset_r != len1 - 4);
987                                 cd->offset = p + (cd->offset - tmp);
988                                 cd->offset1 = tmp;
989                         }
990
991                         len2 = (num_entry_words << 2) - len1;
992
993                         /* move from temp page to current and next pages */
994                         memmove(p, tmp, len1);
995                         memmove(tmp, (caddr_t)tmp+len1, len2);
996
997                         p = tmp + (len2 >> 2);
998                 }
999         }
1000         else {
1001                 cd->common.err = nfserr_toosmall;
1002                 return -EINVAL;
1003         }
1004
1005         cd->buflen -= num_entry_words;
1006         cd->buffer = p;
1007         cd->common.err = nfs_ok;
1008         return 0;
1009
1010 }
1011
1012 int
1013 nfs3svc_encode_entry(void *cd, const char *name,
1014                      int namlen, loff_t offset, u64 ino, unsigned int d_type)
1015 {
1016         return encode_entry(cd, name, namlen, offset, ino, d_type, 0);
1017 }
1018
1019 int
1020 nfs3svc_encode_entry_plus(void *cd, const char *name,
1021                           int namlen, loff_t offset, u64 ino,
1022                           unsigned int d_type)
1023 {
1024         return encode_entry(cd, name, namlen, offset, ino, d_type, 1);
1025 }
1026
1027 /* FSSTAT */
1028 int
1029 nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, __be32 *p,
1030                                         struct nfsd3_fsstatres *resp)
1031 {
1032         struct kstatfs  *s = &resp->stats;
1033         u64             bs = s->f_bsize;
1034
1035         *p++ = xdr_zero;        /* no post_op_attr */
1036
1037         if (resp->status == 0) {
1038                 p = xdr_encode_hyper(p, bs * s->f_blocks);      /* total bytes */
1039                 p = xdr_encode_hyper(p, bs * s->f_bfree);       /* free bytes */
1040                 p = xdr_encode_hyper(p, bs * s->f_bavail);      /* user available bytes */
1041                 p = xdr_encode_hyper(p, s->f_files);    /* total inodes */
1042                 p = xdr_encode_hyper(p, s->f_ffree);    /* free inodes */
1043                 p = xdr_encode_hyper(p, s->f_ffree);    /* user available inodes */
1044                 *p++ = htonl(resp->invarsec);   /* mean unchanged time */
1045         }
1046         return xdr_ressize_check(rqstp, p);
1047 }
1048
1049 /* FSINFO */
1050 int
1051 nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, __be32 *p,
1052                                         struct nfsd3_fsinfores *resp)
1053 {
1054         *p++ = xdr_zero;        /* no post_op_attr */
1055
1056         if (resp->status == 0) {
1057                 *p++ = htonl(resp->f_rtmax);
1058                 *p++ = htonl(resp->f_rtpref);
1059                 *p++ = htonl(resp->f_rtmult);
1060                 *p++ = htonl(resp->f_wtmax);
1061                 *p++ = htonl(resp->f_wtpref);
1062                 *p++ = htonl(resp->f_wtmult);
1063                 *p++ = htonl(resp->f_dtpref);
1064                 p = xdr_encode_hyper(p, resp->f_maxfilesize);
1065                 *p++ = xdr_one;
1066                 *p++ = xdr_zero;
1067                 *p++ = htonl(resp->f_properties);
1068         }
1069
1070         return xdr_ressize_check(rqstp, p);
1071 }
1072
1073 /* PATHCONF */
1074 int
1075 nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, __be32 *p,
1076                                         struct nfsd3_pathconfres *resp)
1077 {
1078         *p++ = xdr_zero;        /* no post_op_attr */
1079
1080         if (resp->status == 0) {
1081                 *p++ = htonl(resp->p_link_max);
1082                 *p++ = htonl(resp->p_name_max);
1083                 *p++ = htonl(resp->p_no_trunc);
1084                 *p++ = htonl(resp->p_chown_restricted);
1085                 *p++ = htonl(resp->p_case_insensitive);
1086                 *p++ = htonl(resp->p_case_preserving);
1087         }
1088
1089         return xdr_ressize_check(rqstp, p);
1090 }
1091
1092 /* COMMIT */
1093 int
1094 nfs3svc_encode_commitres(struct svc_rqst *rqstp, __be32 *p,
1095                                         struct nfsd3_commitres *resp)
1096 {
1097         struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
1098
1099         p = encode_wcc_data(rqstp, p, &resp->fh);
1100         /* Write verifier */
1101         if (resp->status == 0) {
1102                 *p++ = htonl(nn->nfssvc_boot.tv_sec);
1103                 *p++ = htonl(nn->nfssvc_boot.tv_usec);
1104         }
1105         return xdr_ressize_check(rqstp, p);
1106 }
1107
1108 /*
1109  * XDR release functions
1110  */
1111 int
1112 nfs3svc_release_fhandle(struct svc_rqst *rqstp, __be32 *p,
1113                                         struct nfsd3_attrstat *resp)
1114 {
1115         fh_put(&resp->fh);
1116         return 1;
1117 }
1118
1119 int
1120 nfs3svc_release_fhandle2(struct svc_rqst *rqstp, __be32 *p,
1121                                         struct nfsd3_fhandle_pair *resp)
1122 {
1123         fh_put(&resp->fh1);
1124         fh_put(&resp->fh2);
1125         return 1;
1126 }