2 * linux/fs/nfs/nfs3xdr.c
4 * XDR functions to encode/decode NFSv3 RPC arguments and results.
6 * Copyright (C) 1996, 1997 Olaf Kirch
9 #include <linux/param.h>
10 #include <linux/time.h>
12 #include <linux/errno.h>
13 #include <linux/string.h>
15 #include <linux/pagemap.h>
16 #include <linux/proc_fs.h>
17 #include <linux/kdev_t.h>
18 #include <linux/sunrpc/clnt.h>
19 #include <linux/nfs.h>
20 #include <linux/nfs3.h>
21 #include <linux/nfs_fs.h>
22 #include <linux/nfsacl.h>
25 #define NFSDBG_FACILITY NFSDBG_XDR
27 /* Mapping from NFS error code to "errno" error code. */
28 #define errno_NFSERR_IO EIO
31 * Declare the space requirements for NFS arguments and replies as
32 * number of 32bit-words
34 #define NFS3_fhandle_sz (1+16)
35 #define NFS3_fh_sz (NFS3_fhandle_sz) /* shorthand */
36 #define NFS3_sattr_sz (15)
37 #define NFS3_filename_sz (1+(NFS3_MAXNAMLEN>>2))
38 #define NFS3_path_sz (1+(NFS3_MAXPATHLEN>>2))
39 #define NFS3_fattr_sz (21)
40 #define NFS3_cookieverf_sz (NFS3_COOKIEVERFSIZE>>2)
41 #define NFS3_wcc_attr_sz (6)
42 #define NFS3_pre_op_attr_sz (1+NFS3_wcc_attr_sz)
43 #define NFS3_post_op_attr_sz (1+NFS3_fattr_sz)
44 #define NFS3_wcc_data_sz (NFS3_pre_op_attr_sz+NFS3_post_op_attr_sz)
45 #define NFS3_fsstat_sz
46 #define NFS3_fsinfo_sz
47 #define NFS3_pathconf_sz
48 #define NFS3_entry_sz (NFS3_filename_sz+3)
50 #define NFS3_sattrargs_sz (NFS3_fh_sz+NFS3_sattr_sz+3)
51 #define NFS3_diropargs_sz (NFS3_fh_sz+NFS3_filename_sz)
52 #define NFS3_removeargs_sz (NFS3_fh_sz+NFS3_filename_sz)
53 #define NFS3_accessargs_sz (NFS3_fh_sz+1)
54 #define NFS3_readlinkargs_sz (NFS3_fh_sz)
55 #define NFS3_readargs_sz (NFS3_fh_sz+3)
56 #define NFS3_writeargs_sz (NFS3_fh_sz+5)
57 #define NFS3_createargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz)
58 #define NFS3_mkdirargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz)
59 #define NFS3_symlinkargs_sz (NFS3_diropargs_sz+1+NFS3_sattr_sz)
60 #define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz)
61 #define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz)
62 #define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz)
63 #define NFS3_readdirargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+3)
64 #define NFS3_readdirplusargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+4)
65 #define NFS3_commitargs_sz (NFS3_fh_sz+3)
67 #define NFS3_attrstat_sz (1+NFS3_fattr_sz)
68 #define NFS3_wccstat_sz (1+NFS3_wcc_data_sz)
69 #define NFS3_removeres_sz (NFS3_wccstat_sz)
70 #define NFS3_lookupres_sz (1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz))
71 #define NFS3_accessres_sz (1+NFS3_post_op_attr_sz+1)
72 #define NFS3_readlinkres_sz (1+NFS3_post_op_attr_sz+1)
73 #define NFS3_readres_sz (1+NFS3_post_op_attr_sz+3)
74 #define NFS3_writeres_sz (1+NFS3_wcc_data_sz+4)
75 #define NFS3_createres_sz (1+NFS3_fh_sz+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
76 #define NFS3_renameres_sz (1+(2 * NFS3_wcc_data_sz))
77 #define NFS3_linkres_sz (1+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
78 #define NFS3_readdirres_sz (1+NFS3_post_op_attr_sz+2)
79 #define NFS3_fsstatres_sz (1+NFS3_post_op_attr_sz+13)
80 #define NFS3_fsinfores_sz (1+NFS3_post_op_attr_sz+12)
81 #define NFS3_pathconfres_sz (1+NFS3_post_op_attr_sz+6)
82 #define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2)
84 #define ACL3_getaclargs_sz (NFS3_fh_sz+1)
85 #define ACL3_setaclargs_sz (NFS3_fh_sz+1+ \
86 XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
87 #define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+ \
88 XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
89 #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz)
92 * Map file type to S_IFMT bits
94 static const umode_t nfs_type2fmt[] = {
101 [NF3SOCK] = S_IFSOCK,
105 static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
107 dprintk("nfs: %s: prematurely hit end of receive buffer. "
108 "Remaining buffer length is %tu words.\n",
109 func, xdr->end - xdr->p);
113 * While encoding arguments, set up the reply buffer in advance to
114 * receive reply data directly into the page cache.
116 static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
117 unsigned int base, unsigned int len,
118 unsigned int bufsize)
120 struct rpc_auth *auth = req->rq_cred->cr_auth;
123 replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
124 xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
129 * Common NFS XDR functions as inlines
131 static inline __be32 *
132 xdr_encode_fhandle(__be32 *p, const struct nfs_fh *fh)
134 return xdr_encode_array(p, fh->data, fh->size);
137 static inline __be32 *
138 xdr_decode_fhandle(__be32 *p, struct nfs_fh *fh)
140 if ((fh->size = ntohl(*p++)) <= NFS3_FHSIZE) {
141 memcpy(fh->data, p, fh->size);
142 return p + XDR_QUADLEN(fh->size);
147 static inline __be32 *
148 xdr_decode_fhandle_stream(struct xdr_stream *xdr, struct nfs_fh *fh)
151 p = xdr_inline_decode(xdr, 4);
154 fh->size = ntohl(*p++);
156 if (fh->size <= NFS3_FHSIZE) {
157 p = xdr_inline_decode(xdr, fh->size);
160 memcpy(fh->data, p, fh->size);
161 return p + XDR_QUADLEN(fh->size);
166 print_overflow_msg(__func__, xdr);
167 return ERR_PTR(-EIO);
171 * Encode/decode time.
173 static inline __be32 *
174 xdr_encode_time3(__be32 *p, const struct timespec *timep)
176 *p++ = htonl(timep->tv_sec);
177 *p++ = htonl(timep->tv_nsec);
181 static inline __be32 *
182 xdr_decode_time3(__be32 *p, struct timespec *timep)
184 timep->tv_sec = ntohl(*p++);
185 timep->tv_nsec = ntohl(*p++);
190 xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
192 unsigned int type, major, minor;
198 fmode = nfs_type2fmt[type];
199 fattr->mode = (ntohl(*p++) & ~S_IFMT) | fmode;
200 fattr->nlink = ntohl(*p++);
201 fattr->uid = ntohl(*p++);
202 fattr->gid = ntohl(*p++);
203 p = xdr_decode_hyper(p, &fattr->size);
204 p = xdr_decode_hyper(p, &fattr->du.nfs3.used);
206 /* Turn remote device info into Linux-specific dev_t */
209 fattr->rdev = MKDEV(major, minor);
210 if (MAJOR(fattr->rdev) != major || MINOR(fattr->rdev) != minor)
213 p = xdr_decode_hyper(p, &fattr->fsid.major);
214 fattr->fsid.minor = 0;
215 p = xdr_decode_hyper(p, &fattr->fileid);
216 p = xdr_decode_time3(p, &fattr->atime);
217 p = xdr_decode_time3(p, &fattr->mtime);
218 p = xdr_decode_time3(p, &fattr->ctime);
220 /* Update the mode bits */
221 fattr->valid |= NFS_ATTR_FATTR_V3;
225 static inline __be32 *
226 xdr_encode_sattr(__be32 *p, const struct iattr *attr)
228 if (attr->ia_valid & ATTR_MODE) {
230 *p++ = htonl(attr->ia_mode & S_IALLUGO);
234 if (attr->ia_valid & ATTR_UID) {
236 *p++ = htonl(attr->ia_uid);
240 if (attr->ia_valid & ATTR_GID) {
242 *p++ = htonl(attr->ia_gid);
246 if (attr->ia_valid & ATTR_SIZE) {
248 p = xdr_encode_hyper(p, (__u64) attr->ia_size);
252 if (attr->ia_valid & ATTR_ATIME_SET) {
254 p = xdr_encode_time3(p, &attr->ia_atime);
255 } else if (attr->ia_valid & ATTR_ATIME) {
260 if (attr->ia_valid & ATTR_MTIME_SET) {
262 p = xdr_encode_time3(p, &attr->ia_mtime);
263 } else if (attr->ia_valid & ATTR_MTIME) {
271 static inline __be32 *
272 xdr_decode_wcc_attr(__be32 *p, struct nfs_fattr *fattr)
274 p = xdr_decode_hyper(p, &fattr->pre_size);
275 p = xdr_decode_time3(p, &fattr->pre_mtime);
276 p = xdr_decode_time3(p, &fattr->pre_ctime);
277 fattr->valid |= NFS_ATTR_FATTR_PRESIZE
278 | NFS_ATTR_FATTR_PREMTIME
279 | NFS_ATTR_FATTR_PRECTIME;
283 static inline __be32 *
284 xdr_decode_post_op_attr(__be32 *p, struct nfs_fattr *fattr)
287 p = xdr_decode_fattr(p, fattr);
291 static inline __be32 *
292 xdr_decode_post_op_attr_stream(struct xdr_stream *xdr, struct nfs_fattr *fattr)
296 p = xdr_inline_decode(xdr, 4);
300 p = xdr_inline_decode(xdr, 84);
303 p = xdr_decode_fattr(p, fattr);
307 print_overflow_msg(__func__, xdr);
308 return ERR_PTR(-EIO);
311 static inline __be32 *
312 xdr_decode_pre_op_attr(__be32 *p, struct nfs_fattr *fattr)
315 return xdr_decode_wcc_attr(p, fattr);
320 static inline __be32 *
321 xdr_decode_wcc_data(__be32 *p, struct nfs_fattr *fattr)
323 p = xdr_decode_pre_op_attr(p, fattr);
324 return xdr_decode_post_op_attr(p, fattr);
329 * Encode/decode NFSv3 basic data types
331 * Basic NFSv3 data types are defined in section 2.5 of RFC 1813:
332 * "NFS Version 3 Protocol Specification".
334 * Not all basic data types have their own encoding and decoding
335 * functions. For run-time efficiency, some data types are encoded
339 static void encode_uint32(struct xdr_stream *xdr, u32 value)
341 __be32 *p = xdr_reserve_space(xdr, 4);
342 *p = cpu_to_be32(value);
348 * typedef string filename3<>;
350 static void encode_filename3(struct xdr_stream *xdr,
351 const char *name, u32 length)
355 BUG_ON(length > NFS3_MAXNAMLEN);
356 p = xdr_reserve_space(xdr, 4 + length);
357 xdr_encode_opaque(p, name, length);
363 * typedef string nfspath3<>;
365 static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages,
368 BUG_ON(length > NFS3_MAXPATHLEN);
369 encode_uint32(xdr, length);
370 xdr_write_pages(xdr, pages, 0, length);
376 * typedef uint64 cookie3
378 static __be32 *xdr_encode_cookie3(__be32 *p, u64 cookie)
380 return xdr_encode_hyper(p, cookie);
386 * typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
388 static __be32 *xdr_encode_cookieverf3(__be32 *p, const __be32 *verifier)
390 memcpy(p, verifier, NFS3_COOKIEVERFSIZE);
391 return p + XDR_QUADLEN(NFS3_COOKIEVERFSIZE);
397 * typedef opaque createverf3[NFS3_CREATEVERFSIZE];
399 static void encode_createverf3(struct xdr_stream *xdr, const __be32 *verifier)
403 p = xdr_reserve_space(xdr, NFS3_CREATEVERFSIZE);
404 memcpy(p, verifier, NFS3_CREATEVERFSIZE);
420 static void encode_ftype3(struct xdr_stream *xdr, const u32 type)
422 BUG_ON(type > NF3FIFO);
423 encode_uint32(xdr, type);
434 static void encode_specdata3(struct xdr_stream *xdr, const dev_t rdev)
438 p = xdr_reserve_space(xdr, 8);
439 *p++ = cpu_to_be32(MAJOR(rdev));
440 *p = cpu_to_be32(MINOR(rdev));
447 * opaque data<NFS3_FHSIZE>;
450 static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh)
454 BUG_ON(fh->size > NFS3_FHSIZE);
455 p = xdr_reserve_space(xdr, 4 + fh->size);
456 xdr_encode_opaque(p, fh->data, fh->size);
464 * SET_TO_SERVER_TIME = 1,
465 * SET_TO_CLIENT_TIME = 2
468 * union set_mode3 switch (bool set_it) {
475 * union set_uid3 switch (bool set_it) {
482 * union set_gid3 switch (bool set_it) {
489 * union set_size3 switch (bool set_it) {
496 * union set_atime switch (time_how set_it) {
497 * case SET_TO_CLIENT_TIME:
503 * union set_mtime switch (time_how set_it) {
504 * case SET_TO_CLIENT_TIME:
519 static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)
525 * In order to make only a single xdr_reserve_space() call,
526 * pre-compute the total number of bytes to be reserved.
527 * Six boolean values, one for each set_foo field, are always
528 * present in the encoded result, so start there.
531 if (attr->ia_valid & ATTR_MODE)
533 if (attr->ia_valid & ATTR_UID)
535 if (attr->ia_valid & ATTR_GID)
537 if (attr->ia_valid & ATTR_SIZE)
539 if (attr->ia_valid & ATTR_ATIME_SET)
541 if (attr->ia_valid & ATTR_MTIME_SET)
543 p = xdr_reserve_space(xdr, nbytes);
545 xdr_encode_sattr(p, attr);
551 * struct diropargs3 {
556 static void encode_diropargs3(struct xdr_stream *xdr, const struct nfs_fh *fh,
557 const char *name, u32 length)
559 encode_nfs_fh3(xdr, fh);
560 encode_filename3(xdr, name, length);
565 * NFS encode functions
569 * Encode file handle argument
572 nfs3_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh)
574 p = xdr_encode_fhandle(p, fh);
575 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
582 * struct GETATTR3args {
586 static int nfs3_xdr_enc_getattr3args(struct rpc_rqst *req, __be32 *p,
587 const struct nfs_fh *fh)
589 struct xdr_stream xdr;
591 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
592 encode_nfs_fh3(&xdr, fh);
597 * Encode SETATTR arguments
600 nfs3_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs3_sattrargs *args)
602 p = xdr_encode_fhandle(p, args->fh);
603 p = xdr_encode_sattr(p, args->sattr);
604 *p++ = htonl(args->guard);
606 p = xdr_encode_time3(p, &args->guardtime);
607 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
614 * union sattrguard3 switch (bool check) {
616 * nfstime3 obj_ctime;
621 * struct SETATTR3args {
623 * sattr3 new_attributes;
627 static void encode_sattrguard3(struct xdr_stream *xdr,
628 const struct nfs3_sattrargs *args)
633 p = xdr_reserve_space(xdr, 4 + 8);
635 xdr_encode_time3(p, &args->guardtime);
637 p = xdr_reserve_space(xdr, 4);
642 static int nfs3_xdr_enc_setattr3args(struct rpc_rqst *req, __be32 *p,
643 const struct nfs3_sattrargs *args)
645 struct xdr_stream xdr;
647 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
648 encode_nfs_fh3(&xdr, args->fh);
649 encode_sattr3(&xdr, args->sattr);
650 encode_sattrguard3(&xdr, args);
655 * Encode directory ops argument
658 nfs3_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs3_diropargs *args)
660 p = xdr_encode_fhandle(p, args->fh);
661 p = xdr_encode_array(p, args->name, args->len);
662 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
669 * struct LOOKUP3args {
673 static int nfs3_xdr_enc_lookup3args(struct rpc_rqst *req, __be32 *p,
674 const struct nfs3_diropargs *args)
676 struct xdr_stream xdr;
678 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
679 encode_diropargs3(&xdr, args->fh, args->name, args->len);
684 * Encode REMOVE argument
687 nfs3_xdr_removeargs(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args)
689 p = xdr_encode_fhandle(p, args->fh);
690 p = xdr_encode_array(p, args->name.name, args->name.len);
691 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
696 * Encode access() argument
699 nfs3_xdr_accessargs(struct rpc_rqst *req, __be32 *p, struct nfs3_accessargs *args)
701 p = xdr_encode_fhandle(p, args->fh);
702 *p++ = htonl(args->access);
703 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
710 * struct ACCESS3args {
715 static void encode_access3args(struct xdr_stream *xdr,
716 const struct nfs3_accessargs *args)
718 encode_nfs_fh3(xdr, args->fh);
719 encode_uint32(xdr, args->access);
722 static int nfs3_xdr_enc_access3args(struct rpc_rqst *req, __be32 *p,
723 const struct nfs3_accessargs *args)
725 struct xdr_stream xdr;
727 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
728 encode_access3args(&xdr, args);
733 * 3.3.5 READLINK3args
735 * struct READLINK3args {
739 static int nfs3_xdr_enc_readlink3args(struct rpc_rqst *req, __be32 *p,
740 const struct nfs3_readlinkargs *args)
742 struct xdr_stream xdr;
744 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
745 encode_nfs_fh3(&xdr, args->fh);
746 prepare_reply_buffer(req, args->pages, args->pgbase,
747 args->pglen, NFS3_readlinkres_sz);
752 * Arguments to a READ call. Since we read data directly into the page
753 * cache, we also set up the reply iovec here so that iov[1] points
754 * exactly to the page we want to fetch.
757 nfs3_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
759 struct rpc_auth *auth = req->rq_cred->cr_auth;
761 u32 count = args->count;
763 p = xdr_encode_fhandle(p, args->fh);
764 p = xdr_encode_hyper(p, args->offset);
766 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
768 /* Inline the page array */
769 replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readres_sz) << 2;
770 xdr_inline_pages(&req->rq_rcv_buf, replen,
771 args->pages, args->pgbase, count);
772 req->rq_rcv_buf.flags |= XDRBUF_READ;
785 static void encode_read3args(struct xdr_stream *xdr,
786 const struct nfs_readargs *args)
790 encode_nfs_fh3(xdr, args->fh);
792 p = xdr_reserve_space(xdr, 8 + 4);
793 p = xdr_encode_hyper(p, args->offset);
794 *p = cpu_to_be32(args->count);
797 static int nfs3_xdr_enc_read3args(struct rpc_rqst *req, __be32 *p,
798 const struct nfs_readargs *args)
800 struct xdr_stream xdr;
802 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
803 encode_read3args(&xdr, args);
804 prepare_reply_buffer(req, args->pages, args->pgbase,
805 args->count, NFS3_readres_sz);
806 req->rq_rcv_buf.flags |= XDRBUF_READ;
811 * Write arguments. Splice the buffer to be written into the iovec.
814 nfs3_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
816 struct xdr_buf *sndbuf = &req->rq_snd_buf;
817 u32 count = args->count;
819 p = xdr_encode_fhandle(p, args->fh);
820 p = xdr_encode_hyper(p, args->offset);
822 *p++ = htonl(args->stable);
824 sndbuf->len = xdr_adjust_iovec(sndbuf->head, p);
826 /* Copy the page array */
827 xdr_encode_pages(sndbuf, args->pages, args->pgbase, count);
828 sndbuf->flags |= XDRBUF_WRITE;
841 * struct WRITE3args {
849 static void encode_write3args(struct xdr_stream *xdr,
850 const struct nfs_writeargs *args)
854 encode_nfs_fh3(xdr, args->fh);
856 p = xdr_reserve_space(xdr, 8 + 4 + 4 + 4);
857 p = xdr_encode_hyper(p, args->offset);
858 *p++ = cpu_to_be32(args->count);
860 BUG_ON(args->stable > NFS_FILE_SYNC);
861 *p++ = cpu_to_be32(args->stable);
863 *p = cpu_to_be32(args->count);
864 xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
867 static int nfs3_xdr_enc_write3args(struct rpc_rqst *req, __be32 *p,
868 const struct nfs_writeargs *args)
870 struct xdr_stream xdr;
872 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
873 encode_write3args(&xdr, args);
874 xdr.buf->flags |= XDRBUF_WRITE;
879 * Encode CREATE arguments
882 nfs3_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs3_createargs *args)
884 p = xdr_encode_fhandle(p, args->fh);
885 p = xdr_encode_array(p, args->name, args->len);
887 *p++ = htonl(args->createmode);
888 if (args->createmode == NFS3_CREATE_EXCLUSIVE) {
889 *p++ = args->verifier[0];
890 *p++ = args->verifier[1];
892 p = xdr_encode_sattr(p, args->sattr);
894 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
907 * union createhow3 switch (createmode3 mode) {
910 * sattr3 obj_attributes;
915 * struct CREATE3args {
920 static void encode_createhow3(struct xdr_stream *xdr,
921 const struct nfs3_createargs *args)
923 encode_uint32(xdr, args->createmode);
924 switch (args->createmode) {
925 case NFS3_CREATE_UNCHECKED:
926 case NFS3_CREATE_GUARDED:
927 encode_sattr3(xdr, args->sattr);
929 case NFS3_CREATE_EXCLUSIVE:
930 encode_createverf3(xdr, args->verifier);
937 static int nfs3_xdr_enc_create3args(struct rpc_rqst *req, __be32 *p,
938 const struct nfs3_createargs *args)
940 struct xdr_stream xdr;
942 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
943 encode_diropargs3(&xdr, args->fh, args->name, args->len);
944 encode_createhow3(&xdr, args);
949 * Encode MKDIR arguments
952 nfs3_xdr_mkdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mkdirargs *args)
954 p = xdr_encode_fhandle(p, args->fh);
955 p = xdr_encode_array(p, args->name, args->len);
956 p = xdr_encode_sattr(p, args->sattr);
957 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
964 * struct MKDIR3args {
969 static int nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req, __be32 *p,
970 const struct nfs3_mkdirargs *args)
972 struct xdr_stream xdr;
974 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
975 encode_diropargs3(&xdr, args->fh, args->name, args->len);
976 encode_sattr3(&xdr, args->sattr);
981 * Encode SYMLINK arguments
984 nfs3_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_symlinkargs *args)
986 p = xdr_encode_fhandle(p, args->fromfh);
987 p = xdr_encode_array(p, args->fromname, args->fromlen);
988 p = xdr_encode_sattr(p, args->sattr);
989 *p++ = htonl(args->pathlen);
990 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
993 xdr_encode_pages(&req->rq_snd_buf, args->pages, 0, args->pathlen);
998 * 3.3.10 SYMLINK3args
1000 * struct symlinkdata3 {
1001 * sattr3 symlink_attributes;
1002 * nfspath3 symlink_data;
1005 * struct SYMLINK3args {
1007 * symlinkdata3 symlink;
1010 static void encode_symlinkdata3(struct xdr_stream *xdr,
1011 const struct nfs3_symlinkargs *args)
1013 encode_sattr3(xdr, args->sattr);
1014 encode_nfspath3(xdr, args->pages, args->pathlen);
1017 static int nfs3_xdr_enc_symlink3args(struct rpc_rqst *req, __be32 *p,
1018 const struct nfs3_symlinkargs *args)
1020 struct xdr_stream xdr;
1022 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1023 encode_diropargs3(&xdr, args->fromfh, args->fromname, args->fromlen);
1024 encode_symlinkdata3(&xdr, args);
1029 * Encode MKNOD arguments
1032 nfs3_xdr_mknodargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mknodargs *args)
1034 p = xdr_encode_fhandle(p, args->fh);
1035 p = xdr_encode_array(p, args->name, args->len);
1036 *p++ = htonl(args->type);
1037 p = xdr_encode_sattr(p, args->sattr);
1038 if (args->type == NF3CHR || args->type == NF3BLK) {
1039 *p++ = htonl(MAJOR(args->rdev));
1040 *p++ = htonl(MINOR(args->rdev));
1043 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
1050 * struct devicedata3 {
1051 * sattr3 dev_attributes;
1055 * union mknoddata3 switch (ftype3 type) {
1058 * devicedata3 device;
1061 * sattr3 pipe_attributes;
1066 * struct MKNOD3args {
1071 static void encode_devicedata3(struct xdr_stream *xdr,
1072 const struct nfs3_mknodargs *args)
1074 encode_sattr3(xdr, args->sattr);
1075 encode_specdata3(xdr, args->rdev);
1078 static void encode_mknoddata3(struct xdr_stream *xdr,
1079 const struct nfs3_mknodargs *args)
1081 encode_ftype3(xdr, args->type);
1082 switch (args->type) {
1085 encode_devicedata3(xdr, args);
1089 encode_sattr3(xdr, args->sattr);
1099 static int nfs3_xdr_enc_mknod3args(struct rpc_rqst *req, __be32 *p,
1100 const struct nfs3_mknodargs *args)
1102 struct xdr_stream xdr;
1104 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1105 encode_diropargs3(&xdr, args->fh, args->name, args->len);
1106 encode_mknoddata3(&xdr, args);
1111 * 3.3.12 REMOVE3args
1113 * struct REMOVE3args {
1114 * diropargs3 object;
1117 static int nfs3_xdr_enc_remove3args(struct rpc_rqst *req, __be32 *p,
1118 const struct nfs_removeargs *args)
1120 struct xdr_stream xdr;
1122 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1123 encode_diropargs3(&xdr, args->fh, args->name.name, args->name.len);
1128 * Encode RENAME arguments
1131 nfs3_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs_renameargs *args)
1133 p = xdr_encode_fhandle(p, args->old_dir);
1134 p = xdr_encode_array(p, args->old_name->name, args->old_name->len);
1135 p = xdr_encode_fhandle(p, args->new_dir);
1136 p = xdr_encode_array(p, args->new_name->name, args->new_name->len);
1137 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
1142 * 3.3.14 RENAME3args
1144 * struct RENAME3args {
1149 static int nfs3_xdr_enc_rename3args(struct rpc_rqst *req, __be32 *p,
1150 const struct nfs_renameargs *args)
1152 const struct qstr *old = args->old_name;
1153 const struct qstr *new = args->new_name;
1154 struct xdr_stream xdr;
1156 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1157 encode_diropargs3(&xdr, args->old_dir, old->name, old->len);
1158 encode_diropargs3(&xdr, args->new_dir, new->name, new->len);
1163 * Encode LINK arguments
1166 nfs3_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_linkargs *args)
1168 p = xdr_encode_fhandle(p, args->fromfh);
1169 p = xdr_encode_fhandle(p, args->tofh);
1170 p = xdr_encode_array(p, args->toname, args->tolen);
1171 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
1178 * struct LINK3args {
1183 static int nfs3_xdr_enc_link3args(struct rpc_rqst *req, __be32 *p,
1184 const struct nfs3_linkargs *args)
1186 struct xdr_stream xdr;
1188 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1189 encode_nfs_fh3(&xdr, args->fromfh);
1190 encode_diropargs3(&xdr, args->tofh, args->toname, args->tolen);
1195 * Encode arguments to readdir call
1198 nfs3_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirargs *args)
1200 struct rpc_auth *auth = req->rq_cred->cr_auth;
1201 unsigned int replen;
1202 u32 count = args->count;
1204 p = xdr_encode_fhandle(p, args->fh);
1205 p = xdr_encode_hyper(p, args->cookie);
1206 *p++ = args->verf[0];
1207 *p++ = args->verf[1];
1209 /* readdirplus: need dircount + buffer size.
1210 * We just make sure we make dircount big enough */
1211 *p++ = htonl(count >> 3);
1213 *p++ = htonl(count);
1214 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
1216 /* Inline the page array */
1217 replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readdirres_sz) << 2;
1218 xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0, count);
1223 * 3.3.16 READDIR3args
1225 * struct READDIR3args {
1228 * cookieverf3 cookieverf;
1232 static void encode_readdir3args(struct xdr_stream *xdr,
1233 const struct nfs3_readdirargs *args)
1237 encode_nfs_fh3(xdr, args->fh);
1239 p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4);
1240 p = xdr_encode_cookie3(p, args->cookie);
1241 p = xdr_encode_cookieverf3(p, args->verf);
1242 *p = cpu_to_be32(args->count);
1245 static int nfs3_xdr_enc_readdir3args(struct rpc_rqst *req, __be32 *p,
1246 const struct nfs3_readdirargs *args)
1248 struct xdr_stream xdr;
1250 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1251 encode_readdir3args(&xdr, args);
1252 prepare_reply_buffer(req, args->pages, 0,
1253 args->count, NFS3_readdirres_sz);
1258 * 3.3.17 READDIRPLUS3args
1260 * struct READDIRPLUS3args {
1263 * cookieverf3 cookieverf;
1268 static void encode_readdirplus3args(struct xdr_stream *xdr,
1269 const struct nfs3_readdirargs *args)
1273 encode_nfs_fh3(xdr, args->fh);
1275 p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4 + 4);
1276 p = xdr_encode_cookie3(p, args->cookie);
1277 p = xdr_encode_cookieverf3(p, args->verf);
1280 * readdirplus: need dircount + buffer size.
1281 * We just make sure we make dircount big enough
1283 *p++ = cpu_to_be32(args->count >> 3);
1285 *p = cpu_to_be32(args->count);
1288 static int nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req, __be32 *p,
1289 const struct nfs3_readdirargs *args)
1291 struct xdr_stream xdr;
1293 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1294 encode_readdirplus3args(&xdr, args);
1295 prepare_reply_buffer(req, args->pages, 0,
1296 args->count, NFS3_readdirres_sz);
1301 * Decode the result of a readdir call.
1302 * We just check for syntactical correctness.
1305 nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res)
1307 struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
1308 struct kvec *iov = rcvbuf->head;
1314 status = ntohl(*p++);
1315 /* Decode post_op_attrs */
1316 p = xdr_decode_post_op_attr(p, res->dir_attr);
1318 return nfs_stat_to_errno(status);
1319 /* Decode verifier cookie */
1321 res->verf[0] = *p++;
1322 res->verf[1] = *p++;
1327 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
1328 if (iov->iov_len < hdrlen) {
1329 dprintk("NFS: READDIR reply header overflowed:"
1330 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1331 return -errno_NFSERR_IO;
1332 } else if (iov->iov_len != hdrlen) {
1333 dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
1334 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
1337 pglen = rcvbuf->page_len;
1338 recvd = rcvbuf->len - hdrlen;
1341 page = rcvbuf->pages;
1347 nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_server *server, int plus)
1350 struct nfs_entry old = *entry;
1352 p = xdr_inline_decode(xdr, 4);
1356 p = xdr_inline_decode(xdr, 4);
1360 return ERR_PTR(-EAGAIN);
1362 return ERR_PTR(-EBADCOOKIE);
1365 p = xdr_inline_decode(xdr, 12);
1368 p = xdr_decode_hyper(p, &entry->ino);
1369 entry->len = ntohl(*p++);
1371 p = xdr_inline_decode(xdr, entry->len + 8);
1374 entry->name = (const char *) p;
1375 p += XDR_QUADLEN(entry->len);
1376 entry->prev_cookie = entry->cookie;
1377 p = xdr_decode_hyper(p, &entry->cookie);
1379 entry->d_type = DT_UNKNOWN;
1381 entry->fattr->valid = 0;
1382 p = xdr_decode_post_op_attr_stream(xdr, entry->fattr);
1384 goto out_overflow_exit;
1385 entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
1386 /* In fact, a post_op_fh3: */
1387 p = xdr_inline_decode(xdr, 4);
1391 p = xdr_decode_fhandle_stream(xdr, entry->fh);
1393 goto out_overflow_exit;
1394 /* Ugh -- server reply was truncated */
1396 dprintk("NFS: FH truncated\n");
1398 return ERR_PTR(-EAGAIN);
1401 memset((u8*)(entry->fh), 0, sizeof(*entry->fh));
1404 p = xdr_inline_peek(xdr, 8);
1406 entry->eof = !p[0] && p[1];
1413 print_overflow_msg(__func__, xdr);
1415 return ERR_PTR(-EAGAIN);
1419 * Encode COMMIT arguments
1422 nfs3_xdr_commitargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
1424 p = xdr_encode_fhandle(p, args->fh);
1425 p = xdr_encode_hyper(p, args->offset);
1426 *p++ = htonl(args->count);
1427 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
1432 * 3.3.21 COMMIT3args
1434 * struct COMMIT3args {
1440 static void encode_commit3args(struct xdr_stream *xdr,
1441 const struct nfs_writeargs *args)
1445 encode_nfs_fh3(xdr, args->fh);
1447 p = xdr_reserve_space(xdr, 8 + 4);
1448 p = xdr_encode_hyper(p, args->offset);
1449 *p = cpu_to_be32(args->count);
1452 static int nfs3_xdr_enc_commit3args(struct rpc_rqst *req, __be32 *p,
1453 const struct nfs_writeargs *args)
1455 struct xdr_stream xdr;
1457 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1458 encode_commit3args(&xdr, args);
1462 #ifdef CONFIG_NFS_V3_ACL
1464 * Encode GETACL arguments
1467 nfs3_xdr_getaclargs(struct rpc_rqst *req, __be32 *p,
1468 struct nfs3_getaclargs *args)
1470 struct rpc_auth *auth = req->rq_cred->cr_auth;
1471 unsigned int replen;
1473 p = xdr_encode_fhandle(p, args->fh);
1474 *p++ = htonl(args->mask);
1475 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
1477 if (args->mask & (NFS_ACL | NFS_DFACL)) {
1478 /* Inline the page array */
1479 replen = (RPC_REPHDRSIZE + auth->au_rslack +
1480 ACL3_getaclres_sz) << 2;
1481 xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0,
1482 NFSACL_MAXPAGES << PAGE_SHIFT);
1487 static int nfs3_xdr_enc_getacl3args(struct rpc_rqst *req, __be32 *p,
1488 const struct nfs3_getaclargs *args)
1490 struct xdr_stream xdr;
1492 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1493 encode_nfs_fh3(&xdr, args->fh);
1494 encode_uint32(&xdr, args->mask);
1495 if (args->mask & (NFS_ACL | NFS_DFACL))
1496 prepare_reply_buffer(req, args->pages, 0,
1497 NFSACL_MAXPAGES << PAGE_SHIFT,
1503 * Encode SETACL arguments
1506 nfs3_xdr_setaclargs(struct rpc_rqst *req, __be32 *p,
1507 struct nfs3_setaclargs *args)
1509 struct xdr_buf *buf = &req->rq_snd_buf;
1513 p = xdr_encode_fhandle(p, NFS_FH(args->inode));
1514 *p++ = htonl(args->mask);
1515 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
1516 base = req->rq_slen;
1518 if (args->npages != 0)
1519 xdr_encode_pages(buf, args->pages, 0, args->len);
1521 req->rq_slen = xdr_adjust_iovec(req->rq_svec,
1522 p + XDR_QUADLEN(args->len));
1524 err = nfsacl_encode(buf, base, args->inode,
1525 (args->mask & NFS_ACL) ?
1526 args->acl_access : NULL, 1, 0);
1528 err = nfsacl_encode(buf, base + err, args->inode,
1529 (args->mask & NFS_DFACL) ?
1530 args->acl_default : NULL, 1,
1532 return (err > 0) ? 0 : err;
1535 static int nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, __be32 *p,
1536 const struct nfs3_setaclargs *args)
1538 struct xdr_stream xdr;
1542 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1543 encode_nfs_fh3(&xdr, NFS_FH(args->inode));
1544 encode_uint32(&xdr, args->mask);
1545 if (args->npages != 0)
1546 xdr_write_pages(&xdr, args->pages, 0, args->len);
1548 base = req->rq_slen;
1549 error = nfsacl_encode(xdr.buf, base, args->inode,
1550 (args->mask & NFS_ACL) ?
1551 args->acl_access : NULL, 1, 0);
1553 error = nfsacl_encode(xdr.buf, base + error, args->inode,
1554 (args->mask & NFS_DFACL) ?
1555 args->acl_default : NULL, 1,
1561 #endif /* CONFIG_NFS_V3_ACL */
1564 * NFS XDR decode functions
1568 * Decode attrstat reply.
1571 nfs3_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1575 if ((status = ntohl(*p++)))
1576 return nfs_stat_to_errno(status);
1577 xdr_decode_fattr(p, fattr);
1582 * Decode status+wcc_data reply
1583 * SATTR, REMOVE, RMDIR
1586 nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1590 if ((status = ntohl(*p++)))
1591 status = nfs_stat_to_errno(status);
1592 xdr_decode_wcc_data(p, fattr);
1597 nfs3_xdr_removeres(struct rpc_rqst *req, __be32 *p, struct nfs_removeres *res)
1599 return nfs3_xdr_wccstat(req, p, res->dir_attr);
1603 * Decode LOOKUP reply
1606 nfs3_xdr_lookupres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
1610 if ((status = ntohl(*p++))) {
1611 status = nfs_stat_to_errno(status);
1613 if (!(p = xdr_decode_fhandle(p, res->fh)))
1614 return -errno_NFSERR_IO;
1615 p = xdr_decode_post_op_attr(p, res->fattr);
1617 xdr_decode_post_op_attr(p, res->dir_attr);
1622 * Decode ACCESS reply
1625 nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res)
1627 int status = ntohl(*p++);
1629 p = xdr_decode_post_op_attr(p, res->fattr);
1631 return nfs_stat_to_errno(status);
1632 res->access = ntohl(*p++);
1637 nfs3_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readlinkargs *args)
1639 struct rpc_auth *auth = req->rq_cred->cr_auth;
1640 unsigned int replen;
1642 p = xdr_encode_fhandle(p, args->fh);
1643 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
1645 /* Inline the page array */
1646 replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readlinkres_sz) << 2;
1647 xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, args->pgbase, args->pglen);
1652 * Decode READLINK reply
1655 nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1657 struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
1658 struct kvec *iov = rcvbuf->head;
1663 status = ntohl(*p++);
1664 p = xdr_decode_post_op_attr(p, fattr);
1667 return nfs_stat_to_errno(status);
1669 /* Convert length of symlink */
1671 if (len >= rcvbuf->page_len) {
1672 dprintk("nfs: server returned giant symlink!\n");
1673 return -ENAMETOOLONG;
1676 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
1677 if (iov->iov_len < hdrlen) {
1678 dprintk("NFS: READLINK reply header overflowed:"
1679 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1680 return -errno_NFSERR_IO;
1681 } else if (iov->iov_len != hdrlen) {
1682 dprintk("NFS: READLINK header is short. "
1683 "iovec will be shifted.\n");
1684 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
1686 recvd = req->rq_rcv_buf.len - hdrlen;
1688 dprintk("NFS: server cheating in readlink reply: "
1689 "count %u > recvd %u\n", len, recvd);
1693 xdr_terminate_string(rcvbuf, len);
1701 nfs3_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
1703 struct kvec *iov = req->rq_rcv_buf.head;
1705 u32 count, ocount, recvd;
1708 status = ntohl(*p++);
1709 p = xdr_decode_post_op_attr(p, res->fattr);
1712 return nfs_stat_to_errno(status);
1714 /* Decode reply count and EOF flag. NFSv3 is somewhat redundant
1715 * in that it puts the count both in the res struct and in the
1716 * opaque data count. */
1717 count = ntohl(*p++);
1718 res->eof = ntohl(*p++);
1719 ocount = ntohl(*p++);
1721 if (ocount != count) {
1722 dprintk("NFS: READ count doesn't match RPC opaque count.\n");
1723 return -errno_NFSERR_IO;
1726 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
1727 if (iov->iov_len < hdrlen) {
1728 dprintk("NFS: READ reply header overflowed:"
1729 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1730 return -errno_NFSERR_IO;
1731 } else if (iov->iov_len != hdrlen) {
1732 dprintk("NFS: READ header is short. iovec will be shifted.\n");
1733 xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
1736 recvd = req->rq_rcv_buf.len - hdrlen;
1737 if (count > recvd) {
1738 dprintk("NFS: server cheating in read reply: "
1739 "count %u > recvd %u\n", count, recvd);
1744 if (count < res->count)
1751 * Decode WRITE response
1754 nfs3_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
1758 status = ntohl(*p++);
1759 p = xdr_decode_wcc_data(p, res->fattr);
1762 return nfs_stat_to_errno(status);
1764 res->count = ntohl(*p++);
1765 res->verf->committed = (enum nfs3_stable_how)ntohl(*p++);
1766 res->verf->verifier[0] = *p++;
1767 res->verf->verifier[1] = *p++;
1773 * Decode a CREATE response
1776 nfs3_xdr_createres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
1780 status = ntohl(*p++);
1783 if (!(p = xdr_decode_fhandle(p, res->fh)))
1784 return -errno_NFSERR_IO;
1785 p = xdr_decode_post_op_attr(p, res->fattr);
1787 memset(res->fh, 0, sizeof(*res->fh));
1788 /* Do decode post_op_attr but set it to NULL */
1789 p = xdr_decode_post_op_attr(p, res->fattr);
1790 res->fattr->valid = 0;
1793 status = nfs_stat_to_errno(status);
1795 p = xdr_decode_wcc_data(p, res->dir_attr);
1800 * Decode RENAME reply
1803 nfs3_xdr_renameres(struct rpc_rqst *req, __be32 *p, struct nfs_renameres *res)
1807 if ((status = ntohl(*p++)) != 0)
1808 status = nfs_stat_to_errno(status);
1809 p = xdr_decode_wcc_data(p, res->old_fattr);
1810 p = xdr_decode_wcc_data(p, res->new_fattr);
1818 nfs3_xdr_linkres(struct rpc_rqst *req, __be32 *p, struct nfs3_linkres *res)
1822 if ((status = ntohl(*p++)) != 0)
1823 status = nfs_stat_to_errno(status);
1824 p = xdr_decode_post_op_attr(p, res->fattr);
1825 p = xdr_decode_wcc_data(p, res->dir_attr);
1830 * Decode FSSTAT reply
1833 nfs3_xdr_fsstatres(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *res)
1837 status = ntohl(*p++);
1839 p = xdr_decode_post_op_attr(p, res->fattr);
1841 return nfs_stat_to_errno(status);
1843 p = xdr_decode_hyper(p, &res->tbytes);
1844 p = xdr_decode_hyper(p, &res->fbytes);
1845 p = xdr_decode_hyper(p, &res->abytes);
1846 p = xdr_decode_hyper(p, &res->tfiles);
1847 p = xdr_decode_hyper(p, &res->ffiles);
1848 p = xdr_decode_hyper(p, &res->afiles);
1850 /* ignore invarsec */
1855 * Decode FSINFO reply
1858 nfs3_xdr_fsinfores(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *res)
1862 status = ntohl(*p++);
1864 p = xdr_decode_post_op_attr(p, res->fattr);
1866 return nfs_stat_to_errno(status);
1868 res->rtmax = ntohl(*p++);
1869 res->rtpref = ntohl(*p++);
1870 res->rtmult = ntohl(*p++);
1871 res->wtmax = ntohl(*p++);
1872 res->wtpref = ntohl(*p++);
1873 res->wtmult = ntohl(*p++);
1874 res->dtpref = ntohl(*p++);
1875 p = xdr_decode_hyper(p, &res->maxfilesize);
1876 p = xdr_decode_time3(p, &res->time_delta);
1878 /* ignore properties */
1879 res->lease_time = 0;
1884 * Decode PATHCONF reply
1887 nfs3_xdr_pathconfres(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *res)
1891 status = ntohl(*p++);
1893 p = xdr_decode_post_op_attr(p, res->fattr);
1895 return nfs_stat_to_errno(status);
1896 res->max_link = ntohl(*p++);
1897 res->max_namelen = ntohl(*p++);
1899 /* ignore remaining fields */
1904 * Decode COMMIT reply
1907 nfs3_xdr_commitres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
1911 status = ntohl(*p++);
1912 p = xdr_decode_wcc_data(p, res->fattr);
1914 return nfs_stat_to_errno(status);
1916 res->verf->verifier[0] = *p++;
1917 res->verf->verifier[1] = *p++;
1921 #ifdef CONFIG_NFS_V3_ACL
1923 * Decode GETACL reply
1926 nfs3_xdr_getaclres(struct rpc_rqst *req, __be32 *p,
1927 struct nfs3_getaclres *res)
1929 struct xdr_buf *buf = &req->rq_rcv_buf;
1930 int status = ntohl(*p++);
1931 struct posix_acl **acl;
1932 unsigned int *aclcnt;
1936 return nfs_stat_to_errno(status);
1937 p = xdr_decode_post_op_attr(p, res->fattr);
1938 res->mask = ntohl(*p++);
1939 if (res->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
1941 base = (char *)p - (char *)req->rq_rcv_buf.head->iov_base;
1943 acl = (res->mask & NFS_ACL) ? &res->acl_access : NULL;
1944 aclcnt = (res->mask & NFS_ACLCNT) ? &res->acl_access_count : NULL;
1945 err = nfsacl_decode(buf, base, aclcnt, acl);
1947 acl = (res->mask & NFS_DFACL) ? &res->acl_default : NULL;
1948 aclcnt = (res->mask & NFS_DFACLCNT) ? &res->acl_default_count : NULL;
1950 err = nfsacl_decode(buf, base + err, aclcnt, acl);
1951 return (err > 0) ? 0 : err;
1955 * Decode setacl reply.
1958 nfs3_xdr_setaclres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1960 int status = ntohl(*p++);
1963 return nfs_stat_to_errno(status);
1964 xdr_decode_post_op_attr(p, fattr);
1967 #endif /* CONFIG_NFS_V3_ACL */
1969 #define PROC(proc, argtype, restype, timer) \
1970 [NFS3PROC_##proc] = { \
1971 .p_proc = NFS3PROC_##proc, \
1972 .p_encode = (kxdrproc_t) nfs3_xdr_##argtype, \
1973 .p_decode = (kxdrproc_t) nfs3_xdr_##restype, \
1974 .p_arglen = NFS3_##argtype##_sz, \
1975 .p_replen = NFS3_##restype##_sz, \
1977 .p_statidx = NFS3PROC_##proc, \
1981 struct rpc_procinfo nfs3_procedures[] = {
1982 PROC(GETATTR, fhandle, attrstat, 1),
1983 PROC(SETATTR, sattrargs, wccstat, 0),
1984 PROC(LOOKUP, diropargs, lookupres, 2),
1985 PROC(ACCESS, accessargs, accessres, 1),
1986 PROC(READLINK, readlinkargs, readlinkres, 3),
1987 PROC(READ, readargs, readres, 3),
1988 PROC(WRITE, writeargs, writeres, 4),
1989 PROC(CREATE, createargs, createres, 0),
1990 PROC(MKDIR, mkdirargs, createres, 0),
1991 PROC(SYMLINK, symlinkargs, createres, 0),
1992 PROC(MKNOD, mknodargs, createres, 0),
1993 PROC(REMOVE, removeargs, removeres, 0),
1994 PROC(RMDIR, diropargs, wccstat, 0),
1995 PROC(RENAME, renameargs, renameres, 0),
1996 PROC(LINK, linkargs, linkres, 0),
1997 PROC(READDIR, readdirargs, readdirres, 3),
1998 PROC(READDIRPLUS, readdirargs, readdirres, 3),
1999 PROC(FSSTAT, fhandle, fsstatres, 0),
2000 PROC(FSINFO, fhandle, fsinfores, 0),
2001 PROC(PATHCONF, fhandle, pathconfres, 0),
2002 PROC(COMMIT, commitargs, commitres, 5),
2005 struct rpc_version nfs_version3 = {
2007 .nrprocs = ARRAY_SIZE(nfs3_procedures),
2008 .procs = nfs3_procedures
2011 #ifdef CONFIG_NFS_V3_ACL
2012 static struct rpc_procinfo nfs3_acl_procedures[] = {
2013 [ACLPROC3_GETACL] = {
2014 .p_proc = ACLPROC3_GETACL,
2015 .p_encode = (kxdrproc_t) nfs3_xdr_getaclargs,
2016 .p_decode = (kxdrproc_t) nfs3_xdr_getaclres,
2017 .p_arglen = ACL3_getaclargs_sz,
2018 .p_replen = ACL3_getaclres_sz,
2022 [ACLPROC3_SETACL] = {
2023 .p_proc = ACLPROC3_SETACL,
2024 .p_encode = (kxdrproc_t) nfs3_xdr_setaclargs,
2025 .p_decode = (kxdrproc_t) nfs3_xdr_setaclres,
2026 .p_arglen = ACL3_setaclargs_sz,
2027 .p_replen = ACL3_setaclres_sz,
2033 struct rpc_version nfsacl_version3 = {
2035 .nrprocs = sizeof(nfs3_acl_procedures)/
2036 sizeof(nfs3_acl_procedures[0]),
2037 .procs = nfs3_acl_procedures,
2039 #endif /* CONFIG_NFS_V3_ACL */