NFSD: Clean up after updating NFSv3 ACL encoders
[linux-2.6-microblaze.git] / fs / nfsd / nfs3xdr.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * XDR support for nfsd/protocol version 3.
4  *
5  * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
6  *
7  * 2003-08-09 Jamie Lokier: Use htonl() for nanoseconds, not htons()!
8  */
9
10 #include <linux/namei.h>
11 #include <linux/sunrpc/svc_xprt.h>
12 #include "xdr3.h"
13 #include "auth.h"
14 #include "netns.h"
15 #include "vfs.h"
16
17 #define NFSDDBG_FACILITY                NFSDDBG_XDR
18
19
20 /*
21  * Force construction of an empty post-op attr
22  */
23 static const struct svc_fh nfs3svc_null_fh = {
24         .fh_no_wcc      = true,
25 };
26
27 /*
28  * time_delta. {1, 0} means the server is accurate only
29  * to the nearest second.
30  */
31 static const struct timespec64 nfs3svc_time_delta = {
32         .tv_sec         = 1,
33         .tv_nsec        = 0,
34 };
35
36 /*
37  * Mapping of S_IF* types to NFS file types
38  */
39 static const u32 nfs3_ftypes[] = {
40         NF3NON,  NF3FIFO, NF3CHR, NF3BAD,
41         NF3DIR,  NF3BAD,  NF3BLK, NF3BAD,
42         NF3REG,  NF3BAD,  NF3LNK, NF3BAD,
43         NF3SOCK, NF3BAD,  NF3LNK, NF3BAD,
44 };
45
46
47 /*
48  * Basic NFSv3 data types (RFC 1813 Sections 2.5 and 2.6)
49  */
50
51 static __be32 *
52 encode_nfstime3(__be32 *p, const struct timespec64 *time)
53 {
54         *p++ = cpu_to_be32((u32)time->tv_sec);
55         *p++ = cpu_to_be32(time->tv_nsec);
56
57         return p;
58 }
59
60 static bool
61 svcxdr_decode_nfstime3(struct xdr_stream *xdr, struct timespec64 *timep)
62 {
63         __be32 *p;
64
65         p = xdr_inline_decode(xdr, XDR_UNIT * 2);
66         if (!p)
67                 return false;
68         timep->tv_sec = be32_to_cpup(p++);
69         timep->tv_nsec = be32_to_cpup(p);
70
71         return true;
72 }
73
74 /**
75  * svcxdr_decode_nfs_fh3 - Decode an NFSv3 file handle
76  * @xdr: XDR stream positioned at an undecoded NFSv3 FH
77  * @fhp: OUT: filled-in server file handle
78  *
79  * Return values:
80  *  %false: The encoded file handle was not valid
81  *  %true: @fhp has been initialized
82  */
83 bool
84 svcxdr_decode_nfs_fh3(struct xdr_stream *xdr, struct svc_fh *fhp)
85 {
86         __be32 *p;
87         u32 size;
88
89         if (xdr_stream_decode_u32(xdr, &size) < 0)
90                 return false;
91         if (size == 0 || size > NFS3_FHSIZE)
92                 return false;
93         p = xdr_inline_decode(xdr, size);
94         if (!p)
95                 return false;
96         fh_init(fhp, NFS3_FHSIZE);
97         fhp->fh_handle.fh_size = size;
98         memcpy(&fhp->fh_handle.fh_base, p, size);
99
100         return true;
101 }
102
103 /**
104  * svcxdr_encode_nfsstat3 - Encode an NFSv3 status code
105  * @xdr: XDR stream
106  * @status: status value to encode
107  *
108  * Return values:
109  *   %false: Send buffer space was exhausted
110  *   %true: Success
111  */
112 bool
113 svcxdr_encode_nfsstat3(struct xdr_stream *xdr, __be32 status)
114 {
115         __be32 *p;
116
117         p = xdr_reserve_space(xdr, sizeof(status));
118         if (!p)
119                 return false;
120         *p = status;
121
122         return true;
123 }
124
125 static bool
126 svcxdr_encode_nfs_fh3(struct xdr_stream *xdr, const struct svc_fh *fhp)
127 {
128         u32 size = fhp->fh_handle.fh_size;
129         __be32 *p;
130
131         p = xdr_reserve_space(xdr, XDR_UNIT + size);
132         if (!p)
133                 return false;
134         *p++ = cpu_to_be32(size);
135         if (size)
136                 p[XDR_QUADLEN(size) - 1] = 0;
137         memcpy(p, &fhp->fh_handle.fh_base, size);
138
139         return true;
140 }
141
142 static bool
143 svcxdr_encode_post_op_fh3(struct xdr_stream *xdr, const struct svc_fh *fhp)
144 {
145         if (xdr_stream_encode_item_present(xdr) < 0)
146                 return false;
147         if (!svcxdr_encode_nfs_fh3(xdr, fhp))
148                 return false;
149
150         return true;
151 }
152
153 static bool
154 svcxdr_encode_cookieverf3(struct xdr_stream *xdr, const __be32 *verf)
155 {
156         __be32 *p;
157
158         p = xdr_reserve_space(xdr, NFS3_COOKIEVERFSIZE);
159         if (!p)
160                 return false;
161         memcpy(p, verf, NFS3_COOKIEVERFSIZE);
162
163         return true;
164 }
165
166 static bool
167 svcxdr_encode_writeverf3(struct xdr_stream *xdr, const __be32 *verf)
168 {
169         __be32 *p;
170
171         p = xdr_reserve_space(xdr, NFS3_WRITEVERFSIZE);
172         if (!p)
173                 return false;
174         memcpy(p, verf, NFS3_WRITEVERFSIZE);
175
176         return true;
177 }
178
179 static bool
180 svcxdr_decode_filename3(struct xdr_stream *xdr, char **name, unsigned int *len)
181 {
182         u32 size, i;
183         __be32 *p;
184         char *c;
185
186         if (xdr_stream_decode_u32(xdr, &size) < 0)
187                 return false;
188         if (size == 0 || size > NFS3_MAXNAMLEN)
189                 return false;
190         p = xdr_inline_decode(xdr, size);
191         if (!p)
192                 return false;
193
194         *len = size;
195         *name = (char *)p;
196         for (i = 0, c = *name; i < size; i++, c++) {
197                 if (*c == '\0' || *c == '/')
198                         return false;
199         }
200
201         return true;
202 }
203
204 static bool
205 svcxdr_decode_diropargs3(struct xdr_stream *xdr, struct svc_fh *fhp,
206                          char **name, unsigned int *len)
207 {
208         return svcxdr_decode_nfs_fh3(xdr, fhp) &&
209                 svcxdr_decode_filename3(xdr, name, len);
210 }
211
212 static bool
213 svcxdr_decode_sattr3(struct svc_rqst *rqstp, struct xdr_stream *xdr,
214                      struct iattr *iap)
215 {
216         u32 set_it;
217
218         iap->ia_valid = 0;
219
220         if (xdr_stream_decode_bool(xdr, &set_it) < 0)
221                 return false;
222         if (set_it) {
223                 u32 mode;
224
225                 if (xdr_stream_decode_u32(xdr, &mode) < 0)
226                         return false;
227                 iap->ia_valid |= ATTR_MODE;
228                 iap->ia_mode = mode;
229         }
230         if (xdr_stream_decode_bool(xdr, &set_it) < 0)
231                 return false;
232         if (set_it) {
233                 u32 uid;
234
235                 if (xdr_stream_decode_u32(xdr, &uid) < 0)
236                         return false;
237                 iap->ia_uid = make_kuid(nfsd_user_namespace(rqstp), uid);
238                 if (uid_valid(iap->ia_uid))
239                         iap->ia_valid |= ATTR_UID;
240         }
241         if (xdr_stream_decode_bool(xdr, &set_it) < 0)
242                 return false;
243         if (set_it) {
244                 u32 gid;
245
246                 if (xdr_stream_decode_u32(xdr, &gid) < 0)
247                         return false;
248                 iap->ia_gid = make_kgid(nfsd_user_namespace(rqstp), gid);
249                 if (gid_valid(iap->ia_gid))
250                         iap->ia_valid |= ATTR_GID;
251         }
252         if (xdr_stream_decode_bool(xdr, &set_it) < 0)
253                 return false;
254         if (set_it) {
255                 u64 newsize;
256
257                 if (xdr_stream_decode_u64(xdr, &newsize) < 0)
258                         return false;
259                 iap->ia_valid |= ATTR_SIZE;
260                 iap->ia_size = min_t(u64, newsize, NFS_OFFSET_MAX);
261         }
262         if (xdr_stream_decode_u32(xdr, &set_it) < 0)
263                 return false;
264         switch (set_it) {
265         case DONT_CHANGE:
266                 break;
267         case SET_TO_SERVER_TIME:
268                 iap->ia_valid |= ATTR_ATIME;
269                 break;
270         case SET_TO_CLIENT_TIME:
271                 if (!svcxdr_decode_nfstime3(xdr, &iap->ia_atime))
272                         return false;
273                 iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET;
274                 break;
275         default:
276                 return false;
277         }
278         if (xdr_stream_decode_u32(xdr, &set_it) < 0)
279                 return false;
280         switch (set_it) {
281         case DONT_CHANGE:
282                 break;
283         case SET_TO_SERVER_TIME:
284                 iap->ia_valid |= ATTR_MTIME;
285                 break;
286         case SET_TO_CLIENT_TIME:
287                 if (!svcxdr_decode_nfstime3(xdr, &iap->ia_mtime))
288                         return false;
289                 iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET;
290                 break;
291         default:
292                 return false;
293         }
294
295         return true;
296 }
297
298 static bool
299 svcxdr_decode_sattrguard3(struct xdr_stream *xdr, struct nfsd3_sattrargs *args)
300 {
301         __be32 *p;
302         u32 check;
303
304         if (xdr_stream_decode_bool(xdr, &check) < 0)
305                 return false;
306         if (check) {
307                 p = xdr_inline_decode(xdr, XDR_UNIT * 2);
308                 if (!p)
309                         return false;
310                 args->check_guard = 1;
311                 args->guardtime = be32_to_cpup(p);
312         } else
313                 args->check_guard = 0;
314
315         return true;
316 }
317
318 static bool
319 svcxdr_decode_specdata3(struct xdr_stream *xdr, struct nfsd3_mknodargs *args)
320 {
321         __be32 *p;
322
323         p = xdr_inline_decode(xdr, XDR_UNIT * 2);
324         if (!p)
325                 return false;
326         args->major = be32_to_cpup(p++);
327         args->minor = be32_to_cpup(p);
328
329         return true;
330 }
331
332 static bool
333 svcxdr_decode_devicedata3(struct svc_rqst *rqstp, struct xdr_stream *xdr,
334                           struct nfsd3_mknodargs *args)
335 {
336         return svcxdr_decode_sattr3(rqstp, xdr, &args->attrs) &&
337                 svcxdr_decode_specdata3(xdr, args);
338 }
339
340 static bool
341 svcxdr_encode_fattr3(struct svc_rqst *rqstp, struct xdr_stream *xdr,
342                      const struct svc_fh *fhp, const struct kstat *stat)
343 {
344         struct user_namespace *userns = nfsd_user_namespace(rqstp);
345         __be32 *p;
346         u64 fsid;
347
348         p = xdr_reserve_space(xdr, XDR_UNIT * 21);
349         if (!p)
350                 return false;
351
352         *p++ = cpu_to_be32(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
353         *p++ = cpu_to_be32((u32)(stat->mode & S_IALLUGO));
354         *p++ = cpu_to_be32((u32)stat->nlink);
355         *p++ = cpu_to_be32((u32)from_kuid_munged(userns, stat->uid));
356         *p++ = cpu_to_be32((u32)from_kgid_munged(userns, stat->gid));
357         if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN)
358                 p = xdr_encode_hyper(p, (u64)NFS3_MAXPATHLEN);
359         else
360                 p = xdr_encode_hyper(p, (u64)stat->size);
361
362         /* used */
363         p = xdr_encode_hyper(p, ((u64)stat->blocks) << 9);
364
365         /* rdev */
366         *p++ = cpu_to_be32((u32)MAJOR(stat->rdev));
367         *p++ = cpu_to_be32((u32)MINOR(stat->rdev));
368
369         switch(fsid_source(fhp)) {
370         case FSIDSOURCE_FSID:
371                 fsid = (u64)fhp->fh_export->ex_fsid;
372                 break;
373         case FSIDSOURCE_UUID:
374                 fsid = ((u64 *)fhp->fh_export->ex_uuid)[0];
375                 fsid ^= ((u64 *)fhp->fh_export->ex_uuid)[1];
376                 break;
377         default:
378                 fsid = (u64)huge_encode_dev(fhp->fh_dentry->d_sb->s_dev);
379         }
380         p = xdr_encode_hyper(p, fsid);
381
382         /* fileid */
383         p = xdr_encode_hyper(p, stat->ino);
384
385         p = encode_nfstime3(p, &stat->atime);
386         p = encode_nfstime3(p, &stat->mtime);
387         encode_nfstime3(p, &stat->ctime);
388
389         return true;
390 }
391
392 static bool
393 svcxdr_encode_wcc_attr(struct xdr_stream *xdr, const struct svc_fh *fhp)
394 {
395         __be32 *p;
396
397         p = xdr_reserve_space(xdr, XDR_UNIT * 6);
398         if (!p)
399                 return false;
400         p = xdr_encode_hyper(p, (u64)fhp->fh_pre_size);
401         p = encode_nfstime3(p, &fhp->fh_pre_mtime);
402         encode_nfstime3(p, &fhp->fh_pre_ctime);
403
404         return true;
405 }
406
407 static bool
408 svcxdr_encode_pre_op_attr(struct xdr_stream *xdr, const struct svc_fh *fhp)
409 {
410         if (!fhp->fh_pre_saved) {
411                 if (xdr_stream_encode_item_absent(xdr) < 0)
412                         return false;
413                 return true;
414         }
415
416         if (xdr_stream_encode_item_present(xdr) < 0)
417                 return false;
418         return svcxdr_encode_wcc_attr(xdr, fhp);
419 }
420
421 /**
422  * svcxdr_encode_post_op_attr - Encode NFSv3 post-op attributes
423  * @rqstp: Context of a completed RPC transaction
424  * @xdr: XDR stream
425  * @fhp: File handle to encode
426  *
427  * Return values:
428  *   %false: Send buffer space was exhausted
429  *   %true: Success
430  */
431 bool
432 svcxdr_encode_post_op_attr(struct svc_rqst *rqstp, struct xdr_stream *xdr,
433                            const struct svc_fh *fhp)
434 {
435         struct dentry *dentry = fhp->fh_dentry;
436         struct kstat stat;
437
438         /*
439          * The inode may be NULL if the call failed because of a
440          * stale file handle. In this case, no attributes are
441          * returned.
442          */
443         if (fhp->fh_no_wcc || !dentry || !d_really_is_positive(dentry))
444                 goto no_post_op_attrs;
445         if (fh_getattr(fhp, &stat) != nfs_ok)
446                 goto no_post_op_attrs;
447
448         if (xdr_stream_encode_item_present(xdr) < 0)
449                 return false;
450         lease_get_mtime(d_inode(dentry), &stat.mtime);
451         if (!svcxdr_encode_fattr3(rqstp, xdr, fhp, &stat))
452                 return false;
453
454         return true;
455
456 no_post_op_attrs:
457         return xdr_stream_encode_item_absent(xdr) > 0;
458 }
459
460 /*
461  * Encode weak cache consistency data
462  */
463 static bool
464 svcxdr_encode_wcc_data(struct svc_rqst *rqstp, struct xdr_stream *xdr,
465                        const struct svc_fh *fhp)
466 {
467         struct dentry *dentry = fhp->fh_dentry;
468
469         if (!dentry || !d_really_is_positive(dentry) || !fhp->fh_post_saved)
470                 goto neither;
471
472         /* before */
473         if (!svcxdr_encode_pre_op_attr(xdr, fhp))
474                 return false;
475
476         /* after */
477         if (xdr_stream_encode_item_present(xdr) < 0)
478                 return false;
479         if (!svcxdr_encode_fattr3(rqstp, xdr, fhp, &fhp->fh_post_attr))
480                 return false;
481
482         return true;
483
484 neither:
485         if (xdr_stream_encode_item_absent(xdr) < 0)
486                 return false;
487         if (!svcxdr_encode_post_op_attr(rqstp, xdr, fhp))
488                 return false;
489
490         return true;
491 }
492
493 static bool fs_supports_change_attribute(struct super_block *sb)
494 {
495         return sb->s_flags & SB_I_VERSION || sb->s_export_op->fetch_iversion;
496 }
497
498 /*
499  * Fill in the pre_op attr for the wcc data
500  */
501 void fill_pre_wcc(struct svc_fh *fhp)
502 {
503         struct inode    *inode;
504         struct kstat    stat;
505         bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE);
506
507         if (fhp->fh_no_wcc || fhp->fh_pre_saved)
508                 return;
509         inode = d_inode(fhp->fh_dentry);
510         if (fs_supports_change_attribute(inode->i_sb) || !v4) {
511                 __be32 err = fh_getattr(fhp, &stat);
512
513                 if (err) {
514                         /* Grab the times from inode anyway */
515                         stat.mtime = inode->i_mtime;
516                         stat.ctime = inode->i_ctime;
517                         stat.size  = inode->i_size;
518                 }
519                 fhp->fh_pre_mtime = stat.mtime;
520                 fhp->fh_pre_ctime = stat.ctime;
521                 fhp->fh_pre_size  = stat.size;
522         }
523         if (v4)
524                 fhp->fh_pre_change = nfsd4_change_attribute(&stat, inode);
525
526         fhp->fh_pre_saved = true;
527 }
528
529 /*
530  * Fill in the post_op attr for the wcc data
531  */
532 void fill_post_wcc(struct svc_fh *fhp)
533 {
534         bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE);
535         struct inode *inode = d_inode(fhp->fh_dentry);
536
537         if (fhp->fh_no_wcc)
538                 return;
539
540         if (fhp->fh_post_saved)
541                 printk("nfsd: inode locked twice during operation.\n");
542
543         fhp->fh_post_saved = true;
544
545         if (fs_supports_change_attribute(inode->i_sb) || !v4) {
546                 __be32 err = fh_getattr(fhp, &fhp->fh_post_attr);
547
548                 if (err) {
549                         fhp->fh_post_saved = false;
550                         fhp->fh_post_attr.ctime = inode->i_ctime;
551                 }
552         }
553         if (v4)
554                 fhp->fh_post_change =
555                         nfsd4_change_attribute(&fhp->fh_post_attr, inode);
556 }
557
558 /*
559  * XDR decode functions
560  */
561
562 int
563 nfs3svc_decode_fhandleargs(struct svc_rqst *rqstp, __be32 *p)
564 {
565         struct xdr_stream *xdr = &rqstp->rq_arg_stream;
566         struct nfsd_fhandle *args = rqstp->rq_argp;
567
568         return svcxdr_decode_nfs_fh3(xdr, &args->fh);
569 }
570
571 int
572 nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p)
573 {
574         struct xdr_stream *xdr = &rqstp->rq_arg_stream;
575         struct nfsd3_sattrargs *args = rqstp->rq_argp;
576
577         return svcxdr_decode_nfs_fh3(xdr, &args->fh) &&
578                 svcxdr_decode_sattr3(rqstp, xdr, &args->attrs) &&
579                 svcxdr_decode_sattrguard3(xdr, args);
580 }
581
582 int
583 nfs3svc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p)
584 {
585         struct xdr_stream *xdr = &rqstp->rq_arg_stream;
586         struct nfsd3_diropargs *args = rqstp->rq_argp;
587
588         return svcxdr_decode_diropargs3(xdr, &args->fh, &args->name, &args->len);
589 }
590
591 int
592 nfs3svc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p)
593 {
594         struct xdr_stream *xdr = &rqstp->rq_arg_stream;
595         struct nfsd3_accessargs *args = rqstp->rq_argp;
596
597         if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
598                 return 0;
599         if (xdr_stream_decode_u32(xdr, &args->access) < 0)
600                 return 0;
601
602         return 1;
603 }
604
605 int
606 nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p)
607 {
608         struct xdr_stream *xdr = &rqstp->rq_arg_stream;
609         struct nfsd3_readargs *args = rqstp->rq_argp;
610
611         if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
612                 return 0;
613         if (xdr_stream_decode_u64(xdr, &args->offset) < 0)
614                 return 0;
615         if (xdr_stream_decode_u32(xdr, &args->count) < 0)
616                 return 0;
617
618         return 1;
619 }
620
621 int
622 nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
623 {
624         struct xdr_stream *xdr = &rqstp->rq_arg_stream;
625         struct nfsd3_writeargs *args = rqstp->rq_argp;
626         u32 max_blocksize = svc_max_payload(rqstp);
627         struct kvec *head = rqstp->rq_arg.head;
628         struct kvec *tail = rqstp->rq_arg.tail;
629         size_t remaining;
630
631         if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
632                 return 0;
633         if (xdr_stream_decode_u64(xdr, &args->offset) < 0)
634                 return 0;
635         if (xdr_stream_decode_u32(xdr, &args->count) < 0)
636                 return 0;
637         if (xdr_stream_decode_u32(xdr, &args->stable) < 0)
638                 return 0;
639
640         /* opaque data */
641         if (xdr_stream_decode_u32(xdr, &args->len) < 0)
642                 return 0;
643
644         /* request sanity */
645         if (args->count != args->len)
646                 return 0;
647         remaining = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len;
648         remaining -= xdr_stream_pos(xdr);
649         if (remaining < xdr_align_size(args->len))
650                 return 0;
651         if (args->count > max_blocksize) {
652                 args->count = max_blocksize;
653                 args->len = max_blocksize;
654         }
655
656         args->first.iov_base = xdr->p;
657         args->first.iov_len = head->iov_len - xdr_stream_pos(xdr);
658
659         return 1;
660 }
661
662 int
663 nfs3svc_decode_createargs(struct svc_rqst *rqstp, __be32 *p)
664 {
665         struct xdr_stream *xdr = &rqstp->rq_arg_stream;
666         struct nfsd3_createargs *args = rqstp->rq_argp;
667
668         if (!svcxdr_decode_diropargs3(xdr, &args->fh, &args->name, &args->len))
669                 return 0;
670         if (xdr_stream_decode_u32(xdr, &args->createmode) < 0)
671                 return 0;
672         switch (args->createmode) {
673         case NFS3_CREATE_UNCHECKED:
674         case NFS3_CREATE_GUARDED:
675                 return svcxdr_decode_sattr3(rqstp, xdr, &args->attrs);
676         case NFS3_CREATE_EXCLUSIVE:
677                 args->verf = xdr_inline_decode(xdr, NFS3_CREATEVERFSIZE);
678                 if (!args->verf)
679                         return 0;
680                 break;
681         default:
682                 return 0;
683         }
684         return 1;
685 }
686
687 int
688 nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p)
689 {
690         struct xdr_stream *xdr = &rqstp->rq_arg_stream;
691         struct nfsd3_createargs *args = rqstp->rq_argp;
692
693         return svcxdr_decode_diropargs3(xdr, &args->fh,
694                                         &args->name, &args->len) &&
695                 svcxdr_decode_sattr3(rqstp, xdr, &args->attrs);
696 }
697
698 int
699 nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p)
700 {
701         struct xdr_stream *xdr = &rqstp->rq_arg_stream;
702         struct nfsd3_symlinkargs *args = rqstp->rq_argp;
703         struct kvec *head = rqstp->rq_arg.head;
704         struct kvec *tail = rqstp->rq_arg.tail;
705         size_t remaining;
706
707         if (!svcxdr_decode_diropargs3(xdr, &args->ffh, &args->fname, &args->flen))
708                 return 0;
709         if (!svcxdr_decode_sattr3(rqstp, xdr, &args->attrs))
710                 return 0;
711         if (xdr_stream_decode_u32(xdr, &args->tlen) < 0)
712                 return 0;
713
714         /* request sanity */
715         remaining = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len;
716         remaining -= xdr_stream_pos(xdr);
717         if (remaining < xdr_align_size(args->tlen))
718                 return 0;
719
720         args->first.iov_base = xdr->p;
721         args->first.iov_len = head->iov_len - xdr_stream_pos(xdr);
722
723         return 1;
724 }
725
726 int
727 nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, __be32 *p)
728 {
729         struct xdr_stream *xdr = &rqstp->rq_arg_stream;
730         struct nfsd3_mknodargs *args = rqstp->rq_argp;
731
732         if (!svcxdr_decode_diropargs3(xdr, &args->fh, &args->name, &args->len))
733                 return 0;
734         if (xdr_stream_decode_u32(xdr, &args->ftype) < 0)
735                 return 0;
736         switch (args->ftype) {
737         case NF3CHR:
738         case NF3BLK:
739                 return svcxdr_decode_devicedata3(rqstp, xdr, args);
740         case NF3SOCK:
741         case NF3FIFO:
742                 return svcxdr_decode_sattr3(rqstp, xdr, &args->attrs);
743         case NF3REG:
744         case NF3DIR:
745         case NF3LNK:
746                 /* Valid XDR but illegal file types */
747                 break;
748         default:
749                 return 0;
750         }
751
752         return 1;
753 }
754
755 int
756 nfs3svc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p)
757 {
758         struct xdr_stream *xdr = &rqstp->rq_arg_stream;
759         struct nfsd3_renameargs *args = rqstp->rq_argp;
760
761         return svcxdr_decode_diropargs3(xdr, &args->ffh,
762                                         &args->fname, &args->flen) &&
763                 svcxdr_decode_diropargs3(xdr, &args->tfh,
764                                          &args->tname, &args->tlen);
765 }
766
767 int
768 nfs3svc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p)
769 {
770         struct xdr_stream *xdr = &rqstp->rq_arg_stream;
771         struct nfsd3_linkargs *args = rqstp->rq_argp;
772
773         return svcxdr_decode_nfs_fh3(xdr, &args->ffh) &&
774                 svcxdr_decode_diropargs3(xdr, &args->tfh,
775                                          &args->tname, &args->tlen);
776 }
777
778 int
779 nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p)
780 {
781         struct xdr_stream *xdr = &rqstp->rq_arg_stream;
782         struct nfsd3_readdirargs *args = rqstp->rq_argp;
783
784         if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
785                 return 0;
786         if (xdr_stream_decode_u64(xdr, &args->cookie) < 0)
787                 return 0;
788         args->verf = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE);
789         if (!args->verf)
790                 return 0;
791         if (xdr_stream_decode_u32(xdr, &args->count) < 0)
792                 return 0;
793
794         return 1;
795 }
796
797 int
798 nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p)
799 {
800         struct xdr_stream *xdr = &rqstp->rq_arg_stream;
801         struct nfsd3_readdirargs *args = rqstp->rq_argp;
802         u32 dircount;
803
804         if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
805                 return 0;
806         if (xdr_stream_decode_u64(xdr, &args->cookie) < 0)
807                 return 0;
808         args->verf = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE);
809         if (!args->verf)
810                 return 0;
811         /* dircount is ignored */
812         if (xdr_stream_decode_u32(xdr, &dircount) < 0)
813                 return 0;
814         if (xdr_stream_decode_u32(xdr, &args->count) < 0)
815                 return 0;
816
817         return 1;
818 }
819
820 int
821 nfs3svc_decode_commitargs(struct svc_rqst *rqstp, __be32 *p)
822 {
823         struct xdr_stream *xdr = &rqstp->rq_arg_stream;
824         struct nfsd3_commitargs *args = rqstp->rq_argp;
825
826         if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
827                 return 0;
828         if (xdr_stream_decode_u64(xdr, &args->offset) < 0)
829                 return 0;
830         if (xdr_stream_decode_u32(xdr, &args->count) < 0)
831                 return 0;
832
833         return 1;
834 }
835
836 /*
837  * XDR encode functions
838  */
839
840 /* GETATTR */
841 int
842 nfs3svc_encode_getattrres(struct svc_rqst *rqstp, __be32 *p)
843 {
844         struct xdr_stream *xdr = &rqstp->rq_res_stream;
845         struct nfsd3_attrstat *resp = rqstp->rq_resp;
846
847         if (!svcxdr_encode_nfsstat3(xdr, resp->status))
848                 return 0;
849         switch (resp->status) {
850         case nfs_ok:
851                 lease_get_mtime(d_inode(resp->fh.fh_dentry), &resp->stat.mtime);
852                 if (!svcxdr_encode_fattr3(rqstp, xdr, &resp->fh, &resp->stat))
853                         return 0;
854                 break;
855         }
856
857         return 1;
858 }
859
860 /* SETATTR, REMOVE, RMDIR */
861 int
862 nfs3svc_encode_wccstat(struct svc_rqst *rqstp, __be32 *p)
863 {
864         struct xdr_stream *xdr = &rqstp->rq_res_stream;
865         struct nfsd3_attrstat *resp = rqstp->rq_resp;
866
867         return svcxdr_encode_nfsstat3(xdr, resp->status) &&
868                 svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh);
869 }
870
871 /* LOOKUP */
872 int nfs3svc_encode_lookupres(struct svc_rqst *rqstp, __be32 *p)
873 {
874         struct xdr_stream *xdr = &rqstp->rq_res_stream;
875         struct nfsd3_diropres *resp = rqstp->rq_resp;
876
877         if (!svcxdr_encode_nfsstat3(xdr, resp->status))
878                 return 0;
879         switch (resp->status) {
880         case nfs_ok:
881                 if (!svcxdr_encode_nfs_fh3(xdr, &resp->fh))
882                         return 0;
883                 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
884                         return 0;
885                 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->dirfh))
886                         return 0;
887                 break;
888         default:
889                 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->dirfh))
890                         return 0;
891         }
892
893         return 1;
894 }
895
896 /* ACCESS */
897 int
898 nfs3svc_encode_accessres(struct svc_rqst *rqstp, __be32 *p)
899 {
900         struct xdr_stream *xdr = &rqstp->rq_res_stream;
901         struct nfsd3_accessres *resp = rqstp->rq_resp;
902
903         if (!svcxdr_encode_nfsstat3(xdr, resp->status))
904                 return 0;
905         switch (resp->status) {
906         case nfs_ok:
907                 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
908                         return 0;
909                 if (xdr_stream_encode_u32(xdr, resp->access) < 0)
910                         return 0;
911                 break;
912         default:
913                 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
914                         return 0;
915         }
916
917         return 1;
918 }
919
920 /* READLINK */
921 int
922 nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p)
923 {
924         struct xdr_stream *xdr = &rqstp->rq_res_stream;
925         struct nfsd3_readlinkres *resp = rqstp->rq_resp;
926         struct kvec *head = rqstp->rq_res.head;
927
928         if (!svcxdr_encode_nfsstat3(xdr, resp->status))
929                 return 0;
930         switch (resp->status) {
931         case nfs_ok:
932                 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
933                         return 0;
934                 if (xdr_stream_encode_u32(xdr, resp->len) < 0)
935                         return 0;
936                 xdr_write_pages(xdr, resp->pages, 0, resp->len);
937                 if (svc_encode_result_payload(rqstp, head->iov_len, resp->len) < 0)
938                         return 0;
939                 break;
940         default:
941                 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
942                         return 0;
943         }
944
945         return 1;
946 }
947
948 /* READ */
949 int
950 nfs3svc_encode_readres(struct svc_rqst *rqstp, __be32 *p)
951 {
952         struct xdr_stream *xdr = &rqstp->rq_res_stream;
953         struct nfsd3_readres *resp = rqstp->rq_resp;
954         struct kvec *head = rqstp->rq_res.head;
955
956         if (!svcxdr_encode_nfsstat3(xdr, resp->status))
957                 return 0;
958         switch (resp->status) {
959         case nfs_ok:
960                 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
961                         return 0;
962                 if (xdr_stream_encode_u32(xdr, resp->count) < 0)
963                         return 0;
964                 if (xdr_stream_encode_bool(xdr, resp->eof) < 0)
965                         return 0;
966                 if (xdr_stream_encode_u32(xdr, resp->count) < 0)
967                         return 0;
968                 xdr_write_pages(xdr, resp->pages, rqstp->rq_res.page_base,
969                                 resp->count);
970                 if (svc_encode_result_payload(rqstp, head->iov_len, resp->count) < 0)
971                         return 0;
972                 break;
973         default:
974                 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
975                         return 0;
976         }
977
978         return 1;
979 }
980
981 /* WRITE */
982 int
983 nfs3svc_encode_writeres(struct svc_rqst *rqstp, __be32 *p)
984 {
985         struct xdr_stream *xdr = &rqstp->rq_res_stream;
986         struct nfsd3_writeres *resp = rqstp->rq_resp;
987
988         if (!svcxdr_encode_nfsstat3(xdr, resp->status))
989                 return 0;
990         switch (resp->status) {
991         case nfs_ok:
992                 if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh))
993                         return 0;
994                 if (xdr_stream_encode_u32(xdr, resp->count) < 0)
995                         return 0;
996                 if (xdr_stream_encode_u32(xdr, resp->committed) < 0)
997                         return 0;
998                 if (!svcxdr_encode_writeverf3(xdr, resp->verf))
999                         return 0;
1000                 break;
1001         default:
1002                 if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh))
1003                         return 0;
1004         }
1005
1006         return 1;
1007 }
1008
1009 /* CREATE, MKDIR, SYMLINK, MKNOD */
1010 int
1011 nfs3svc_encode_createres(struct svc_rqst *rqstp, __be32 *p)
1012 {
1013         struct xdr_stream *xdr = &rqstp->rq_res_stream;
1014         struct nfsd3_diropres *resp = rqstp->rq_resp;
1015
1016         if (!svcxdr_encode_nfsstat3(xdr, resp->status))
1017                 return 0;
1018         switch (resp->status) {
1019         case nfs_ok:
1020                 if (!svcxdr_encode_post_op_fh3(xdr, &resp->fh))
1021                         return 0;
1022                 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
1023                         return 0;
1024                 if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->dirfh))
1025                         return 0;
1026                 break;
1027         default:
1028                 if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->dirfh))
1029                         return 0;
1030         }
1031
1032         return 1;
1033 }
1034
1035 /* RENAME */
1036 int
1037 nfs3svc_encode_renameres(struct svc_rqst *rqstp, __be32 *p)
1038 {
1039         struct xdr_stream *xdr = &rqstp->rq_res_stream;
1040         struct nfsd3_renameres *resp = rqstp->rq_resp;
1041
1042         return svcxdr_encode_nfsstat3(xdr, resp->status) &&
1043                 svcxdr_encode_wcc_data(rqstp, xdr, &resp->ffh) &&
1044                 svcxdr_encode_wcc_data(rqstp, xdr, &resp->tfh);
1045 }
1046
1047 /* LINK */
1048 int
1049 nfs3svc_encode_linkres(struct svc_rqst *rqstp, __be32 *p)
1050 {
1051         struct xdr_stream *xdr = &rqstp->rq_res_stream;
1052         struct nfsd3_linkres *resp = rqstp->rq_resp;
1053
1054         return svcxdr_encode_nfsstat3(xdr, resp->status) &&
1055                 svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh) &&
1056                 svcxdr_encode_wcc_data(rqstp, xdr, &resp->tfh);
1057 }
1058
1059 /* READDIR */
1060 int
1061 nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p)
1062 {
1063         struct xdr_stream *xdr = &rqstp->rq_res_stream;
1064         struct nfsd3_readdirres *resp = rqstp->rq_resp;
1065         struct xdr_buf *dirlist = &resp->dirlist;
1066
1067         if (!svcxdr_encode_nfsstat3(xdr, resp->status))
1068                 return 0;
1069         switch (resp->status) {
1070         case nfs_ok:
1071                 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
1072                         return 0;
1073                 if (!svcxdr_encode_cookieverf3(xdr, resp->verf))
1074                         return 0;
1075                 xdr_write_pages(xdr, dirlist->pages, 0, dirlist->len);
1076                 /* no more entries */
1077                 if (xdr_stream_encode_item_absent(xdr) < 0)
1078                         return 0;
1079                 if (xdr_stream_encode_bool(xdr, resp->common.err == nfserr_eof) < 0)
1080                         return 0;
1081                 break;
1082         default:
1083                 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
1084                         return 0;
1085         }
1086
1087         return 1;
1088 }
1089
1090 static __be32
1091 compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
1092                  const char *name, int namlen, u64 ino)
1093 {
1094         struct svc_export       *exp;
1095         struct dentry           *dparent, *dchild;
1096         __be32 rv = nfserr_noent;
1097
1098         dparent = cd->fh.fh_dentry;
1099         exp  = cd->fh.fh_export;
1100
1101         if (isdotent(name, namlen)) {
1102                 if (namlen == 2) {
1103                         dchild = dget_parent(dparent);
1104                         /*
1105                          * Don't return filehandle for ".." if we're at
1106                          * the filesystem or export root:
1107                          */
1108                         if (dchild == dparent)
1109                                 goto out;
1110                         if (dparent == exp->ex_path.dentry)
1111                                 goto out;
1112                 } else
1113                         dchild = dget(dparent);
1114         } else
1115                 dchild = lookup_positive_unlocked(name, dparent, namlen);
1116         if (IS_ERR(dchild))
1117                 return rv;
1118         if (d_mountpoint(dchild))
1119                 goto out;
1120         if (dchild->d_inode->i_ino != ino)
1121                 goto out;
1122         rv = fh_compose(fhp, exp, dchild, &cd->fh);
1123 out:
1124         dput(dchild);
1125         return rv;
1126 }
1127
1128 /**
1129  * nfs3svc_encode_cookie3 - Encode a directory offset cookie
1130  * @resp: readdir result context
1131  * @offset: offset cookie to encode
1132  *
1133  * The buffer space for the offset cookie has already been reserved
1134  * by svcxdr_encode_entry3_common().
1135  */
1136 void nfs3svc_encode_cookie3(struct nfsd3_readdirres *resp, u64 offset)
1137 {
1138         __be64 cookie = cpu_to_be64(offset);
1139
1140         if (!resp->cookie_offset)
1141                 return;
1142         write_bytes_to_xdr_buf(&resp->dirlist, resp->cookie_offset, &cookie,
1143                                sizeof(cookie));
1144         resp->cookie_offset = 0;
1145 }
1146
1147 static bool
1148 svcxdr_encode_entry3_common(struct nfsd3_readdirres *resp, const char *name,
1149                             int namlen, loff_t offset, u64 ino)
1150 {
1151         struct xdr_buf *dirlist = &resp->dirlist;
1152         struct xdr_stream *xdr = &resp->xdr;
1153
1154         if (xdr_stream_encode_item_present(xdr) < 0)
1155                 return false;
1156         /* fileid */
1157         if (xdr_stream_encode_u64(xdr, ino) < 0)
1158                 return false;
1159         /* name */
1160         if (xdr_stream_encode_opaque(xdr, name, min(namlen, NFS3_MAXNAMLEN)) < 0)
1161                 return false;
1162         /* cookie */
1163         resp->cookie_offset = dirlist->len;
1164         if (xdr_stream_encode_u64(xdr, NFS_OFFSET_MAX) < 0)
1165                 return false;
1166
1167         return true;
1168 }
1169
1170 /**
1171  * nfs3svc_encode_entry3 - encode one NFSv3 READDIR entry
1172  * @data: directory context
1173  * @name: name of the object to be encoded
1174  * @namlen: length of that name, in bytes
1175  * @offset: the offset of the previous entry
1176  * @ino: the fileid of this entry
1177  * @d_type: unused
1178  *
1179  * Return values:
1180  *   %0: Entry was successfully encoded.
1181  *   %-EINVAL: An encoding problem occured, secondary status code in resp->common.err
1182  *
1183  * On exit, the following fields are updated:
1184  *   - resp->xdr
1185  *   - resp->common.err
1186  *   - resp->cookie_offset
1187  */
1188 int nfs3svc_encode_entry3(void *data, const char *name, int namlen,
1189                           loff_t offset, u64 ino, unsigned int d_type)
1190 {
1191         struct readdir_cd *ccd = data;
1192         struct nfsd3_readdirres *resp = container_of(ccd,
1193                                                      struct nfsd3_readdirres,
1194                                                      common);
1195         unsigned int starting_length = resp->dirlist.len;
1196
1197         /* The offset cookie for the previous entry */
1198         nfs3svc_encode_cookie3(resp, offset);
1199
1200         if (!svcxdr_encode_entry3_common(resp, name, namlen, offset, ino))
1201                 goto out_toosmall;
1202
1203         xdr_commit_encode(&resp->xdr);
1204         resp->common.err = nfs_ok;
1205         return 0;
1206
1207 out_toosmall:
1208         resp->cookie_offset = 0;
1209         resp->common.err = nfserr_toosmall;
1210         resp->dirlist.len = starting_length;
1211         return -EINVAL;
1212 }
1213
1214 static bool
1215 svcxdr_encode_entry3_plus(struct nfsd3_readdirres *resp, const char *name,
1216                           int namlen, u64 ino)
1217 {
1218         struct xdr_stream *xdr = &resp->xdr;
1219         struct svc_fh *fhp = &resp->scratch;
1220         bool result;
1221
1222         result = false;
1223         fh_init(fhp, NFS3_FHSIZE);
1224         if (compose_entry_fh(resp, fhp, name, namlen, ino) != nfs_ok)
1225                 goto out_noattrs;
1226
1227         if (!svcxdr_encode_post_op_attr(resp->rqstp, xdr, fhp))
1228                 goto out;
1229         if (!svcxdr_encode_post_op_fh3(xdr, fhp))
1230                 goto out;
1231         result = true;
1232
1233 out:
1234         fh_put(fhp);
1235         return result;
1236
1237 out_noattrs:
1238         if (xdr_stream_encode_item_absent(xdr) < 0)
1239                 return false;
1240         if (xdr_stream_encode_item_absent(xdr) < 0)
1241                 return false;
1242         return true;
1243 }
1244
1245 /**
1246  * nfs3svc_encode_entryplus3 - encode one NFSv3 READDIRPLUS entry
1247  * @data: directory context
1248  * @name: name of the object to be encoded
1249  * @namlen: length of that name, in bytes
1250  * @offset: the offset of the previous entry
1251  * @ino: the fileid of this entry
1252  * @d_type: unused
1253  *
1254  * Return values:
1255  *   %0: Entry was successfully encoded.
1256  *   %-EINVAL: An encoding problem occured, secondary status code in resp->common.err
1257  *
1258  * On exit, the following fields are updated:
1259  *   - resp->xdr
1260  *   - resp->common.err
1261  *   - resp->cookie_offset
1262  */
1263 int nfs3svc_encode_entryplus3(void *data, const char *name, int namlen,
1264                               loff_t offset, u64 ino, unsigned int d_type)
1265 {
1266         struct readdir_cd *ccd = data;
1267         struct nfsd3_readdirres *resp = container_of(ccd,
1268                                                      struct nfsd3_readdirres,
1269                                                      common);
1270         unsigned int starting_length = resp->dirlist.len;
1271
1272         /* The offset cookie for the previous entry */
1273         nfs3svc_encode_cookie3(resp, offset);
1274
1275         if (!svcxdr_encode_entry3_common(resp, name, namlen, offset, ino))
1276                 goto out_toosmall;
1277         if (!svcxdr_encode_entry3_plus(resp, name, namlen, ino))
1278                 goto out_toosmall;
1279
1280         xdr_commit_encode(&resp->xdr);
1281         resp->common.err = nfs_ok;
1282         return 0;
1283
1284 out_toosmall:
1285         resp->cookie_offset = 0;
1286         resp->common.err = nfserr_toosmall;
1287         resp->dirlist.len = starting_length;
1288         return -EINVAL;
1289 }
1290
1291 static bool
1292 svcxdr_encode_fsstat3resok(struct xdr_stream *xdr,
1293                            const struct nfsd3_fsstatres *resp)
1294 {
1295         const struct kstatfs *s = &resp->stats;
1296         u64 bs = s->f_bsize;
1297         __be32 *p;
1298
1299         p = xdr_reserve_space(xdr, XDR_UNIT * 13);
1300         if (!p)
1301                 return false;
1302         p = xdr_encode_hyper(p, bs * s->f_blocks);      /* total bytes */
1303         p = xdr_encode_hyper(p, bs * s->f_bfree);       /* free bytes */
1304         p = xdr_encode_hyper(p, bs * s->f_bavail);      /* user available bytes */
1305         p = xdr_encode_hyper(p, s->f_files);            /* total inodes */
1306         p = xdr_encode_hyper(p, s->f_ffree);            /* free inodes */
1307         p = xdr_encode_hyper(p, s->f_ffree);            /* user available inodes */
1308         *p = cpu_to_be32(resp->invarsec);               /* mean unchanged time */
1309
1310         return true;
1311 }
1312
1313 /* FSSTAT */
1314 int
1315 nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, __be32 *p)
1316 {
1317         struct xdr_stream *xdr = &rqstp->rq_res_stream;
1318         struct nfsd3_fsstatres *resp = rqstp->rq_resp;
1319
1320         if (!svcxdr_encode_nfsstat3(xdr, resp->status))
1321                 return 0;
1322         switch (resp->status) {
1323         case nfs_ok:
1324                 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh))
1325                         return 0;
1326                 if (!svcxdr_encode_fsstat3resok(xdr, resp))
1327                         return 0;
1328                 break;
1329         default:
1330                 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh))
1331                         return 0;
1332         }
1333
1334         return 1;
1335 }
1336
1337 static bool
1338 svcxdr_encode_fsinfo3resok(struct xdr_stream *xdr,
1339                            const struct nfsd3_fsinfores *resp)
1340 {
1341         __be32 *p;
1342
1343         p = xdr_reserve_space(xdr, XDR_UNIT * 12);
1344         if (!p)
1345                 return false;
1346         *p++ = cpu_to_be32(resp->f_rtmax);
1347         *p++ = cpu_to_be32(resp->f_rtpref);
1348         *p++ = cpu_to_be32(resp->f_rtmult);
1349         *p++ = cpu_to_be32(resp->f_wtmax);
1350         *p++ = cpu_to_be32(resp->f_wtpref);
1351         *p++ = cpu_to_be32(resp->f_wtmult);
1352         *p++ = cpu_to_be32(resp->f_dtpref);
1353         p = xdr_encode_hyper(p, resp->f_maxfilesize);
1354         p = encode_nfstime3(p, &nfs3svc_time_delta);
1355         *p = cpu_to_be32(resp->f_properties);
1356
1357         return true;
1358 }
1359
1360 /* FSINFO */
1361 int
1362 nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, __be32 *p)
1363 {
1364         struct xdr_stream *xdr = &rqstp->rq_res_stream;
1365         struct nfsd3_fsinfores *resp = rqstp->rq_resp;
1366
1367         if (!svcxdr_encode_nfsstat3(xdr, resp->status))
1368                 return 0;
1369         switch (resp->status) {
1370         case nfs_ok:
1371                 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh))
1372                         return 0;
1373                 if (!svcxdr_encode_fsinfo3resok(xdr, resp))
1374                         return 0;
1375                 break;
1376         default:
1377                 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh))
1378                         return 0;
1379         }
1380
1381         return 1;
1382 }
1383
1384 static bool
1385 svcxdr_encode_pathconf3resok(struct xdr_stream *xdr,
1386                              const struct nfsd3_pathconfres *resp)
1387 {
1388         __be32 *p;
1389
1390         p = xdr_reserve_space(xdr, XDR_UNIT * 6);
1391         if (!p)
1392                 return false;
1393         *p++ = cpu_to_be32(resp->p_link_max);
1394         *p++ = cpu_to_be32(resp->p_name_max);
1395         p = xdr_encode_bool(p, resp->p_no_trunc);
1396         p = xdr_encode_bool(p, resp->p_chown_restricted);
1397         p = xdr_encode_bool(p, resp->p_case_insensitive);
1398         xdr_encode_bool(p, resp->p_case_preserving);
1399
1400         return true;
1401 }
1402
1403 /* PATHCONF */
1404 int
1405 nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, __be32 *p)
1406 {
1407         struct xdr_stream *xdr = &rqstp->rq_res_stream;
1408         struct nfsd3_pathconfres *resp = rqstp->rq_resp;
1409
1410         if (!svcxdr_encode_nfsstat3(xdr, resp->status))
1411                 return 0;
1412         switch (resp->status) {
1413         case nfs_ok:
1414                 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh))
1415                         return 0;
1416                 if (!svcxdr_encode_pathconf3resok(xdr, resp))
1417                         return 0;
1418                 break;
1419         default:
1420                 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh))
1421                         return 0;
1422         }
1423
1424         return 1;
1425 }
1426
1427 /* COMMIT */
1428 int
1429 nfs3svc_encode_commitres(struct svc_rqst *rqstp, __be32 *p)
1430 {
1431         struct xdr_stream *xdr = &rqstp->rq_res_stream;
1432         struct nfsd3_commitres *resp = rqstp->rq_resp;
1433
1434         if (!svcxdr_encode_nfsstat3(xdr, resp->status))
1435                 return 0;
1436         switch (resp->status) {
1437         case nfs_ok:
1438                 if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh))
1439                         return 0;
1440                 if (!svcxdr_encode_writeverf3(xdr, resp->verf))
1441                         return 0;
1442                 break;
1443         default:
1444                 if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh))
1445                         return 0;
1446         }
1447
1448         return 1;
1449 }
1450
1451 /*
1452  * XDR release functions
1453  */
1454 void
1455 nfs3svc_release_fhandle(struct svc_rqst *rqstp)
1456 {
1457         struct nfsd3_attrstat *resp = rqstp->rq_resp;
1458
1459         fh_put(&resp->fh);
1460 }
1461
1462 void
1463 nfs3svc_release_fhandle2(struct svc_rqst *rqstp)
1464 {
1465         struct nfsd3_fhandle_pair *resp = rqstp->rq_resp;
1466
1467         fh_put(&resp->fh1);
1468         fh_put(&resp->fh2);
1469 }