2 * linux/fs/nfsd/nfs3xdr.c
4 * XDR support for nfsd/protocol version 3.
6 * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
9 #include <linux/types.h>
10 #include <linux/sched.h>
11 #include <linux/nfs3.h>
13 #include <linux/sunrpc/xdr.h>
14 #include <linux/sunrpc/svc.h>
15 #include <linux/nfsd/nfsd.h>
16 #include <linux/nfsd/xdr3.h>
18 #define NFSDDBG_FACILITY NFSDDBG_XDR
20 #ifdef NFSD_OPTIMIZE_SPACE
26 * Mapping of S_IF* types to NFS file types
28 static u32 nfs3_ftypes[] = {
29 NF3NON, NF3FIFO, NF3CHR, NF3BAD,
30 NF3DIR, NF3BAD, NF3BLK, NF3BAD,
31 NF3REG, NF3BAD, NF3LNK, NF3BAD,
32 NF3SOCK, NF3BAD, NF3LNK, NF3BAD,
36 * XDR functions for basic NFS types
39 encode_time3(u32 *p, time_t secs)
41 *p++ = htonl((u32) secs); *p++ = 0;
46 decode_time3(u32 *p, time_t *secp)
53 decode_fh(u32 *p, struct svc_fh *fhp)
56 fh_init(fhp, NFS3_FHSIZE);
58 if (size > NFS3_FHSIZE)
61 memcpy(&fhp->fh_handle.fh_base, p, size);
62 fhp->fh_handle.fh_size = size;
63 return p + XDR_QUADLEN(size);
67 encode_fh(u32 *p, struct svc_fh *fhp)
69 int size = fhp->fh_handle.fh_size;
71 if (size) p[XDR_QUADLEN(size)-1]=0;
72 memcpy(p, &fhp->fh_handle.fh_base, size);
73 return p + XDR_QUADLEN(size);
77 * Decode a file name and make sure that the path contains
78 * no slashes or null bytes.
81 decode_filename(u32 *p, char **namp, int *lenp)
86 if ((p = xdr_decode_string_inplace(p, namp, lenp, NFS3_MAXNAMLEN)) != NULL) {
87 for (i = 0, name = *namp; i < *lenp; i++, name++) {
88 if (*name == '\0' || *name == '/')
97 decode_pathname(u32 *p, char **namp, int *lenp)
102 if ((p = xdr_decode_string(p, namp, lenp, NFS3_MAXPATHLEN)) != NULL) {
103 for (i = 0, name = *namp; i < *lenp; i++, name++) {
113 decode_sattr3(u32 *p, struct iattr *iap)
120 iap->ia_valid |= ATTR_MODE;
121 iap->ia_mode = ntohl(*p++);
124 iap->ia_valid |= ATTR_UID;
125 iap->ia_uid = ntohl(*p++);
128 iap->ia_valid |= ATTR_GID;
129 iap->ia_gid = ntohl(*p++);
134 iap->ia_valid |= ATTR_SIZE;
135 p = xdr_decode_hyper(p, &newsize);
136 if (newsize <= NFS_OFFSET_MAX)
137 iap->ia_size = newsize;
139 iap->ia_size = NFS_OFFSET_MAX;
141 if ((tmp = ntohl(*p++)) == 1) { /* set to server time */
142 iap->ia_valid |= ATTR_ATIME;
143 } else if (tmp == 2) { /* set to client time */
144 iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET;
145 iap->ia_atime = ntohl(*p++), p++;
147 if ((tmp = ntohl(*p++)) == 1) { /* set to server time */
148 iap->ia_valid |= ATTR_MTIME;
149 } else if (tmp == 2) { /* set to client time */
150 iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET;
151 iap->ia_mtime = ntohl(*p++), p++;
157 encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
159 struct inode *inode = fhp->fh_dentry->d_inode;
161 *p++ = htonl(nfs3_ftypes[(inode->i_mode & S_IFMT) >> 12]);
162 *p++ = htonl((u32) inode->i_mode);
163 *p++ = htonl((u32) inode->i_nlink);
164 *p++ = htonl((u32) nfsd_ruid(rqstp, inode->i_uid));
165 *p++ = htonl((u32) nfsd_rgid(rqstp, inode->i_gid));
166 if (S_ISLNK(inode->i_mode) && inode->i_size > NFS3_MAXPATHLEN) {
167 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
169 p = xdr_encode_hyper(p, (u64) inode->i_size);
171 if (inode->i_blksize == 0 && inode->i_blocks == 0)
172 /* Minix file system(?) i_size is (hopefully) close enough */
173 p = xdr_encode_hyper(p, (u64)(inode->i_size +511)& ~511);
175 p = xdr_encode_hyper(p, ((u64)inode->i_blocks) << 9);
176 *p++ = htonl((u32) MAJOR(inode->i_rdev));
177 *p++ = htonl((u32) MINOR(inode->i_rdev));
178 if (rqstp->rq_reffh->fh_version == 1
179 && rqstp->rq_reffh->fh_fsid_type == 1
180 && (fhp->fh_export->ex_flags & NFSEXP_FSID))
181 p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
183 p = xdr_encode_hyper(p, (u64) inode->i_dev);
184 p = xdr_encode_hyper(p, (u64) inode->i_ino);
185 p = encode_time3(p, inode->i_atime);
186 p = encode_time3(p, lease_get_mtime(inode));
187 p = encode_time3(p, inode->i_ctime);
193 encode_saved_post_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
195 struct inode *inode = fhp->fh_dentry->d_inode;
197 /* Attributes to follow */
200 *p++ = htonl(nfs3_ftypes[(fhp->fh_post_mode & S_IFMT) >> 12]);
201 *p++ = htonl((u32) fhp->fh_post_mode);
202 *p++ = htonl((u32) fhp->fh_post_nlink);
203 *p++ = htonl((u32) nfsd_ruid(rqstp, fhp->fh_post_uid));
204 *p++ = htonl((u32) nfsd_rgid(rqstp, fhp->fh_post_gid));
205 if (S_ISLNK(fhp->fh_post_mode) && fhp->fh_post_size > NFS3_MAXPATHLEN) {
206 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
208 p = xdr_encode_hyper(p, (u64) fhp->fh_post_size);
210 p = xdr_encode_hyper(p, ((u64)fhp->fh_post_blocks) << 9);
211 *p++ = htonl((u32) MAJOR(fhp->fh_post_rdev));
212 *p++ = htonl((u32) MINOR(fhp->fh_post_rdev));
213 if (rqstp->rq_reffh->fh_version == 1
214 && rqstp->rq_reffh->fh_fsid_type == 1
215 && (fhp->fh_export->ex_flags & NFSEXP_FSID))
216 p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
218 p = xdr_encode_hyper(p, (u64) inode->i_dev);
219 p = xdr_encode_hyper(p, (u64) inode->i_ino);
220 p = encode_time3(p, fhp->fh_post_atime);
221 p = encode_time3(p, fhp->fh_post_mtime);
222 p = encode_time3(p, fhp->fh_post_ctime);
228 * Encode post-operation attributes.
229 * The inode may be NULL if the call failed because of a stale file
230 * handle. In this case, no attributes are returned.
233 encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
235 struct dentry *dentry = fhp->fh_dentry;
236 if (dentry && dentry->d_inode != NULL) {
237 *p++ = xdr_one; /* attributes follow */
238 return encode_fattr3(rqstp, p, fhp);
245 * Enocde weak cache consistency data
248 encode_wcc_data(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
250 struct dentry *dentry = fhp->fh_dentry;
252 if (dentry && dentry->d_inode && fhp->fh_post_saved) {
253 if (fhp->fh_pre_saved) {
255 p = xdr_encode_hyper(p, (u64) fhp->fh_pre_size);
256 p = encode_time3(p, fhp->fh_pre_mtime);
257 p = encode_time3(p, fhp->fh_pre_ctime);
261 return encode_saved_post_attr(rqstp, p, fhp);
263 /* no pre- or post-attrs */
265 return encode_post_op_attr(rqstp, p, fhp);
269 * Check buffer bounds after decoding arguments
272 xdr_argsize_check(struct svc_rqst *rqstp, u32 *p)
274 struct svc_buf *buf = &rqstp->rq_argbuf;
276 return p - buf->base <= buf->buflen;
280 xdr_ressize_check(struct svc_rqst *rqstp, u32 *p)
282 struct svc_buf *buf = &rqstp->rq_resbuf;
284 buf->len = p - buf->base;
285 dprintk("nfsd: ressize_check p %p base %p len %d\n",
286 p, buf->base, buf->buflen);
287 return (buf->len <= buf->buflen);
291 * XDR decode functions
294 nfs3svc_decode_fhandle(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
296 if (!(p = decode_fh(p, fhp)))
298 return xdr_argsize_check(rqstp, p);
302 nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, u32 *p,
303 struct nfsd3_sattrargs *args)
305 if (!(p = decode_fh(p, &args->fh))
306 || !(p = decode_sattr3(p, &args->attrs)))
309 if ((args->check_guard = ntohl(*p++)) != 0)
310 p = decode_time3(p, &args->guardtime);
312 return xdr_argsize_check(rqstp, p);
316 nfs3svc_decode_diropargs(struct svc_rqst *rqstp, u32 *p,
317 struct nfsd3_diropargs *args)
319 if (!(p = decode_fh(p, &args->fh))
320 || !(p = decode_filename(p, &args->name, &args->len)))
323 return xdr_argsize_check(rqstp, p);
327 nfs3svc_decode_accessargs(struct svc_rqst *rqstp, u32 *p,
328 struct nfsd3_accessargs *args)
330 if (!(p = decode_fh(p, &args->fh)))
332 args->access = ntohl(*p++);
334 return xdr_argsize_check(rqstp, p);
338 nfs3svc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
339 struct nfsd3_readargs *args)
341 if (!(p = decode_fh(p, &args->fh))
342 || !(p = xdr_decode_hyper(p, &args->offset)))
345 args->count = ntohl(*p++);
346 return xdr_argsize_check(rqstp, p);
350 nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
351 struct nfsd3_writeargs *args)
353 if (!(p = decode_fh(p, &args->fh))
354 || !(p = xdr_decode_hyper(p, &args->offset)))
357 args->count = ntohl(*p++);
358 args->stable = ntohl(*p++);
359 args->len = ntohl(*p++);
360 args->data = (char *) p;
361 p += XDR_QUADLEN(args->len);
363 return xdr_argsize_check(rqstp, p);
367 nfs3svc_decode_createargs(struct svc_rqst *rqstp, u32 *p,
368 struct nfsd3_createargs *args)
370 if (!(p = decode_fh(p, &args->fh))
371 || !(p = decode_filename(p, &args->name, &args->len)))
374 switch (args->createmode = ntohl(*p++)) {
375 case NFS3_CREATE_UNCHECKED:
376 case NFS3_CREATE_GUARDED:
377 if (!(p = decode_sattr3(p, &args->attrs)))
380 case NFS3_CREATE_EXCLUSIVE:
388 return xdr_argsize_check(rqstp, p);
391 nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, u32 *p,
392 struct nfsd3_createargs *args)
394 if (!(p = decode_fh(p, &args->fh))
395 || !(p = decode_filename(p, &args->name, &args->len))
396 || !(p = decode_sattr3(p, &args->attrs)))
399 return xdr_argsize_check(rqstp, p);
403 nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, u32 *p,
404 struct nfsd3_symlinkargs *args)
406 if (!(p = decode_fh(p, &args->ffh))
407 || !(p = decode_filename(p, &args->fname, &args->flen))
408 || !(p = decode_sattr3(p, &args->attrs))
409 || !(p = decode_pathname(p, &args->tname, &args->tlen)))
412 return xdr_argsize_check(rqstp, p);
416 nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, u32 *p,
417 struct nfsd3_mknodargs *args)
419 if (!(p = decode_fh(p, &args->fh))
420 || !(p = decode_filename(p, &args->name, &args->len)))
423 args->ftype = ntohl(*p++);
425 if (args->ftype == NF3BLK || args->ftype == NF3CHR
426 || args->ftype == NF3SOCK || args->ftype == NF3FIFO) {
427 if (!(p = decode_sattr3(p, &args->attrs)))
431 if (args->ftype == NF3BLK || args->ftype == NF3CHR) {
432 args->major = ntohl(*p++);
433 args->minor = ntohl(*p++);
436 return xdr_argsize_check(rqstp, p);
440 nfs3svc_decode_renameargs(struct svc_rqst *rqstp, u32 *p,
441 struct nfsd3_renameargs *args)
443 if (!(p = decode_fh(p, &args->ffh))
444 || !(p = decode_filename(p, &args->fname, &args->flen))
445 || !(p = decode_fh(p, &args->tfh))
446 || !(p = decode_filename(p, &args->tname, &args->tlen)))
449 return xdr_argsize_check(rqstp, p);
453 nfs3svc_decode_linkargs(struct svc_rqst *rqstp, u32 *p,
454 struct nfsd3_linkargs *args)
456 if (!(p = decode_fh(p, &args->ffh))
457 || !(p = decode_fh(p, &args->tfh))
458 || !(p = decode_filename(p, &args->tname, &args->tlen)))
461 return xdr_argsize_check(rqstp, p);
465 nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, u32 *p,
466 struct nfsd3_readdirargs *args)
468 if (!(p = decode_fh(p, &args->fh)))
470 p = xdr_decode_hyper(p, &args->cookie);
471 args->verf = p; p += 2;
473 args->count = ntohl(*p++);
475 return xdr_argsize_check(rqstp, p);
479 nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, u32 *p,
480 struct nfsd3_readdirargs *args)
482 if (!(p = decode_fh(p, &args->fh)))
484 p = xdr_decode_hyper(p, &args->cookie);
485 args->verf = p; p += 2;
486 args->dircount = ntohl(*p++);
487 args->count = ntohl(*p++);
489 return xdr_argsize_check(rqstp, p);
493 nfs3svc_decode_commitargs(struct svc_rqst *rqstp, u32 *p,
494 struct nfsd3_commitargs *args)
496 if (!(p = decode_fh(p, &args->fh)))
498 p = xdr_decode_hyper(p, &args->offset);
499 args->count = ntohl(*p++);
501 return xdr_argsize_check(rqstp, p);
505 * XDR encode functions
508 * There must be an encoding function for void results so svc_process
509 * will work properly.
512 nfs3svc_encode_voidres(struct svc_rqst *rqstp, u32 *p, void *dummy)
514 return xdr_ressize_check(rqstp, p);
519 nfs3svc_encode_attrstat(struct svc_rqst *rqstp, u32 *p,
520 struct nfsd3_attrstat *resp)
522 if (resp->status == 0)
523 p = encode_fattr3(rqstp, p, &resp->fh);
524 return xdr_ressize_check(rqstp, p);
527 /* SETATTR, REMOVE, RMDIR */
529 nfs3svc_encode_wccstat(struct svc_rqst *rqstp, u32 *p,
530 struct nfsd3_attrstat *resp)
532 p = encode_wcc_data(rqstp, p, &resp->fh);
533 return xdr_ressize_check(rqstp, p);
538 nfs3svc_encode_diropres(struct svc_rqst *rqstp, u32 *p,
539 struct nfsd3_diropres *resp)
541 if (resp->status == 0) {
542 p = encode_fh(p, &resp->fh);
543 p = encode_post_op_attr(rqstp, p, &resp->fh);
545 p = encode_post_op_attr(rqstp, p, &resp->dirfh);
546 return xdr_ressize_check(rqstp, p);
551 nfs3svc_encode_accessres(struct svc_rqst *rqstp, u32 *p,
552 struct nfsd3_accessres *resp)
554 p = encode_post_op_attr(rqstp, p, &resp->fh);
555 if (resp->status == 0)
556 *p++ = htonl(resp->access);
557 return xdr_ressize_check(rqstp, p);
562 nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p,
563 struct nfsd3_readlinkres *resp)
565 p = encode_post_op_attr(rqstp, p, &resp->fh);
566 if (resp->status == 0) {
567 *p++ = htonl(resp->len);
568 p += XDR_QUADLEN(resp->len);
570 return xdr_ressize_check(rqstp, p);
575 nfs3svc_encode_readres(struct svc_rqst *rqstp, u32 *p,
576 struct nfsd3_readres *resp)
578 p = encode_post_op_attr(rqstp, p, &resp->fh);
579 if (resp->status == 0) {
580 *p++ = htonl(resp->count);
581 *p++ = htonl(resp->eof);
582 *p++ = htonl(resp->count); /* xdr opaque count */
583 p += XDR_QUADLEN(resp->count);
585 return xdr_ressize_check(rqstp, p);
590 nfs3svc_encode_writeres(struct svc_rqst *rqstp, u32 *p,
591 struct nfsd3_writeres *resp)
593 p = encode_wcc_data(rqstp, p, &resp->fh);
594 if (resp->status == 0) {
595 *p++ = htonl(resp->count);
596 *p++ = htonl(resp->committed);
597 *p++ = htonl(nfssvc_boot.tv_sec);
598 *p++ = htonl(nfssvc_boot.tv_usec);
600 return xdr_ressize_check(rqstp, p);
603 /* CREATE, MKDIR, SYMLINK, MKNOD */
605 nfs3svc_encode_createres(struct svc_rqst *rqstp, u32 *p,
606 struct nfsd3_diropres *resp)
608 if (resp->status == 0) {
610 p = encode_fh(p, &resp->fh);
611 p = encode_post_op_attr(rqstp, p, &resp->fh);
613 p = encode_wcc_data(rqstp, p, &resp->dirfh);
614 return xdr_ressize_check(rqstp, p);
619 nfs3svc_encode_renameres(struct svc_rqst *rqstp, u32 *p,
620 struct nfsd3_renameres *resp)
622 p = encode_wcc_data(rqstp, p, &resp->ffh);
623 p = encode_wcc_data(rqstp, p, &resp->tfh);
624 return xdr_ressize_check(rqstp, p);
629 nfs3svc_encode_linkres(struct svc_rqst *rqstp, u32 *p,
630 struct nfsd3_linkres *resp)
632 p = encode_post_op_attr(rqstp, p, &resp->fh);
633 p = encode_wcc_data(rqstp, p, &resp->tfh);
634 return xdr_ressize_check(rqstp, p);
639 nfs3svc_encode_readdirres(struct svc_rqst *rqstp, u32 *p,
640 struct nfsd3_readdirres *resp)
642 p = encode_post_op_attr(rqstp, p, &resp->fh);
643 if (resp->status == 0) {
644 /* stupid readdir cookie */
645 memcpy(p, resp->verf, 8); p += 2;
646 p += XDR_QUADLEN(resp->count);
649 return xdr_ressize_check(rqstp, p);
653 * Encode a directory entry. This one works for both normal readdir
655 * The normal readdir reply requires 2 (fileid) + 1 (stringlen)
656 * + string + 2 (cookie) + 1 (next) words, i.e. 6 + strlen.
658 * The readdirplus baggage is 1+21 words for post_op_attr, plus the
662 #define NFS3_ENTRY_BAGGAGE (2 + 1 + 2 + 1)
663 #define NFS3_ENTRYPLUS_BAGGAGE (1 + 21 + 1 + (NFS3_FHSIZE >> 2))
665 encode_entry(struct readdir_cd *cd, const char *name,
666 int namlen, off_t offset, ino_t ino, unsigned int d_type, int plus)
669 int buflen, slen, elen;
672 xdr_encode_hyper(cd->offset, (u64) offset);
674 /* nfsd_readdir calls us with name == 0 when it wants us to
675 * set the last offset entry. */
680 dprintk("encode_entry(%.*s @%ld%s)\n",
681 namlen, name, (long) offset, plus? " plus" : "");
684 /* truncate filename if too long */
685 if (namlen > NFS3_MAXNAMLEN)
686 namlen = NFS3_MAXNAMLEN;
688 slen = XDR_QUADLEN(namlen);
689 elen = slen + NFS3_ENTRY_BAGGAGE
690 + (plus? NFS3_ENTRYPLUS_BAGGAGE : 0);
691 if ((buflen = cd->buflen - elen) < 0) {
695 *p++ = xdr_one; /* mark entry present */
696 p = xdr_encode_hyper(p, ino); /* file id */
697 p = xdr_encode_array(p, name, namlen);/* name length & name */
699 cd->offset = p; /* remember pointer */
700 p = xdr_encode_hyper(p, NFS_OFFSET_MAX); /* offset of next entry */
702 /* throw in readdirplus baggage */
705 struct svc_export *exp;
706 struct dentry *dparent, *dchild;
708 dparent = cd->dirfh->fh_dentry;
709 exp = cd->dirfh->fh_export;
711 fh_init(&fh, NFS3_FHSIZE);
712 if (isdotent(name, namlen)) {
715 dchild = dchild->d_parent;
716 dchild = dget(dchild);
718 dchild = lookup_one_len(name, dparent,namlen);
721 if (fh_compose(&fh, exp, dchild, cd->dirfh) != 0 || !dchild->d_inode)
723 p = encode_post_op_attr(cd->rqstp, p, &fh);
724 *p++ = xdr_one; /* yes, a file handle follows */
725 p = encode_fh(p, &fh);
741 nfs3svc_encode_entry(struct readdir_cd *cd, const char *name,
742 int namlen, loff_t offset, ino_t ino, unsigned int d_type)
744 return encode_entry(cd, name, namlen, offset, ino, d_type, 0);
748 nfs3svc_encode_entry_plus(struct readdir_cd *cd, const char *name,
749 int namlen, loff_t offset, ino_t ino, unsigned int d_type)
751 return encode_entry(cd, name, namlen, offset, ino, d_type, 1);
756 nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, u32 *p,
757 struct nfsd3_fsstatres *resp)
759 struct statfs *s = &resp->stats;
762 *p++ = xdr_zero; /* no post_op_attr */
764 if (resp->status == 0) {
765 p = xdr_encode_hyper(p, bs * s->f_blocks); /* total bytes */
766 p = xdr_encode_hyper(p, bs * s->f_bfree); /* free bytes */
767 p = xdr_encode_hyper(p, bs * s->f_bavail); /* user available bytes */
768 p = xdr_encode_hyper(p, s->f_files); /* total inodes */
769 p = xdr_encode_hyper(p, s->f_ffree); /* free inodes */
770 p = xdr_encode_hyper(p, s->f_ffree); /* user available inodes */
771 *p++ = htonl(resp->invarsec); /* mean unchanged time */
773 return xdr_ressize_check(rqstp, p);
778 nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, u32 *p,
779 struct nfsd3_fsinfores *resp)
781 *p++ = xdr_zero; /* no post_op_attr */
783 if (resp->status == 0) {
784 *p++ = htonl(resp->f_rtmax);
785 *p++ = htonl(resp->f_rtpref);
786 *p++ = htonl(resp->f_rtmult);
787 *p++ = htonl(resp->f_wtmax);
788 *p++ = htonl(resp->f_wtpref);
789 *p++ = htonl(resp->f_wtmult);
790 *p++ = htonl(resp->f_dtpref);
791 p = xdr_encode_hyper(p, resp->f_maxfilesize);
794 *p++ = htonl(resp->f_properties);
797 return xdr_ressize_check(rqstp, p);
802 nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, u32 *p,
803 struct nfsd3_pathconfres *resp)
805 *p++ = xdr_zero; /* no post_op_attr */
807 if (resp->status == 0) {
808 *p++ = htonl(resp->p_link_max);
809 *p++ = htonl(resp->p_name_max);
810 *p++ = htonl(resp->p_no_trunc);
811 *p++ = htonl(resp->p_chown_restricted);
812 *p++ = htonl(resp->p_case_insensitive);
813 *p++ = htonl(resp->p_case_preserving);
816 return xdr_ressize_check(rqstp, p);
821 nfs3svc_encode_commitres(struct svc_rqst *rqstp, u32 *p,
822 struct nfsd3_commitres *resp)
824 p = encode_wcc_data(rqstp, p, &resp->fh);
826 if (resp->status == 0) {
827 *p++ = htonl(nfssvc_boot.tv_sec);
828 *p++ = htonl(nfssvc_boot.tv_usec);
830 return xdr_ressize_check(rqstp, p);
834 * XDR release functions
837 nfs3svc_release_fhandle(struct svc_rqst *rqstp, u32 *p,
838 struct nfsd3_attrstat *resp)
845 nfs3svc_release_fhandle2(struct svc_rqst *rqstp, u32 *p,
846 struct nfsd3_fhandle_pair *resp)