2 * linux/fs/nfsd/nfs3xdr.c
4 * XDR support for nfsd/protocol version 3.
6 * Copyright (C) 1995, 1996 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 u32 nfs_ok
, nfserr_perm
, nfserr_noent
, nfserr_io
, nfserr_nxio
,
21 nfserr_acces
, nfserr_exist
, nfserr_nodev
, nfserr_notdir
,
22 nfserr_isdir
, nfserr_fbig
, nfserr_nospc
, nfserr_rofs
,
23 nfserr_nametoolong
, nfserr_dquot
, nfserr_stale
;
25 #ifdef NFSD_OPTIMIZE_SPACE
30 * Mapping of S_IF* types to NFS file types
32 static u32 nfs3_ftypes
[] = {
33 NF3NON
, NF3FIFO
, NF3CHR
, NF3BAD
,
34 NF3DIR
, NF3BAD
, NF3BLK
, NF3BAD
,
35 NF3REG
, NF3BAD
, NF3LNK
, NF3BAD
,
36 NF3SOCK
, NF3BAD
, NF3LNK
, NF3BAD
,
40 * Initialization of NFS status variables
45 static int inited
= 0;
50 nfs_ok
= htonl(NFS_OK
);
51 nfserr_perm
= htonl(NFSERR_PERM
);
52 nfserr_noent
= htonl(NFSERR_NOENT
);
53 nfserr_io
= htonl(NFSERR_IO
);
54 nfserr_nxio
= htonl(NFSERR_NXIO
);
55 nfserr_acces
= htonl(NFSERR_ACCES
);
56 nfserr_exist
= htonl(NFSERR_EXIST
);
57 nfserr_nodev
= htonl(NFSERR_NODEV
);
58 nfserr_notdir
= htonl(NFSERR_NOTDIR
);
59 nfserr_isdir
= htonl(NFSERR_ISDIR
);
60 nfserr_fbig
= htonl(NFSERR_FBIG
);
61 nfserr_nospc
= htonl(NFSERR_NOSPC
);
62 nfserr_rofs
= htonl(NFSERR_ROFS
);
63 nfserr_nametoolong
= htonl(NFSERR_NAMETOOLONG
);
64 nfserr_dquot
= htonl(NFSERR_DQUOT
);
65 nfserr_stale
= htonl(NFSERR_STALE
);
71 * XDR functions for basic NFS types
74 enc64(u32
*p
, u64 val
)
77 *p
++ = (val
& 0xffffffff);
82 dec64(u32
*p
, u64
*valp
)
84 *valp
= ((u64
) ntohl(*p
++)) << 32;
90 encode_time3(u32
*p
, time_t secs
)
92 *p
++ = htonl((u32
) secs
); *p
++ = 0;
97 decode_time3(u32
*p
, time_t *secp
)
104 decode_fh(u32
*p
, struct svc_fh
*fhp
)
106 if (*p
++ != sizeof(struct knfs_fh
))
109 memcpy(&fhp
->fh_handle
, p
, sizeof(struct knfs_fh
));
110 fhp
->fh_inode
= NULL
;
111 fhp
->fh_export
= NULL
;
113 return p
+ (sizeof(struct knfs_fh
) >> 2);
117 encode_fh(u32
*p
, struct svc_fh
*fhp
)
119 *p
++ = htonl(sizeof(struct knfs_fh
));
120 memcpy(p
, &fhp
->fh_handle
, sizeof(struct knfs_fh
));
121 return p
+ (sizeof(struct knfs_fh
) >> 2);
125 * Decode a file name and make sure that the path contains
126 * no slashes or null bytes.
129 decode_filename(u32
*p
, char **namp
, int *lenp
)
134 if ((p
= xdr_decode_string(p
, namp
, lenp
, NFS3_MAXNAMLEN
)) != NULL
) {
135 for (i
= 0, name
= *namp
; i
< *lenp
; i
++, name
++) {
136 if (*name
== '\0' || *name
== '/')
146 decode_pathname(u32
*p
, char **namp
, int *lenp
)
151 if ((p
= xdr_decode_string(p
, namp
, lenp
, NFS3_MAXPATHLEN
)) != NULL
) {
152 for (i
= 0, name
= *namp
; i
< *lenp
; i
++, name
++) {
163 decode_sattr3(u32
*p
, struct iattr
*iap
)
170 iap
->ia_valid
|= ATTR_MODE
;
171 iap
->ia_mode
= ntohl(*p
++);
174 iap
->ia_valid
|= ATTR_UID
;
175 iap
->ia_uid
= ntohl(*p
++);
178 iap
->ia_valid
|= ATTR_GID
;
179 iap
->ia_gid
= ntohl(*p
++);
182 iap
->ia_valid
|= ATTR_SIZE
;
183 iap
->ia_size
= ntohl(*p
++);
185 if ((tmp
= *p
++) == 1) {
186 iap
->ia_valid
|= ATTR_ATIME
;
187 } else if (tmp
== 2) {
188 iap
->ia_valid
|= ATTR_ATIME
| ATTR_ATIME_SET
;
189 iap
->ia_atime
= ntohl(*p
++), p
++;
191 if ((tmp
= *p
++) != 0) {
192 iap
->ia_valid
|= ATTR_MTIME
| ATTR_MTIME_SET
;
193 } else if (tmp
== 2) {
194 iap
->ia_valid
|= ATTR_MTIME
;
195 iap
->ia_mtime
= ntohl(*p
++), p
++;
201 encode_fattr3(struct svc_rqst
*rqstp
, u32
*p
, struct inode
*inode
)
204 printk("nfsd: NULL inode in %s:%d", __FILE__
, __LINE__
);
208 *p
++ = htonl(nfs3_ftypes
[(inode
->i_mode
& S_IFMT
) >> 12]);
209 *p
++ = htonl((u32
) inode
->i_mode
);
210 *p
++ = htonl((u32
) inode
->i_nlink
);
211 *p
++ = htonl((u32
) nfsd_ruid(rqstp
, inode
->i_uid
));
212 *p
++ = htonl((u32
) nfsd_rgid(rqstp
, inode
->i_gid
));
213 if (S_ISLNK(inode
->i_mode
) && inode
->i_size
> NFS3_MAXPATHLEN
) {
214 p
= enc64(p
, (u64
) NFS3_MAXPATHLEN
);
216 p
= enc64(p
, (u64
) inode
->i_size
);
218 p
= enc64(p
, inode
->i_blksize
* inode
->i_blocks
);
219 *p
++ = htonl((u32
) MAJOR(inode
->i_rdev
));
220 *p
++ = htonl((u32
) MINOR(inode
->i_rdev
));
221 p
= enc64(p
, (u64
) inode
->i_dev
);
222 p
= enc64(p
, (u64
) inode
->i_ino
);
223 p
= encode_time3(p
, inode
->i_atime
);
224 p
= encode_time3(p
, inode
->i_mtime
);
225 p
= encode_time3(p
, inode
->i_ctime
);
231 * Encode post-operation attributes.
232 * The inode may be NULL if the call failed because of a stale file
233 * handle. In this case, no attributes are returned.
236 encode_post_op_attr(struct svc_rqst
*rqstp
, u32
*p
, struct inode
*inode
)
242 return encode_fattr3(rqstp
, p
, inode
);
246 * Enocde weak cache consistency data
249 encode_wcc_data(struct svc_rqst
*rqstp
, u32
*p
, struct svc_fh
*fhp
)
251 struct inode
*inode
= fhp
->fh_inode
;
253 if (fhp
->fh_post_version
== inode
->i_version
) {
255 p
= enc64(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_post_op_attr(rqstp
, p
, inode
);
265 * Check buffer bounds after decoding arguments
268 xdr_argsize_check(struct svc_rqst
*rqstp
, u32
*p
)
270 struct svc_buf
*buf
= &rqstp
->rq_argbuf
;
272 return p
- buf
->base
<= buf
->buflen
;
276 xdr_ressize_check(struct svc_rqst
*rqstp
, u32
*p
)
278 struct svc_buf
*buf
= &rqstp
->rq_resbuf
;
280 buf
->len
= p
- buf
->base
;
281 dprintk("nfsd: ressize_check p %p base %p len %d\n",
282 p
, buf
->base
, buf
->buflen
);
283 return (buf
->len
<= buf
->buflen
);
287 * XDR decode functions
290 nfs3svc_decode_fhandle(struct svc_rqst
*rqstp
, u32
*p
, struct svc_fh
*fhp
)
292 if (!(p
= decode_fh(p
, fhp
)))
294 return xdr_argsize_check(rqstp
, p
);
298 nfs3svc_decode_sattrargs(struct svc_rqst
*rqstp
, u32
*p
,
299 struct nfsd3_sattrargs
*args
)
301 if (!(p
= decode_fh(p
, &args
->fh
))
302 || !(p
= decode_sattr3(p
, &args
->attrs
))
303 || (*p
++ && !(p
= decode_time3(p
, &args
->guardtime
))))
306 return xdr_argsize_check(rqstp
, p
);
310 nfs3svc_decode_diropargs(struct svc_rqst
*rqstp
, u32
*p
,
311 struct nfsd3_diropargs
*args
)
313 if (!(p
= decode_fh(p
, &args
->fh
))
314 || !(p
= decode_filename(p
, &args
->name
, &args
->len
)))
317 return xdr_argsize_check(rqstp
, p
);
321 nfs3svc_decode_accessargs(struct svc_rqst
*rqstp
, u32
*p
,
322 struct nfsd3_accessargs
*args
)
324 if (!(p
= decode_fh(p
, &args
->fh
)))
326 args
->access
= ntohl(*p
++);
328 return xdr_argsize_check(rqstp
, p
);
332 nfs3svc_decode_readargs(struct svc_rqst
*rqstp
, u32
*p
,
333 struct nfsd3_readargs
*args
)
335 if (!(p
= decode_fh(p
, &args
->fh
))
336 || !(p
= dec64(p
, &args
->offset
))
337 || !(p
= dec64(p
, &args
->count
)))
340 return xdr_argsize_check(rqstp
, p
);
344 nfs3svc_decode_writeargs(struct svc_rqst
*rqstp
, u32
*p
,
345 struct nfsd3_writeargs
*args
)
347 if (!(p
= decode_fh(p
, &args
->fh
))
348 || !(p
= dec64(p
, &args
->offset
))
349 || !(p
= dec64(p
, &args
->count
)))
352 args
->stable
= ntohl(*p
++);
353 args
->len
= ntohl(*p
++);
354 args
->data
= (char *) p
;
355 p
+= (args
->len
+ 3) >> 2;
357 return xdr_argsize_check(rqstp
, p
);
361 nfs3svc_decode_createargs(struct svc_rqst
*rqstp
, u32
*p
,
362 struct nfsd3_createargs
*args
)
364 if (!(p
= decode_fh(p
, &args
->fh
))
365 || !(p
= decode_filename(p
, &args
->name
, &args
->len
)))
368 switch (args
->createmode
= ntohl(*p
++)) {
370 if (!(p
= decode_sattr3(p
, &args
->attrs
)))
381 return xdr_argsize_check(rqstp
, p
);
384 nfs3svc_decode_mkdirargs(struct svc_rqst
*rqstp
, u32
*p
,
385 struct nfsd3_createargs
*args
)
387 if (!(p
= decode_fh(p
, &args
->fh
))
388 || !(p
= decode_filename(p
, &args
->name
, &args
->len
))
389 || !(p
= decode_sattr3(p
, &args
->attrs
)))
392 return xdr_argsize_check(rqstp
, p
);
396 nfs3svc_decode_symlinkargs(struct svc_rqst
*rqstp
, u32
*p
,
397 struct nfsd3_symlinkargs
*args
)
399 if (!(p
= decode_fh(p
, &args
->ffh
))
400 || !(p
= decode_filename(p
, &args
->fname
, &args
->flen
))
401 || !(p
= decode_sattr3(p
, &args
->attrs
))
402 || !(p
= decode_pathname(p
, &args
->tname
, &args
->tlen
)))
405 return xdr_argsize_check(rqstp
, p
);
409 nfs3svc_decode_mknodargs(struct svc_rqst
*rqstp
, u32
*p
,
410 struct nfsd3_mknodargs
*args
)
412 if (!(p
= decode_fh(p
, &args
->fh
))
413 || !(p
= decode_filename(p
, &args
->name
, &args
->len
)))
416 args
->ftype
= ntohl(*p
++);
418 if (args
->ftype
== NF3BLK
|| args
->ftype
== NF3CHR
419 || args
->ftype
== NF3SOCK
|| args
->ftype
== NF3FIFO
) {
420 if (!(p
= decode_sattr3(p
, &args
->attrs
)))
424 if (args
->ftype
== NF3BLK
|| args
->ftype
== NF3CHR
) {
425 args
->major
= ntohl(*p
++);
426 args
->minor
= ntohl(*p
++);
429 return xdr_argsize_check(rqstp
, p
);
433 nfs3svc_decode_renameargs(struct svc_rqst
*rqstp
, u32
*p
,
434 struct nfsd3_renameargs
*args
)
436 if (!(p
= decode_fh(p
, &args
->ffh
))
437 || !(p
= decode_filename(p
, &args
->fname
, &args
->flen
))
438 || !(p
= decode_fh(p
, &args
->tfh
))
439 || !(p
= decode_filename(p
, &args
->tname
, &args
->tlen
)))
442 return xdr_argsize_check(rqstp
, p
);
446 nfs3svc_decode_linkargs(struct svc_rqst
*rqstp
, u32
*p
,
447 struct nfsd3_linkargs
*args
)
449 if (!(p
= decode_fh(p
, &args
->ffh
))
450 || !(p
= decode_fh(p
, &args
->tfh
))
451 || !(p
= decode_filename(p
, &args
->tname
, &args
->tlen
)))
454 return xdr_argsize_check(rqstp
, p
);
458 nfs3svc_decode_readdirargs(struct svc_rqst
*rqstp
, u32
*p
,
459 struct nfsd3_readdirargs
*args
)
461 if (!(p
= decode_fh(p
, &args
->fh
)))
463 args
->cookie
= ntohl(*p
++);
464 args
->verf
= p
; p
+= 2;
465 args
->count
= ntohl(*p
++);
467 return xdr_argsize_check(rqstp
, p
);
471 nfs3svc_decode_readdirplusargs(struct svc_rqst
*rqstp
, u32
*p
,
472 struct nfsd3_readdirargs
*args
)
474 if (!(p
= decode_fh(p
, &args
->fh
)))
476 args
->cookie
= ntohl(*p
++);
477 args
->verf
= p
; p
+= 2;
478 args
->dircount
= ntohl(*p
++);
479 args
->count
= ntohl(*p
++);
481 return xdr_argsize_check(rqstp
, p
);
485 nfs3svc_decode_commitargs(struct svc_rqst
*rqstp
, u32
*p
,
486 struct nfsd3_commitargs
*args
)
488 if (!(p
= decode_fh(p
, &args
->fh
))
489 || !(p
= dec64(p
, &args
->offset
)))
491 args
->count
= ntohl(*p
++);
493 return xdr_argsize_check(rqstp
, p
);
497 * XDR encode functions
501 nfs3svc_encode_attrstat(struct svc_rqst
*rqstp
, u32
*p
,
502 struct nfsd3_attrstat
*resp
)
504 if (!(p
= encode_fattr3(rqstp
, p
, resp
->fh
.fh_inode
)))
506 return xdr_ressize_check(rqstp
, p
);
509 /* SETATTR, REMOVE, RMDIR */
511 nfs3svc_encode_wccstat(struct svc_rqst
*rqstp
, u32
*p
,
512 struct nfsd3_attrstat
*resp
)
514 if (!(p
= encode_wcc_data(rqstp
, p
, &resp
->fh
)))
516 return xdr_ressize_check(rqstp
, p
);
521 nfs3svc_encode_lookupres(struct svc_rqst
*rqstp
, u32
*p
,
522 struct nfsd3_lookupres
*resp
)
524 if (resp
->status
== 0) {
525 p
= encode_fh(p
, &resp
->fh
);
526 if (!(p
= encode_fattr3(rqstp
, p
, resp
->fh
.fh_inode
)))
529 p
= encode_post_op_attr(rqstp
, p
, resp
->dirfh
.fh_inode
);
530 return xdr_ressize_check(rqstp
, p
);
535 nfs3svc_encode_accessres(struct svc_rqst
*rqstp
, u32
*p
,
536 struct nfsd3_accessres
*resp
)
538 p
= encode_post_op_attr(rqstp
, p
, resp
->fh
.fh_inode
);
539 if (resp
->status
== 0)
540 *p
++ = htonl(resp
->access
);
541 return xdr_ressize_check(rqstp
, p
);
546 nfs3svc_encode_readlinkres(struct svc_rqst
*rqstp
, u32
*p
,
547 struct nfsd3_readlinkres
*resp
)
549 p
= encode_post_op_attr(rqstp
, p
, resp
->fh
.fh_inode
);
550 if (resp
->status
== 0) {
551 *p
++ = htonl(resp
->len
);
552 p
+= XDR_QUADLEN(resp
->len
);
554 return xdr_ressize_check(rqstp
, p
);
559 nfs3svc_encode_readres(struct svc_rqst
*rqstp
, u32
*p
,
560 struct nfsd3_readres
*resp
)
562 p
= encode_post_op_attr(rqstp
, p
, resp
->fh
.fh_inode
);
563 if (resp
->status
== 0) {
564 *p
++ = htonl(resp
->count
);
565 *p
++ = htonl(resp
->eof
);
566 *p
++ = htonl(resp
->count
); /* xdr opaque count */
567 p
+= XDR_QUADLEN(resp
->count
);
569 return xdr_ressize_check(rqstp
, p
);
574 nfs3svc_encode_writeres(struct svc_rqst
*rqstp
, u32
*p
,
575 struct nfsd3_writeres
*resp
)
577 p
= encode_wcc_data(rqstp
, p
, &resp
->fh
);
578 if (resp
->status
== 0) {
579 *p
++ = htonl(resp
->count
);
580 *p
++ = htonl(resp
->committed
);
581 *p
++ = htonl(nfssvc_boot
.tv_sec
);
582 *p
++ = htonl(nfssvc_boot
.tv_usec
);
584 return xdr_ressize_check(rqstp
, p
);
587 /* CREATE, MKDIR, SYMLINK, MKNOD */
589 nfs3svc_encode_createres(struct svc_rqst
*rqstp
, u32
*p
,
590 struct nfsd3_createres
*resp
)
592 if (resp
->status
== 0) {
593 p
= encode_fh(p
, &resp
->fh
);
594 p
= encode_post_op_attr(rqstp
, p
, resp
->fh
.fh_inode
);
596 p
= encode_wcc_data(rqstp
, p
, &resp
->dirfh
);
597 return xdr_ressize_check(rqstp
, p
);
602 nfs3svc_encode_renameres(struct svc_rqst
*rqstp
, u32
*p
,
603 struct nfsd3_renameres
*resp
)
605 p
= encode_wcc_data(rqstp
, p
, &resp
->ffh
);
606 p
= encode_wcc_data(rqstp
, p
, &resp
->tfh
);
607 return xdr_ressize_check(rqstp
, p
);
612 nfs3svc_encode_linkres(struct svc_rqst
*rqstp
, u32
*p
,
613 struct nfsd3_linkres
*resp
)
615 p
= encode_post_op_attr(rqstp
, p
, resp
->fh
.fh_inode
);
616 p
= encode_wcc_data(rqstp
, p
, &resp
->tfh
);
617 return xdr_ressize_check(rqstp
, p
);
622 nfs3svc_encode_readdirres(struct svc_rqst
*rqstp
, u32
*p
,
623 struct nfsd3_readdirres
*resp
)
625 p
= encode_post_op_attr(rqstp
, p
, resp
->fh
.fh_inode
);
626 if (resp
->status
== 0) {
627 /* stupid readdir cookie */
628 *p
++ = ntohl(resp
->fh
.fh_inode
->i_mtime
);
633 return xdr_ressize_check(rqstp
, p
);
636 #define NFS3_ENTRYPLUS_BAGGAGE ((1 + 20 + 1 + NFS3_FHSIZE) << 2)
638 nfs3svc_encode_entry(struct readdir_cd
*cd
, const char *name
,
639 int namlen
, unsigned long offset
, ino_t ino
)
642 int buflen
, slen
, elen
;
645 if (offset
> ~((u64
) 0))
648 *cd
->offset
= htonl(offset
);
650 /* For readdirplus, look up the inode */
651 if (cd
->plus
&& nfsd_lookup(cd
->rqstp
, cd
->dirfh
, name
, namlen
, &fh
))
654 /* truncate filename if too long */
655 if (namlen
> NFS3_MAXNAMLEN
)
656 namlen
= NFS3_MAXNAMLEN
;
658 slen
= XDR_QUADLEN(namlen
);
659 elen
= slen
+ (cd
->plus
? NFS3_ENTRYPLUS_BAGGAGE
: 0);
660 if ((buflen
= cd
->buflen
- elen
- 4) < 0) {
666 *p
++ = xdr_one
; /* mark entry present */
667 *p
++ = xdr_zero
; /* file id (64 bit) */
668 *p
++ = htonl((u32
) ino
);
669 *p
++ = htonl((u32
) namlen
); /* name length & name */
670 memcpy(p
, name
, namlen
);
673 /* throw in readdirplus baggage */
675 p
= encode_post_op_attr(cd
->rqstp
, p
, fh
.fh_inode
);
676 p
= encode_fh(p
, &fh
);
680 cd
->offset
= p
; /* remember pointer */
681 p
= enc64(p
, ~(u64
) 0); /* offset of next entry */
690 nfs3svc_encode_statfsres(struct svc_rqst
*rqstp
, u32
*p
,
691 struct nfsd3_statfsres
*resp
)
693 struct statfs
*s
= &resp
->stats
;
696 *p
++ = xdr_zero
; /* no post_op_attr */
698 if (resp
->status
== 0) {
699 p
= enc64(p
, bs
* s
->f_blocks
); /* total bytes */
700 p
= enc64(p
, bs
* s
->f_bfree
); /* free bytes */
701 p
= enc64(p
, bs
* s
->f_bavail
); /* user available bytes */
702 p
= enc64(p
, s
->f_files
); /* total inodes */
703 p
= enc64(p
, s
->f_ffree
); /* free inodes */
704 p
= enc64(p
, s
->f_ffree
); /* user available inodes */
705 *p
++ = htonl(resp
->invarsec
); /* mean unchanged time */
707 return xdr_ressize_check(rqstp
, p
);
712 nfs3svc_encode_fsinfores(struct svc_rqst
*rqstp
, u32
*p
,
713 struct nfsd3_fsinfores
*resp
)
715 *p
++ = xdr_zero
; /* no post_op_attr */
717 if (resp
->status
== 0) {
718 *p
++ = htonl(resp
->f_rtmax
);
719 *p
++ = htonl(resp
->f_rtpref
);
720 *p
++ = htonl(resp
->f_rtmult
);
721 *p
++ = htonl(resp
->f_wtmax
);
722 *p
++ = htonl(resp
->f_wtpref
);
723 *p
++ = htonl(resp
->f_wtmult
);
724 *p
++ = htonl(resp
->f_dtpref
);
725 *p
++ = htonl(resp
->f_maxfilesize
);
727 *p
++ = htonl(1000000000 / HZ
);
728 *p
++ = htonl(resp
->f_properties
);
731 return xdr_ressize_check(rqstp
, p
);
736 nfs3svc_encode_pathconfres(struct svc_rqst
*rqstp
, u32
*p
,
737 struct nfsd3_pathconfres
*resp
)
739 *p
++ = xdr_zero
; /* no post_op_attr */
741 if (resp
->status
== 0) {
742 *p
++ = htonl(resp
->p_link_max
);
743 *p
++ = htonl(resp
->p_name_max
);
744 *p
++ = xdr_one
; /* always reject long file names */
745 *p
++ = xdr_one
; /* chown restricted */
746 *p
++ = htonl(resp
->p_case_insensitive
);
747 *p
++ = htonl(resp
->p_case_preserving
);
750 return xdr_ressize_check(rqstp
, p
);
755 nfs3svc_encode_commitres(struct svc_rqst
*rqstp
, u32
*p
,
756 struct nfsd3_commitres
*resp
)
758 p
= encode_wcc_data(rqstp
, p
, &resp
->fh
);
760 if (resp
->status
== 0) {
761 *p
++ = htonl(nfssvc_boot
.tv_sec
);
762 *p
++ = htonl(nfssvc_boot
.tv_usec
);
764 return xdr_ressize_check(rqstp
, p
);
768 * XDR release functions
771 nfs3svc_release_fhandle(struct svc_rqst
*rqstp
, u32
*p
,
772 struct nfsd_fhandle
*resp
)
779 nfs3svc_release_fhandle2(struct svc_rqst
*rqstp
, u32
*p
,
780 struct nfsd3_fhandle2
*resp
)