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)
49 #define NFS3_diropargs_sz (NFS3_fh_sz+NFS3_filename_sz)
51 #define NFS3_getattrargs_sz (NFS3_fh_sz)
52 #define NFS3_setattrargs_sz (NFS3_fh_sz+NFS3_sattr_sz+3)
53 #define NFS3_lookupargs_sz (NFS3_fh_sz+NFS3_filename_sz)
54 #define NFS3_accessargs_sz (NFS3_fh_sz+1)
55 #define NFS3_readlinkargs_sz (NFS3_fh_sz)
56 #define NFS3_readargs_sz (NFS3_fh_sz+3)
57 #define NFS3_writeargs_sz (NFS3_fh_sz+5)
58 #define NFS3_createargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz)
59 #define NFS3_mkdirargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz)
60 #define NFS3_symlinkargs_sz (NFS3_diropargs_sz+1+NFS3_sattr_sz)
61 #define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz)
62 #define NFS3_removeargs_sz (NFS3_fh_sz+NFS3_filename_sz)
63 #define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz)
64 #define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz)
65 #define NFS3_readdirargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+3)
66 #define NFS3_readdirplusargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+4)
67 #define NFS3_commitargs_sz (NFS3_fh_sz+3)
69 #define NFS3_attrstat_sz (1+NFS3_fattr_sz)
70 #define NFS3_wccstat_sz (1+NFS3_wcc_data_sz)
71 #define NFS3_removeres_sz (NFS3_wccstat_sz)
72 #define NFS3_lookupres_sz (1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz))
73 #define NFS3_accessres_sz (1+NFS3_post_op_attr_sz+1)
74 #define NFS3_readlinkres_sz (1+NFS3_post_op_attr_sz+1)
75 #define NFS3_readres_sz (1+NFS3_post_op_attr_sz+3)
76 #define NFS3_writeres_sz (1+NFS3_wcc_data_sz+4)
77 #define NFS3_createres_sz (1+NFS3_fh_sz+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
78 #define NFS3_renameres_sz (1+(2 * NFS3_wcc_data_sz))
79 #define NFS3_linkres_sz (1+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
80 #define NFS3_readdirres_sz (1+NFS3_post_op_attr_sz+2)
81 #define NFS3_fsstatres_sz (1+NFS3_post_op_attr_sz+13)
82 #define NFS3_fsinfores_sz (1+NFS3_post_op_attr_sz+12)
83 #define NFS3_pathconfres_sz (1+NFS3_post_op_attr_sz+6)
84 #define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2)
86 #define ACL3_getaclargs_sz (NFS3_fh_sz+1)
87 #define ACL3_setaclargs_sz (NFS3_fh_sz+1+ \
88 XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
89 #define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+ \
90 XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
91 #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz)
94 * Map file type to S_IFMT bits
96 static const umode_t nfs_type2fmt[] = {
103 [NF3SOCK] = S_IFSOCK,
108 * While encoding arguments, set up the reply buffer in advance to
109 * receive reply data directly into the page cache.
111 static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
112 unsigned int base, unsigned int len,
113 unsigned int bufsize)
115 struct rpc_auth *auth = req->rq_cred->cr_auth;
118 replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
119 xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
123 * Handle decode buffer overflows out-of-line.
125 static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
127 dprintk("NFS: %s prematurely hit the end of our receive buffer. "
128 "Remaining buffer length is %tu words.\n",
129 func, xdr->end - xdr->p);
134 * Common NFS XDR functions as inlines
136 static inline __be32 *
137 xdr_decode_fhandle(__be32 *p, struct nfs_fh *fh)
139 if ((fh->size = ntohl(*p++)) <= NFS3_FHSIZE) {
140 memcpy(fh->data, p, fh->size);
141 return p + XDR_QUADLEN(fh->size);
146 static inline __be32 *
147 xdr_decode_fhandle_stream(struct xdr_stream *xdr, struct nfs_fh *fh)
150 p = xdr_inline_decode(xdr, 4);
153 fh->size = ntohl(*p++);
155 if (fh->size <= NFS3_FHSIZE) {
156 p = xdr_inline_decode(xdr, fh->size);
159 memcpy(fh->data, p, fh->size);
160 return p + XDR_QUADLEN(fh->size);
165 print_overflow_msg(__func__, xdr);
166 return ERR_PTR(-EIO);
170 * Encode/decode time.
172 static inline __be32 *
173 xdr_decode_time3(__be32 *p, struct timespec *timep)
175 timep->tv_sec = ntohl(*p++);
176 timep->tv_nsec = ntohl(*p++);
181 xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
183 unsigned int type, major, minor;
189 fmode = nfs_type2fmt[type];
190 fattr->mode = (ntohl(*p++) & ~S_IFMT) | fmode;
191 fattr->nlink = ntohl(*p++);
192 fattr->uid = ntohl(*p++);
193 fattr->gid = ntohl(*p++);
194 p = xdr_decode_hyper(p, &fattr->size);
195 p = xdr_decode_hyper(p, &fattr->du.nfs3.used);
197 /* Turn remote device info into Linux-specific dev_t */
200 fattr->rdev = MKDEV(major, minor);
201 if (MAJOR(fattr->rdev) != major || MINOR(fattr->rdev) != minor)
204 p = xdr_decode_hyper(p, &fattr->fsid.major);
205 fattr->fsid.minor = 0;
206 p = xdr_decode_hyper(p, &fattr->fileid);
207 p = xdr_decode_time3(p, &fattr->atime);
208 p = xdr_decode_time3(p, &fattr->mtime);
209 p = xdr_decode_time3(p, &fattr->ctime);
211 /* Update the mode bits */
212 fattr->valid |= NFS_ATTR_FATTR_V3;
216 static inline __be32 *
217 xdr_decode_wcc_attr(__be32 *p, struct nfs_fattr *fattr)
219 p = xdr_decode_hyper(p, &fattr->pre_size);
220 p = xdr_decode_time3(p, &fattr->pre_mtime);
221 p = xdr_decode_time3(p, &fattr->pre_ctime);
222 fattr->valid |= NFS_ATTR_FATTR_PRESIZE
223 | NFS_ATTR_FATTR_PREMTIME
224 | NFS_ATTR_FATTR_PRECTIME;
228 static inline __be32 *
229 xdr_decode_post_op_attr(__be32 *p, struct nfs_fattr *fattr)
232 p = xdr_decode_fattr(p, fattr);
236 static inline __be32 *
237 xdr_decode_post_op_attr_stream(struct xdr_stream *xdr, struct nfs_fattr *fattr)
241 p = xdr_inline_decode(xdr, 4);
245 p = xdr_inline_decode(xdr, 84);
248 p = xdr_decode_fattr(p, fattr);
252 print_overflow_msg(__func__, xdr);
253 return ERR_PTR(-EIO);
256 static inline __be32 *
257 xdr_decode_pre_op_attr(__be32 *p, struct nfs_fattr *fattr)
260 return xdr_decode_wcc_attr(p, fattr);
265 static inline __be32 *
266 xdr_decode_wcc_data(__be32 *p, struct nfs_fattr *fattr)
268 p = xdr_decode_pre_op_attr(p, fattr);
269 return xdr_decode_post_op_attr(p, fattr);
274 * Encode/decode NFSv3 basic data types
276 * Basic NFSv3 data types are defined in section 2.5 of RFC 1813:
277 * "NFS Version 3 Protocol Specification".
279 * Not all basic data types have their own encoding and decoding
280 * functions. For run-time efficiency, some data types are encoded
284 static void encode_uint32(struct xdr_stream *xdr, u32 value)
286 __be32 *p = xdr_reserve_space(xdr, 4);
287 *p = cpu_to_be32(value);
290 static int decode_uint32(struct xdr_stream *xdr, u32 *value)
294 p = xdr_inline_decode(xdr, 4);
295 if (unlikely(p == NULL))
297 *value = be32_to_cpup(p);
300 print_overflow_msg(__func__, xdr);
304 static int decode_uint64(struct xdr_stream *xdr, u64 *value)
308 p = xdr_inline_decode(xdr, 8);
309 if (unlikely(p == NULL))
311 xdr_decode_hyper(p, value);
314 print_overflow_msg(__func__, xdr);
321 * typedef uint64 fileid3;
323 static int decode_fileid3(struct xdr_stream *xdr, u64 *fileid)
325 return decode_uint64(xdr, fileid);
331 * typedef string filename3<>;
333 static void encode_filename3(struct xdr_stream *xdr,
334 const char *name, u32 length)
338 BUG_ON(length > NFS3_MAXNAMLEN);
339 p = xdr_reserve_space(xdr, 4 + length);
340 xdr_encode_opaque(p, name, length);
343 static int decode_inline_filename3(struct xdr_stream *xdr,
344 const char **name, u32 *length)
349 p = xdr_inline_decode(xdr, 4);
350 if (unlikely(p == NULL))
352 count = be32_to_cpup(p);
353 if (count > NFS3_MAXNAMLEN)
354 goto out_nametoolong;
355 p = xdr_inline_decode(xdr, count);
356 if (unlikely(p == NULL))
358 *name = (const char *)p;
363 dprintk("NFS: returned filename too long: %u\n", count);
364 return -ENAMETOOLONG;
366 print_overflow_msg(__func__, xdr);
373 * typedef string nfspath3<>;
375 static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages,
378 BUG_ON(length > NFS3_MAXPATHLEN);
379 encode_uint32(xdr, length);
380 xdr_write_pages(xdr, pages, 0, length);
383 static int decode_nfspath3(struct xdr_stream *xdr)
389 p = xdr_inline_decode(xdr, 4);
390 if (unlikely(p == NULL))
392 count = be32_to_cpup(p);
393 if (unlikely(count >= xdr->buf->page_len || count > NFS3_MAXPATHLEN))
394 goto out_nametoolong;
395 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
396 recvd = xdr->buf->len - hdrlen;
397 if (unlikely(count > recvd))
400 xdr_read_pages(xdr, count);
401 xdr_terminate_string(xdr->buf, count);
405 dprintk("NFS: returned pathname too long: %u\n", count);
406 return -ENAMETOOLONG;
408 dprintk("NFS: server cheating in pathname result: "
409 "count %u > recvd %u\n", count, recvd);
412 print_overflow_msg(__func__, xdr);
419 * typedef uint64 cookie3
421 static __be32 *xdr_encode_cookie3(__be32 *p, u64 cookie)
423 return xdr_encode_hyper(p, cookie);
426 static int decode_cookie3(struct xdr_stream *xdr, u64 *cookie)
428 return decode_uint64(xdr, cookie);
434 * typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
436 static __be32 *xdr_encode_cookieverf3(__be32 *p, const __be32 *verifier)
438 memcpy(p, verifier, NFS3_COOKIEVERFSIZE);
439 return p + XDR_QUADLEN(NFS3_COOKIEVERFSIZE);
442 static int decode_cookieverf3(struct xdr_stream *xdr, __be32 *verifier)
446 p = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE);
447 if (unlikely(p == NULL))
449 memcpy(verifier, p, NFS3_COOKIEVERFSIZE);
452 print_overflow_msg(__func__, xdr);
459 * typedef opaque createverf3[NFS3_CREATEVERFSIZE];
461 static void encode_createverf3(struct xdr_stream *xdr, const __be32 *verifier)
465 p = xdr_reserve_space(xdr, NFS3_CREATEVERFSIZE);
466 memcpy(p, verifier, NFS3_CREATEVERFSIZE);
469 static int decode_writeverf3(struct xdr_stream *xdr, __be32 *verifier)
473 p = xdr_inline_decode(xdr, NFS3_WRITEVERFSIZE);
474 if (unlikely(p == NULL))
476 memcpy(verifier, p, NFS3_WRITEVERFSIZE);
479 print_overflow_msg(__func__, xdr);
486 * typedef uint64 size3;
488 static __be32 *xdr_decode_size3(__be32 *p, u64 *size)
490 return xdr_decode_hyper(p, size);
501 #define NFS3_OK NFS_OK
503 static int decode_nfsstat3(struct xdr_stream *xdr, enum nfs_stat *status)
507 p = xdr_inline_decode(xdr, 4);
508 if (unlikely(p == NULL))
510 *status = be32_to_cpup(p);
513 print_overflow_msg(__func__, xdr);
530 static void encode_ftype3(struct xdr_stream *xdr, const u32 type)
532 BUG_ON(type > NF3FIFO);
533 encode_uint32(xdr, type);
544 static void encode_specdata3(struct xdr_stream *xdr, const dev_t rdev)
548 p = xdr_reserve_space(xdr, 8);
549 *p++ = cpu_to_be32(MAJOR(rdev));
550 *p = cpu_to_be32(MINOR(rdev));
557 * opaque data<NFS3_FHSIZE>;
560 static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh)
564 BUG_ON(fh->size > NFS3_FHSIZE);
565 p = xdr_reserve_space(xdr, 4 + fh->size);
566 xdr_encode_opaque(p, fh->data, fh->size);
569 static int decode_nfs_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
574 p = xdr_inline_decode(xdr, 4);
575 if (unlikely(p == NULL))
577 length = be32_to_cpup(p++);
578 if (unlikely(length > NFS3_FHSIZE))
580 p = xdr_inline_decode(xdr, length);
581 if (unlikely(p == NULL))
584 memcpy(fh->data, p, length);
587 dprintk("NFS: file handle size (%u) too big\n", length);
590 print_overflow_msg(__func__, xdr);
594 static void zero_nfs_fh3(struct nfs_fh *fh)
596 memset(fh, 0, sizeof(*fh));
607 static __be32 *xdr_encode_nfstime3(__be32 *p, const struct timespec *timep)
609 *p++ = cpu_to_be32(timep->tv_sec);
610 *p++ = cpu_to_be32(timep->tv_nsec);
619 * SET_TO_SERVER_TIME = 1,
620 * SET_TO_CLIENT_TIME = 2
623 * union set_mode3 switch (bool set_it) {
630 * union set_uid3 switch (bool set_it) {
637 * union set_gid3 switch (bool set_it) {
644 * union set_size3 switch (bool set_it) {
651 * union set_atime switch (time_how set_it) {
652 * case SET_TO_CLIENT_TIME:
658 * union set_mtime switch (time_how set_it) {
659 * case SET_TO_CLIENT_TIME:
674 static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)
680 * In order to make only a single xdr_reserve_space() call,
681 * pre-compute the total number of bytes to be reserved.
682 * Six boolean values, one for each set_foo field, are always
683 * present in the encoded result, so start there.
686 if (attr->ia_valid & ATTR_MODE)
688 if (attr->ia_valid & ATTR_UID)
690 if (attr->ia_valid & ATTR_GID)
692 if (attr->ia_valid & ATTR_SIZE)
694 if (attr->ia_valid & ATTR_ATIME_SET)
696 if (attr->ia_valid & ATTR_MTIME_SET)
698 p = xdr_reserve_space(xdr, nbytes);
700 if (attr->ia_valid & ATTR_MODE) {
702 *p++ = cpu_to_be32(attr->ia_mode & S_IALLUGO);
706 if (attr->ia_valid & ATTR_UID) {
708 *p++ = cpu_to_be32(attr->ia_uid);
712 if (attr->ia_valid & ATTR_GID) {
714 *p++ = cpu_to_be32(attr->ia_gid);
718 if (attr->ia_valid & ATTR_SIZE) {
720 p = xdr_encode_hyper(p, (u64)attr->ia_size);
724 if (attr->ia_valid & ATTR_ATIME_SET) {
726 p = xdr_encode_nfstime3(p, &attr->ia_atime);
727 } else if (attr->ia_valid & ATTR_ATIME) {
732 if (attr->ia_valid & ATTR_MTIME_SET) {
734 xdr_encode_nfstime3(p, &attr->ia_mtime);
735 } else if (attr->ia_valid & ATTR_MTIME) {
760 static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr)
764 p = xdr_inline_decode(xdr, NFS3_fattr_sz << 2);
765 if (unlikely(p == NULL))
767 xdr_decode_fattr(p, fattr);
770 print_overflow_msg(__func__, xdr);
777 * union post_op_attr switch (bool attributes_follow) {
784 static int decode_post_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
788 p = xdr_inline_decode(xdr, 4);
789 if (unlikely(p == NULL))
792 return decode_fattr3(xdr, fattr);
795 print_overflow_msg(__func__, xdr);
807 static int decode_wcc_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
811 p = xdr_inline_decode(xdr, NFS3_wcc_attr_sz << 2);
812 if (unlikely(p == NULL))
814 xdr_decode_wcc_attr(p, fattr);
817 print_overflow_msg(__func__, xdr);
823 * union pre_op_attr switch (bool attributes_follow) {
825 * wcc_attr attributes;
833 * pre_op_attr before;
834 * post_op_attr after;
837 static int decode_pre_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
841 p = xdr_inline_decode(xdr, 4);
842 if (unlikely(p == NULL))
845 return decode_wcc_attr(xdr, fattr);
848 print_overflow_msg(__func__, xdr);
852 static int decode_wcc_data(struct xdr_stream *xdr, struct nfs_fattr *fattr)
856 error = decode_pre_op_attr(xdr, fattr);
859 error = decode_post_op_attr(xdr, fattr);
867 * union post_op_fh3 switch (bool handle_follows) {
874 static int decode_post_op_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
876 __be32 *p = xdr_inline_decode(xdr, 4);
877 if (unlikely(p == NULL))
880 return decode_nfs_fh3(xdr, fh);
884 print_overflow_msg(__func__, xdr);
891 * struct diropargs3 {
896 static void encode_diropargs3(struct xdr_stream *xdr, const struct nfs_fh *fh,
897 const char *name, u32 length)
899 encode_nfs_fh3(xdr, fh);
900 encode_filename3(xdr, name, length);
905 * NFSv3 XDR encode functions
907 * NFSv3 argument types are defined in section 3.3 of RFC 1813:
908 * "NFS Version 3 Protocol Specification".
914 * struct GETATTR3args {
918 static int nfs3_xdr_enc_getattr3args(struct rpc_rqst *req, __be32 *p,
919 const struct nfs_fh *fh)
921 struct xdr_stream xdr;
923 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
924 encode_nfs_fh3(&xdr, fh);
931 * union sattrguard3 switch (bool check) {
933 * nfstime3 obj_ctime;
938 * struct SETATTR3args {
940 * sattr3 new_attributes;
944 static void encode_sattrguard3(struct xdr_stream *xdr,
945 const struct nfs3_sattrargs *args)
950 p = xdr_reserve_space(xdr, 4 + 8);
952 xdr_encode_nfstime3(p, &args->guardtime);
954 p = xdr_reserve_space(xdr, 4);
959 static int nfs3_xdr_enc_setattr3args(struct rpc_rqst *req, __be32 *p,
960 const struct nfs3_sattrargs *args)
962 struct xdr_stream xdr;
964 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
965 encode_nfs_fh3(&xdr, args->fh);
966 encode_sattr3(&xdr, args->sattr);
967 encode_sattrguard3(&xdr, args);
974 * struct LOOKUP3args {
978 static int nfs3_xdr_enc_lookup3args(struct rpc_rqst *req, __be32 *p,
979 const struct nfs3_diropargs *args)
981 struct xdr_stream xdr;
983 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
984 encode_diropargs3(&xdr, args->fh, args->name, args->len);
991 * struct ACCESS3args {
996 static void encode_access3args(struct xdr_stream *xdr,
997 const struct nfs3_accessargs *args)
999 encode_nfs_fh3(xdr, args->fh);
1000 encode_uint32(xdr, args->access);
1003 static int nfs3_xdr_enc_access3args(struct rpc_rqst *req, __be32 *p,
1004 const struct nfs3_accessargs *args)
1006 struct xdr_stream xdr;
1008 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1009 encode_access3args(&xdr, args);
1014 * 3.3.5 READLINK3args
1016 * struct READLINK3args {
1020 static int nfs3_xdr_enc_readlink3args(struct rpc_rqst *req, __be32 *p,
1021 const struct nfs3_readlinkargs *args)
1023 struct xdr_stream xdr;
1025 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1026 encode_nfs_fh3(&xdr, args->fh);
1027 prepare_reply_buffer(req, args->pages, args->pgbase,
1028 args->pglen, NFS3_readlinkres_sz);
1035 * struct READ3args {
1041 static void encode_read3args(struct xdr_stream *xdr,
1042 const struct nfs_readargs *args)
1046 encode_nfs_fh3(xdr, args->fh);
1048 p = xdr_reserve_space(xdr, 8 + 4);
1049 p = xdr_encode_hyper(p, args->offset);
1050 *p = cpu_to_be32(args->count);
1053 static int nfs3_xdr_enc_read3args(struct rpc_rqst *req, __be32 *p,
1054 const struct nfs_readargs *args)
1056 struct xdr_stream xdr;
1058 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1059 encode_read3args(&xdr, args);
1060 prepare_reply_buffer(req, args->pages, args->pgbase,
1061 args->count, NFS3_readres_sz);
1062 req->rq_rcv_buf.flags |= XDRBUF_READ;
1075 * struct WRITE3args {
1079 * stable_how stable;
1083 static void encode_write3args(struct xdr_stream *xdr,
1084 const struct nfs_writeargs *args)
1088 encode_nfs_fh3(xdr, args->fh);
1090 p = xdr_reserve_space(xdr, 8 + 4 + 4 + 4);
1091 p = xdr_encode_hyper(p, args->offset);
1092 *p++ = cpu_to_be32(args->count);
1094 BUG_ON(args->stable > NFS_FILE_SYNC);
1095 *p++ = cpu_to_be32(args->stable);
1097 *p = cpu_to_be32(args->count);
1098 xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
1101 static int nfs3_xdr_enc_write3args(struct rpc_rqst *req, __be32 *p,
1102 const struct nfs_writeargs *args)
1104 struct xdr_stream xdr;
1106 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1107 encode_write3args(&xdr, args);
1108 xdr.buf->flags |= XDRBUF_WRITE;
1115 * enum createmode3 {
1121 * union createhow3 switch (createmode3 mode) {
1124 * sattr3 obj_attributes;
1129 * struct CREATE3args {
1134 static void encode_createhow3(struct xdr_stream *xdr,
1135 const struct nfs3_createargs *args)
1137 encode_uint32(xdr, args->createmode);
1138 switch (args->createmode) {
1139 case NFS3_CREATE_UNCHECKED:
1140 case NFS3_CREATE_GUARDED:
1141 encode_sattr3(xdr, args->sattr);
1143 case NFS3_CREATE_EXCLUSIVE:
1144 encode_createverf3(xdr, args->verifier);
1151 static int nfs3_xdr_enc_create3args(struct rpc_rqst *req, __be32 *p,
1152 const struct nfs3_createargs *args)
1154 struct xdr_stream xdr;
1156 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1157 encode_diropargs3(&xdr, args->fh, args->name, args->len);
1158 encode_createhow3(&xdr, args);
1165 * struct MKDIR3args {
1167 * sattr3 attributes;
1170 static int nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req, __be32 *p,
1171 const struct nfs3_mkdirargs *args)
1173 struct xdr_stream xdr;
1175 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1176 encode_diropargs3(&xdr, args->fh, args->name, args->len);
1177 encode_sattr3(&xdr, args->sattr);
1182 * 3.3.10 SYMLINK3args
1184 * struct symlinkdata3 {
1185 * sattr3 symlink_attributes;
1186 * nfspath3 symlink_data;
1189 * struct SYMLINK3args {
1191 * symlinkdata3 symlink;
1194 static void encode_symlinkdata3(struct xdr_stream *xdr,
1195 const struct nfs3_symlinkargs *args)
1197 encode_sattr3(xdr, args->sattr);
1198 encode_nfspath3(xdr, args->pages, args->pathlen);
1201 static int nfs3_xdr_enc_symlink3args(struct rpc_rqst *req, __be32 *p,
1202 const struct nfs3_symlinkargs *args)
1204 struct xdr_stream xdr;
1206 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1207 encode_diropargs3(&xdr, args->fromfh, args->fromname, args->fromlen);
1208 encode_symlinkdata3(&xdr, args);
1215 * struct devicedata3 {
1216 * sattr3 dev_attributes;
1220 * union mknoddata3 switch (ftype3 type) {
1223 * devicedata3 device;
1226 * sattr3 pipe_attributes;
1231 * struct MKNOD3args {
1236 static void encode_devicedata3(struct xdr_stream *xdr,
1237 const struct nfs3_mknodargs *args)
1239 encode_sattr3(xdr, args->sattr);
1240 encode_specdata3(xdr, args->rdev);
1243 static void encode_mknoddata3(struct xdr_stream *xdr,
1244 const struct nfs3_mknodargs *args)
1246 encode_ftype3(xdr, args->type);
1247 switch (args->type) {
1250 encode_devicedata3(xdr, args);
1254 encode_sattr3(xdr, args->sattr);
1264 static int nfs3_xdr_enc_mknod3args(struct rpc_rqst *req, __be32 *p,
1265 const struct nfs3_mknodargs *args)
1267 struct xdr_stream xdr;
1269 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1270 encode_diropargs3(&xdr, args->fh, args->name, args->len);
1271 encode_mknoddata3(&xdr, args);
1276 * 3.3.12 REMOVE3args
1278 * struct REMOVE3args {
1279 * diropargs3 object;
1282 static int nfs3_xdr_enc_remove3args(struct rpc_rqst *req, __be32 *p,
1283 const struct nfs_removeargs *args)
1285 struct xdr_stream xdr;
1287 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1288 encode_diropargs3(&xdr, args->fh, args->name.name, args->name.len);
1293 * 3.3.14 RENAME3args
1295 * struct RENAME3args {
1300 static int nfs3_xdr_enc_rename3args(struct rpc_rqst *req, __be32 *p,
1301 const struct nfs_renameargs *args)
1303 const struct qstr *old = args->old_name;
1304 const struct qstr *new = args->new_name;
1305 struct xdr_stream xdr;
1307 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1308 encode_diropargs3(&xdr, args->old_dir, old->name, old->len);
1309 encode_diropargs3(&xdr, args->new_dir, new->name, new->len);
1316 * struct LINK3args {
1321 static int nfs3_xdr_enc_link3args(struct rpc_rqst *req, __be32 *p,
1322 const struct nfs3_linkargs *args)
1324 struct xdr_stream xdr;
1326 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1327 encode_nfs_fh3(&xdr, args->fromfh);
1328 encode_diropargs3(&xdr, args->tofh, args->toname, args->tolen);
1333 * 3.3.16 READDIR3args
1335 * struct READDIR3args {
1338 * cookieverf3 cookieverf;
1342 static void encode_readdir3args(struct xdr_stream *xdr,
1343 const struct nfs3_readdirargs *args)
1347 encode_nfs_fh3(xdr, args->fh);
1349 p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4);
1350 p = xdr_encode_cookie3(p, args->cookie);
1351 p = xdr_encode_cookieverf3(p, args->verf);
1352 *p = cpu_to_be32(args->count);
1355 static int nfs3_xdr_enc_readdir3args(struct rpc_rqst *req, __be32 *p,
1356 const struct nfs3_readdirargs *args)
1358 struct xdr_stream xdr;
1360 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1361 encode_readdir3args(&xdr, args);
1362 prepare_reply_buffer(req, args->pages, 0,
1363 args->count, NFS3_readdirres_sz);
1368 * 3.3.17 READDIRPLUS3args
1370 * struct READDIRPLUS3args {
1373 * cookieverf3 cookieverf;
1378 static void encode_readdirplus3args(struct xdr_stream *xdr,
1379 const struct nfs3_readdirargs *args)
1383 encode_nfs_fh3(xdr, args->fh);
1385 p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4 + 4);
1386 p = xdr_encode_cookie3(p, args->cookie);
1387 p = xdr_encode_cookieverf3(p, args->verf);
1390 * readdirplus: need dircount + buffer size.
1391 * We just make sure we make dircount big enough
1393 *p++ = cpu_to_be32(args->count >> 3);
1395 *p = cpu_to_be32(args->count);
1398 static int nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req, __be32 *p,
1399 const struct nfs3_readdirargs *args)
1401 struct xdr_stream xdr;
1403 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1404 encode_readdirplus3args(&xdr, args);
1405 prepare_reply_buffer(req, args->pages, 0,
1406 args->count, NFS3_readdirres_sz);
1411 * Decode the result of a readdir call.
1412 * We just check for syntactical correctness.
1415 nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res)
1417 struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
1418 struct kvec *iov = rcvbuf->head;
1424 status = ntohl(*p++);
1425 /* Decode post_op_attrs */
1426 p = xdr_decode_post_op_attr(p, res->dir_attr);
1428 return nfs_stat_to_errno(status);
1429 /* Decode verifier cookie */
1431 res->verf[0] = *p++;
1432 res->verf[1] = *p++;
1437 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
1438 if (iov->iov_len < hdrlen) {
1439 dprintk("NFS: READDIR reply header overflowed:"
1440 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1441 return -errno_NFSERR_IO;
1442 } else if (iov->iov_len != hdrlen) {
1443 dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
1444 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
1447 pglen = rcvbuf->page_len;
1448 recvd = rcvbuf->len - hdrlen;
1451 page = rcvbuf->pages;
1457 * 3.3.21 COMMIT3args
1459 * struct COMMIT3args {
1465 static void encode_commit3args(struct xdr_stream *xdr,
1466 const struct nfs_writeargs *args)
1470 encode_nfs_fh3(xdr, args->fh);
1472 p = xdr_reserve_space(xdr, 8 + 4);
1473 p = xdr_encode_hyper(p, args->offset);
1474 *p = cpu_to_be32(args->count);
1477 static int nfs3_xdr_enc_commit3args(struct rpc_rqst *req, __be32 *p,
1478 const struct nfs_writeargs *args)
1480 struct xdr_stream xdr;
1482 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1483 encode_commit3args(&xdr, args);
1487 #ifdef CONFIG_NFS_V3_ACL
1489 static int nfs3_xdr_enc_getacl3args(struct rpc_rqst *req, __be32 *p,
1490 const struct nfs3_getaclargs *args)
1492 struct xdr_stream xdr;
1494 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1495 encode_nfs_fh3(&xdr, args->fh);
1496 encode_uint32(&xdr, args->mask);
1497 if (args->mask & (NFS_ACL | NFS_DFACL))
1498 prepare_reply_buffer(req, args->pages, 0,
1499 NFSACL_MAXPAGES << PAGE_SHIFT,
1504 static int nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, __be32 *p,
1505 const struct nfs3_setaclargs *args)
1507 struct xdr_stream xdr;
1511 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1512 encode_nfs_fh3(&xdr, NFS_FH(args->inode));
1513 encode_uint32(&xdr, args->mask);
1514 if (args->npages != 0)
1515 xdr_write_pages(&xdr, args->pages, 0, args->len);
1517 base = req->rq_slen;
1518 error = nfsacl_encode(xdr.buf, base, args->inode,
1519 (args->mask & NFS_ACL) ?
1520 args->acl_access : NULL, 1, 0);
1522 error = nfsacl_encode(xdr.buf, base + error, args->inode,
1523 (args->mask & NFS_DFACL) ?
1524 args->acl_default : NULL, 1,
1530 #endif /* CONFIG_NFS_V3_ACL */
1533 * NFS XDR decode functions
1537 * Decode attrstat reply.
1540 nfs3_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1544 if ((status = ntohl(*p++)))
1545 return nfs_stat_to_errno(status);
1546 xdr_decode_fattr(p, fattr);
1553 * struct GETATTR3resok {
1554 * fattr3 obj_attributes;
1557 * union GETATTR3res switch (nfsstat3 status) {
1559 * GETATTR3resok resok;
1564 static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req, __be32 *p,
1565 struct nfs_fattr *result)
1567 struct xdr_stream xdr;
1568 enum nfs_stat status;
1571 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1572 error = decode_nfsstat3(&xdr, &status);
1573 if (unlikely(error))
1575 if (status != NFS3_OK)
1577 error = decode_fattr3(&xdr, result);
1581 return nfs_stat_to_errno(status);
1585 * Decode status+wcc_data reply
1586 * SATTR, REMOVE, RMDIR
1589 nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1593 if ((status = ntohl(*p++)))
1594 status = nfs_stat_to_errno(status);
1595 xdr_decode_wcc_data(p, fattr);
1602 * struct SETATTR3resok {
1606 * struct SETATTR3resfail {
1610 * union SETATTR3res switch (nfsstat3 status) {
1612 * SETATTR3resok resok;
1614 * SETATTR3resfail resfail;
1617 static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req, __be32 *p,
1618 struct nfs_fattr *result)
1620 struct xdr_stream xdr;
1621 enum nfs_stat status;
1624 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1625 error = decode_nfsstat3(&xdr, &status);
1626 if (unlikely(error))
1628 error = decode_wcc_data(&xdr, result);
1629 if (unlikely(error))
1631 if (status != NFS3_OK)
1636 return nfs_stat_to_errno(status);
1640 nfs3_xdr_removeres(struct rpc_rqst *req, __be32 *p, struct nfs_removeres *res)
1642 return nfs3_xdr_wccstat(req, p, res->dir_attr);
1646 * Decode LOOKUP reply
1649 nfs3_xdr_lookupres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
1653 if ((status = ntohl(*p++))) {
1654 status = nfs_stat_to_errno(status);
1656 if (!(p = xdr_decode_fhandle(p, res->fh)))
1657 return -errno_NFSERR_IO;
1658 p = xdr_decode_post_op_attr(p, res->fattr);
1660 xdr_decode_post_op_attr(p, res->dir_attr);
1667 * struct LOOKUP3resok {
1669 * post_op_attr obj_attributes;
1670 * post_op_attr dir_attributes;
1673 * struct LOOKUP3resfail {
1674 * post_op_attr dir_attributes;
1677 * union LOOKUP3res switch (nfsstat3 status) {
1679 * LOOKUP3resok resok;
1681 * LOOKUP3resfail resfail;
1684 static int nfs3_xdr_dec_lookup3res(struct rpc_rqst *req, __be32 *p,
1685 struct nfs3_diropres *result)
1687 struct xdr_stream xdr;
1688 enum nfs_stat status;
1691 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1692 error = decode_nfsstat3(&xdr, &status);
1693 if (unlikely(error))
1695 if (status != NFS3_OK)
1697 error = decode_nfs_fh3(&xdr, result->fh);
1698 if (unlikely(error))
1700 error = decode_post_op_attr(&xdr, result->fattr);
1701 if (unlikely(error))
1703 error = decode_post_op_attr(&xdr, result->dir_attr);
1707 error = decode_post_op_attr(&xdr, result->dir_attr);
1708 if (unlikely(error))
1710 return nfs_stat_to_errno(status);
1714 * Decode ACCESS reply
1717 nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res)
1719 int status = ntohl(*p++);
1721 p = xdr_decode_post_op_attr(p, res->fattr);
1723 return nfs_stat_to_errno(status);
1724 res->access = ntohl(*p++);
1731 * struct ACCESS3resok {
1732 * post_op_attr obj_attributes;
1736 * struct ACCESS3resfail {
1737 * post_op_attr obj_attributes;
1740 * union ACCESS3res switch (nfsstat3 status) {
1742 * ACCESS3resok resok;
1744 * ACCESS3resfail resfail;
1747 static int nfs3_xdr_dec_access3res(struct rpc_rqst *req, __be32 *p,
1748 struct nfs3_accessres *result)
1750 struct xdr_stream xdr;
1751 enum nfs_stat status;
1754 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1755 error = decode_nfsstat3(&xdr, &status);
1756 if (unlikely(error))
1758 error = decode_post_op_attr(&xdr, result->fattr);
1759 if (unlikely(error))
1761 if (status != NFS3_OK)
1763 error = decode_uint32(&xdr, &result->access);
1767 return nfs_stat_to_errno(status);
1771 * Decode READLINK reply
1774 nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1776 struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
1777 struct kvec *iov = rcvbuf->head;
1782 status = ntohl(*p++);
1783 p = xdr_decode_post_op_attr(p, fattr);
1786 return nfs_stat_to_errno(status);
1788 /* Convert length of symlink */
1790 if (len >= rcvbuf->page_len) {
1791 dprintk("nfs: server returned giant symlink!\n");
1792 return -ENAMETOOLONG;
1795 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
1796 if (iov->iov_len < hdrlen) {
1797 dprintk("NFS: READLINK reply header overflowed:"
1798 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1799 return -errno_NFSERR_IO;
1800 } else if (iov->iov_len != hdrlen) {
1801 dprintk("NFS: READLINK header is short. "
1802 "iovec will be shifted.\n");
1803 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
1805 recvd = req->rq_rcv_buf.len - hdrlen;
1807 dprintk("NFS: server cheating in readlink reply: "
1808 "count %u > recvd %u\n", len, recvd);
1812 xdr_terminate_string(rcvbuf, len);
1817 * 3.3.5 READLINK3res
1819 * struct READLINK3resok {
1820 * post_op_attr symlink_attributes;
1824 * struct READLINK3resfail {
1825 * post_op_attr symlink_attributes;
1828 * union READLINK3res switch (nfsstat3 status) {
1830 * READLINK3resok resok;
1832 * READLINK3resfail resfail;
1835 static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req, __be32 *p,
1836 struct nfs_fattr *result)
1838 struct xdr_stream xdr;
1839 enum nfs_stat status;
1842 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1843 error = decode_nfsstat3(&xdr, &status);
1844 if (unlikely(error))
1846 error = decode_post_op_attr(&xdr, result);
1847 if (unlikely(error))
1849 if (status != NFS3_OK)
1851 error = decode_nfspath3(&xdr);
1855 return nfs_stat_to_errno(status);
1862 nfs3_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
1864 struct kvec *iov = req->rq_rcv_buf.head;
1866 u32 count, ocount, recvd;
1869 status = ntohl(*p++);
1870 p = xdr_decode_post_op_attr(p, res->fattr);
1873 return nfs_stat_to_errno(status);
1875 /* Decode reply count and EOF flag. NFSv3 is somewhat redundant
1876 * in that it puts the count both in the res struct and in the
1877 * opaque data count. */
1878 count = ntohl(*p++);
1879 res->eof = ntohl(*p++);
1880 ocount = ntohl(*p++);
1882 if (ocount != count) {
1883 dprintk("NFS: READ count doesn't match RPC opaque count.\n");
1884 return -errno_NFSERR_IO;
1887 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
1888 if (iov->iov_len < hdrlen) {
1889 dprintk("NFS: READ reply header overflowed:"
1890 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1891 return -errno_NFSERR_IO;
1892 } else if (iov->iov_len != hdrlen) {
1893 dprintk("NFS: READ header is short. iovec will be shifted.\n");
1894 xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
1897 recvd = req->rq_rcv_buf.len - hdrlen;
1898 if (count > recvd) {
1899 dprintk("NFS: server cheating in read reply: "
1900 "count %u > recvd %u\n", count, recvd);
1905 if (count < res->count)
1914 * struct READ3resok {
1915 * post_op_attr file_attributes;
1921 * struct READ3resfail {
1922 * post_op_attr file_attributes;
1925 * union READ3res switch (nfsstat3 status) {
1929 * READ3resfail resfail;
1932 static int decode_read3resok(struct xdr_stream *xdr,
1933 struct nfs_readres *result)
1935 u32 eof, count, ocount, recvd;
1939 p = xdr_inline_decode(xdr, 4 + 4 + 4);
1940 if (unlikely(p == NULL))
1942 count = be32_to_cpup(p++);
1943 eof = be32_to_cpup(p++);
1944 ocount = be32_to_cpup(p++);
1945 if (unlikely(ocount != count))
1947 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
1948 recvd = xdr->buf->len - hdrlen;
1949 if (unlikely(count > recvd))
1953 xdr_read_pages(xdr, count);
1955 result->count = count;
1958 dprintk("NFS: READ count doesn't match length of opaque: "
1959 "count %u != ocount %u\n", count, ocount);
1962 dprintk("NFS: server cheating in read result: "
1963 "count %u > recvd %u\n", count, recvd);
1968 print_overflow_msg(__func__, xdr);
1972 static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, __be32 *p,
1973 struct nfs_readres *result)
1975 struct xdr_stream xdr;
1976 enum nfs_stat status;
1979 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1980 error = decode_nfsstat3(&xdr, &status);
1981 if (unlikely(error))
1983 error = decode_post_op_attr(&xdr, result->fattr);
1984 if (unlikely(error))
1986 if (status != NFS3_OK)
1988 error = decode_read3resok(&xdr, result);
1992 return nfs_stat_to_errno(status);
1996 * Decode WRITE response
1999 nfs3_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
2003 status = ntohl(*p++);
2004 p = xdr_decode_wcc_data(p, res->fattr);
2007 return nfs_stat_to_errno(status);
2009 res->count = ntohl(*p++);
2010 res->verf->committed = (enum nfs3_stable_how)ntohl(*p++);
2011 res->verf->verifier[0] = *p++;
2012 res->verf->verifier[1] = *p++;
2026 * struct WRITE3resok {
2027 * wcc_data file_wcc;
2029 * stable_how committed;
2033 * struct WRITE3resfail {
2034 * wcc_data file_wcc;
2037 * union WRITE3res switch (nfsstat3 status) {
2039 * WRITE3resok resok;
2041 * WRITE3resfail resfail;
2044 static int decode_write3resok(struct xdr_stream *xdr,
2045 struct nfs_writeres *result)
2049 p = xdr_inline_decode(xdr, 4 + 4 + NFS3_WRITEVERFSIZE);
2050 if (unlikely(p == NULL))
2052 result->count = be32_to_cpup(p++);
2053 result->verf->committed = be32_to_cpup(p++);
2054 if (unlikely(result->verf->committed > NFS_FILE_SYNC))
2056 memcpy(result->verf->verifier, p, NFS3_WRITEVERFSIZE);
2057 return result->count;
2059 dprintk("NFS: bad stable_how value: %u\n", result->verf->committed);
2062 print_overflow_msg(__func__, xdr);
2066 static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, __be32 *p,
2067 struct nfs_writeres *result)
2069 struct xdr_stream xdr;
2070 enum nfs_stat status;
2073 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2074 error = decode_nfsstat3(&xdr, &status);
2075 if (unlikely(error))
2077 error = decode_wcc_data(&xdr, result->fattr);
2078 if (unlikely(error))
2080 if (status != NFS3_OK)
2082 error = decode_write3resok(&xdr, result);
2086 return nfs_stat_to_errno(status);
2090 * Decode a CREATE response
2093 nfs3_xdr_createres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
2097 status = ntohl(*p++);
2100 if (!(p = xdr_decode_fhandle(p, res->fh)))
2101 return -errno_NFSERR_IO;
2102 p = xdr_decode_post_op_attr(p, res->fattr);
2104 memset(res->fh, 0, sizeof(*res->fh));
2105 /* Do decode post_op_attr but set it to NULL */
2106 p = xdr_decode_post_op_attr(p, res->fattr);
2107 res->fattr->valid = 0;
2110 status = nfs_stat_to_errno(status);
2112 p = xdr_decode_wcc_data(p, res->dir_attr);
2119 * struct CREATE3resok {
2121 * post_op_attr obj_attributes;
2125 * struct CREATE3resfail {
2129 * union CREATE3res switch (nfsstat3 status) {
2131 * CREATE3resok resok;
2133 * CREATE3resfail resfail;
2136 static int decode_create3resok(struct xdr_stream *xdr,
2137 struct nfs3_diropres *result)
2141 error = decode_post_op_fh3(xdr, result->fh);
2142 if (unlikely(error))
2144 error = decode_post_op_attr(xdr, result->fattr);
2145 if (unlikely(error))
2147 /* The server isn't required to return a file handle.
2148 * If it didn't, force the client to perform a LOOKUP
2149 * to determine the correct file handle and attribute
2150 * values for the new object. */
2151 if (result->fh->size == 0)
2152 result->fattr->valid = 0;
2153 error = decode_wcc_data(xdr, result->dir_attr);
2158 static int nfs3_xdr_dec_create3res(struct rpc_rqst *req, __be32 *p,
2159 struct nfs3_diropres *result)
2161 struct xdr_stream xdr;
2162 enum nfs_stat status;
2165 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2166 error = decode_nfsstat3(&xdr, &status);
2167 if (unlikely(error))
2169 if (status != NFS3_OK)
2171 error = decode_create3resok(&xdr, result);
2175 error = decode_wcc_data(&xdr, result->dir_attr);
2176 if (unlikely(error))
2178 return nfs_stat_to_errno(status);
2184 * struct REMOVE3resok {
2188 * struct REMOVE3resfail {
2192 * union REMOVE3res switch (nfsstat3 status) {
2194 * REMOVE3resok resok;
2196 * REMOVE3resfail resfail;
2199 static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req, __be32 *p,
2200 struct nfs_removeres *result)
2202 struct xdr_stream xdr;
2203 enum nfs_stat status;
2206 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2207 error = decode_nfsstat3(&xdr, &status);
2208 if (unlikely(error))
2210 error = decode_wcc_data(&xdr, result->dir_attr);
2211 if (unlikely(error))
2213 if (status != NFS3_OK)
2218 return nfs_stat_to_errno(status);
2222 * Decode RENAME reply
2225 nfs3_xdr_renameres(struct rpc_rqst *req, __be32 *p, struct nfs_renameres *res)
2229 if ((status = ntohl(*p++)) != 0)
2230 status = nfs_stat_to_errno(status);
2231 p = xdr_decode_wcc_data(p, res->old_fattr);
2232 p = xdr_decode_wcc_data(p, res->new_fattr);
2239 * struct RENAME3resok {
2240 * wcc_data fromdir_wcc;
2241 * wcc_data todir_wcc;
2244 * struct RENAME3resfail {
2245 * wcc_data fromdir_wcc;
2246 * wcc_data todir_wcc;
2249 * union RENAME3res switch (nfsstat3 status) {
2251 * RENAME3resok resok;
2253 * RENAME3resfail resfail;
2256 static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req, __be32 *p,
2257 struct nfs_renameres *result)
2259 struct xdr_stream xdr;
2260 enum nfs_stat status;
2263 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2264 error = decode_nfsstat3(&xdr, &status);
2265 if (unlikely(error))
2267 error = decode_wcc_data(&xdr, result->old_fattr);
2268 if (unlikely(error))
2270 error = decode_wcc_data(&xdr, result->new_fattr);
2271 if (unlikely(error))
2273 if (status != NFS3_OK)
2278 return nfs_stat_to_errno(status);
2285 nfs3_xdr_linkres(struct rpc_rqst *req, __be32 *p, struct nfs3_linkres *res)
2289 if ((status = ntohl(*p++)) != 0)
2290 status = nfs_stat_to_errno(status);
2291 p = xdr_decode_post_op_attr(p, res->fattr);
2292 p = xdr_decode_wcc_data(p, res->dir_attr);
2299 * struct LINK3resok {
2300 * post_op_attr file_attributes;
2301 * wcc_data linkdir_wcc;
2304 * struct LINK3resfail {
2305 * post_op_attr file_attributes;
2306 * wcc_data linkdir_wcc;
2309 * union LINK3res switch (nfsstat3 status) {
2313 * LINK3resfail resfail;
2316 static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, __be32 *p,
2317 struct nfs3_linkres *result)
2319 struct xdr_stream xdr;
2320 enum nfs_stat status;
2323 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2324 error = decode_nfsstat3(&xdr, &status);
2325 if (unlikely(error))
2327 error = decode_post_op_attr(&xdr, result->fattr);
2328 if (unlikely(error))
2330 error = decode_wcc_data(&xdr, result->dir_attr);
2331 if (unlikely(error))
2333 if (status != NFS3_OK)
2338 return nfs_stat_to_errno(status);
2342 * nfs3_decode_dirent - Decode a single NFSv3 directory entry stored in
2343 * the local page cache
2344 * @xdr: XDR stream where entry resides
2345 * @entry: buffer to fill in with entry data
2346 * @server: nfs_server data for this directory
2347 * @plus: boolean indicating whether this should be a readdirplus entry
2349 * Returns the position of the next item in the buffer, or an ERR_PTR.
2351 * This function is not invoked during READDIR reply decoding, but
2352 * rather whenever an application invokes the getdents(2) system call
2353 * on a directory already in our cache.
2361 * fhandle3 filehandle;
2362 * post_op_attr3 attributes;
2363 * entry3 *nextentry;
2367 * struct entryplus3 {
2371 * post_op_attr name_attributes;
2372 * post_op_fh3 name_handle;
2373 * entryplus3 *nextentry;
2376 __be32 *nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
2377 struct nfs_server *server, int plus)
2379 struct nfs_entry old = *entry;
2383 p = xdr_inline_decode(xdr, 4);
2384 if (unlikely(p == NULL))
2386 if (*p == xdr_zero) {
2387 p = xdr_inline_decode(xdr, 4);
2388 if (unlikely(p == NULL))
2391 return ERR_PTR(-EAGAIN);
2393 return ERR_PTR(-EBADCOOKIE);
2396 error = decode_fileid3(xdr, &entry->ino);
2397 if (unlikely(error))
2398 return ERR_PTR(error);
2400 error = decode_inline_filename3(xdr, &entry->name, &entry->len);
2401 if (unlikely(error))
2402 return ERR_PTR(error);
2404 entry->prev_cookie = entry->cookie;
2405 error = decode_cookie3(xdr, &entry->cookie);
2406 if (unlikely(error))
2407 return ERR_PTR(error);
2409 entry->d_type = DT_UNKNOWN;
2412 entry->fattr->valid = 0;
2413 error = decode_post_op_attr(xdr, entry->fattr);
2414 if (unlikely(error))
2415 return ERR_PTR(error);
2416 if (entry->fattr->valid & NFS_ATTR_FATTR_V3)
2417 entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
2419 /* In fact, a post_op_fh3: */
2420 p = xdr_inline_decode(xdr, 4);
2421 if (unlikely(p == NULL))
2423 if (*p != xdr_zero) {
2424 error = decode_nfs_fh3(xdr, entry->fh);
2425 if (unlikely(error)) {
2426 if (error == -E2BIG)
2428 return ERR_PTR(error);
2431 zero_nfs_fh3(entry->fh);
2434 /* Peek at the next entry to see if we're at EOD */
2435 p = xdr_inline_peek(xdr, 4 + 4);
2438 entry->eof = (p[0] == xdr_zero) && (p[1] != xdr_zero);
2442 print_overflow_msg(__func__, xdr);
2443 return ERR_PTR(-EAGAIN);
2445 dprintk("NFS: directory entry contains invalid file handle\n");
2447 return ERR_PTR(-EAGAIN);
2451 * 3.3.16 READDIR3res
2458 * struct READDIR3resok {
2459 * post_op_attr dir_attributes;
2460 * cookieverf3 cookieverf;
2464 * struct READDIR3resfail {
2465 * post_op_attr dir_attributes;
2468 * union READDIR3res switch (nfsstat3 status) {
2470 * READDIR3resok resok;
2472 * READDIR3resfail resfail;
2475 * Read the directory contents into the page cache, but otherwise
2476 * don't touch them. The actual decoding is done by nfs3_decode_entry()
2477 * during subsequent nfs_readdir() calls.
2479 static int decode_dirlist3(struct xdr_stream *xdr)
2484 pglen = xdr->buf->page_len;
2485 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
2486 recvd = xdr->buf->len - hdrlen;
2487 if (unlikely(pglen > recvd))
2490 xdr_read_pages(xdr, pglen);
2493 dprintk("NFS: server cheating in readdir result: "
2494 "pglen %u > recvd %u\n", pglen, recvd);
2499 static int decode_readdir3resok(struct xdr_stream *xdr,
2500 struct nfs3_readdirres *result)
2504 error = decode_post_op_attr(xdr, result->dir_attr);
2505 if (unlikely(error))
2507 /* XXX: do we need to check if result->verf != NULL ? */
2508 error = decode_cookieverf3(xdr, result->verf);
2509 if (unlikely(error))
2511 error = decode_dirlist3(xdr);
2516 static int nfs3_xdr_dec_readdir3res(struct rpc_rqst *req, __be32 *p,
2517 struct nfs3_readdirres *result)
2519 struct xdr_stream xdr;
2520 enum nfs_stat status;
2523 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2524 error = decode_nfsstat3(&xdr, &status);
2525 if (unlikely(error))
2527 if (status != NFS3_OK)
2529 error = decode_readdir3resok(&xdr, result);
2533 error = decode_post_op_attr(&xdr, result->dir_attr);
2534 if (unlikely(error))
2536 return nfs_stat_to_errno(status);
2540 * Decode FSSTAT reply
2543 nfs3_xdr_fsstatres(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *res)
2547 status = ntohl(*p++);
2549 p = xdr_decode_post_op_attr(p, res->fattr);
2551 return nfs_stat_to_errno(status);
2553 p = xdr_decode_hyper(p, &res->tbytes);
2554 p = xdr_decode_hyper(p, &res->fbytes);
2555 p = xdr_decode_hyper(p, &res->abytes);
2556 p = xdr_decode_hyper(p, &res->tfiles);
2557 p = xdr_decode_hyper(p, &res->ffiles);
2558 p = xdr_decode_hyper(p, &res->afiles);
2560 /* ignore invarsec */
2567 * struct FSSTAT3resok {
2568 * post_op_attr obj_attributes;
2578 * struct FSSTAT3resfail {
2579 * post_op_attr obj_attributes;
2582 * union FSSTAT3res switch (nfsstat3 status) {
2584 * FSSTAT3resok resok;
2586 * FSSTAT3resfail resfail;
2589 static int decode_fsstat3resok(struct xdr_stream *xdr,
2590 struct nfs_fsstat *result)
2594 p = xdr_inline_decode(xdr, 8 * 6 + 4);
2595 if (unlikely(p == NULL))
2597 p = xdr_decode_size3(p, &result->tbytes);
2598 p = xdr_decode_size3(p, &result->fbytes);
2599 p = xdr_decode_size3(p, &result->abytes);
2600 p = xdr_decode_size3(p, &result->tfiles);
2601 p = xdr_decode_size3(p, &result->ffiles);
2602 xdr_decode_size3(p, &result->afiles);
2603 /* ignore invarsec */
2606 print_overflow_msg(__func__, xdr);
2610 static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req, __be32 *p,
2611 struct nfs_fsstat *result)
2613 struct xdr_stream xdr;
2614 enum nfs_stat status;
2617 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2618 error = decode_nfsstat3(&xdr, &status);
2619 if (unlikely(error))
2621 error = decode_post_op_attr(&xdr, result->fattr);
2622 if (unlikely(error))
2624 if (status != NFS3_OK)
2626 error = decode_fsstat3resok(&xdr, result);
2630 return nfs_stat_to_errno(status);
2634 * Decode FSINFO reply
2637 nfs3_xdr_fsinfores(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *res)
2641 status = ntohl(*p++);
2643 p = xdr_decode_post_op_attr(p, res->fattr);
2645 return nfs_stat_to_errno(status);
2647 res->rtmax = ntohl(*p++);
2648 res->rtpref = ntohl(*p++);
2649 res->rtmult = ntohl(*p++);
2650 res->wtmax = ntohl(*p++);
2651 res->wtpref = ntohl(*p++);
2652 res->wtmult = ntohl(*p++);
2653 res->dtpref = ntohl(*p++);
2654 p = xdr_decode_hyper(p, &res->maxfilesize);
2655 p = xdr_decode_time3(p, &res->time_delta);
2657 /* ignore properties */
2658 res->lease_time = 0;
2665 * struct FSINFO3resok {
2666 * post_op_attr obj_attributes;
2674 * size3 maxfilesize;
2675 * nfstime3 time_delta;
2676 * uint32 properties;
2679 * struct FSINFO3resfail {
2680 * post_op_attr obj_attributes;
2683 * union FSINFO3res switch (nfsstat3 status) {
2685 * FSINFO3resok resok;
2687 * FSINFO3resfail resfail;
2690 static int decode_fsinfo3resok(struct xdr_stream *xdr,
2691 struct nfs_fsinfo *result)
2695 p = xdr_inline_decode(xdr, 4 * 7 + 8 + 8 + 4);
2696 if (unlikely(p == NULL))
2698 result->rtmax = be32_to_cpup(p++);
2699 result->rtpref = be32_to_cpup(p++);
2700 result->rtmult = be32_to_cpup(p++);
2701 result->wtmax = be32_to_cpup(p++);
2702 result->wtpref = be32_to_cpup(p++);
2703 result->wtmult = be32_to_cpup(p++);
2704 result->dtpref = be32_to_cpup(p++);
2705 p = xdr_decode_size3(p, &result->maxfilesize);
2706 xdr_decode_time3(p, &result->time_delta);
2708 /* ignore properties */
2709 result->lease_time = 0;
2712 print_overflow_msg(__func__, xdr);
2716 static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req, __be32 *p,
2717 struct nfs_fsinfo *result)
2719 struct xdr_stream xdr;
2720 enum nfs_stat status;
2723 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2724 error = decode_nfsstat3(&xdr, &status);
2725 if (unlikely(error))
2727 error = decode_post_op_attr(&xdr, result->fattr);
2728 if (unlikely(error))
2730 if (status != NFS3_OK)
2732 error = decode_fsinfo3resok(&xdr, result);
2736 return nfs_stat_to_errno(status);
2740 * Decode PATHCONF reply
2743 nfs3_xdr_pathconfres(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *res)
2747 status = ntohl(*p++);
2749 p = xdr_decode_post_op_attr(p, res->fattr);
2751 return nfs_stat_to_errno(status);
2752 res->max_link = ntohl(*p++);
2753 res->max_namelen = ntohl(*p++);
2755 /* ignore remaining fields */
2760 * 3.3.20 PATHCONF3res
2762 * struct PATHCONF3resok {
2763 * post_op_attr obj_attributes;
2767 * bool chown_restricted;
2768 * bool case_insensitive;
2769 * bool case_preserving;
2772 * struct PATHCONF3resfail {
2773 * post_op_attr obj_attributes;
2776 * union PATHCONF3res switch (nfsstat3 status) {
2778 * PATHCONF3resok resok;
2780 * PATHCONF3resfail resfail;
2783 static int decode_pathconf3resok(struct xdr_stream *xdr,
2784 struct nfs_pathconf *result)
2788 p = xdr_inline_decode(xdr, 4 * 6);
2789 if (unlikely(p == NULL))
2791 result->max_link = be32_to_cpup(p++);
2792 result->max_namelen = be32_to_cpup(p);
2793 /* ignore remaining fields */
2796 print_overflow_msg(__func__, xdr);
2800 static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req, __be32 *p,
2801 struct nfs_pathconf *result)
2803 struct xdr_stream xdr;
2804 enum nfs_stat status;
2807 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2808 error = decode_nfsstat3(&xdr, &status);
2809 if (unlikely(error))
2811 error = decode_post_op_attr(&xdr, result->fattr);
2812 if (unlikely(error))
2814 if (status != NFS3_OK)
2816 error = decode_pathconf3resok(&xdr, result);
2820 return nfs_stat_to_errno(status);
2824 * Decode COMMIT reply
2827 nfs3_xdr_commitres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
2831 status = ntohl(*p++);
2832 p = xdr_decode_wcc_data(p, res->fattr);
2834 return nfs_stat_to_errno(status);
2836 res->verf->verifier[0] = *p++;
2837 res->verf->verifier[1] = *p++;
2844 * struct COMMIT3resok {
2845 * wcc_data file_wcc;
2849 * struct COMMIT3resfail {
2850 * wcc_data file_wcc;
2853 * union COMMIT3res switch (nfsstat3 status) {
2855 * COMMIT3resok resok;
2857 * COMMIT3resfail resfail;
2860 static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req, __be32 *p,
2861 struct nfs_writeres *result)
2863 struct xdr_stream xdr;
2864 enum nfs_stat status;
2867 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2868 error = decode_nfsstat3(&xdr, &status);
2869 if (unlikely(error))
2871 error = decode_wcc_data(&xdr, result->fattr);
2872 if (unlikely(error))
2874 if (status != NFS3_OK)
2876 error = decode_writeverf3(&xdr, result->verf->verifier);
2880 return nfs_stat_to_errno(status);
2883 #ifdef CONFIG_NFS_V3_ACL
2885 * Decode GETACL reply
2888 nfs3_xdr_getaclres(struct rpc_rqst *req, __be32 *p,
2889 struct nfs3_getaclres *res)
2891 struct xdr_buf *buf = &req->rq_rcv_buf;
2892 int status = ntohl(*p++);
2893 struct posix_acl **acl;
2894 unsigned int *aclcnt;
2898 return nfs_stat_to_errno(status);
2899 p = xdr_decode_post_op_attr(p, res->fattr);
2900 res->mask = ntohl(*p++);
2901 if (res->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
2903 base = (char *)p - (char *)req->rq_rcv_buf.head->iov_base;
2905 acl = (res->mask & NFS_ACL) ? &res->acl_access : NULL;
2906 aclcnt = (res->mask & NFS_ACLCNT) ? &res->acl_access_count : NULL;
2907 err = nfsacl_decode(buf, base, aclcnt, acl);
2909 acl = (res->mask & NFS_DFACL) ? &res->acl_default : NULL;
2910 aclcnt = (res->mask & NFS_DFACLCNT) ? &res->acl_default_count : NULL;
2912 err = nfsacl_decode(buf, base + err, aclcnt, acl);
2913 return (err > 0) ? 0 : err;
2916 static inline int decode_getacl3resok(struct xdr_stream *xdr,
2917 struct nfs3_getaclres *result)
2919 struct posix_acl **acl;
2920 unsigned int *aclcnt;
2924 error = decode_post_op_attr(xdr, result->fattr);
2925 if (unlikely(error))
2927 error = decode_uint32(xdr, &result->mask);
2928 if (unlikely(error))
2931 if (result->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
2934 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
2937 if (result->mask & NFS_ACL)
2938 acl = &result->acl_access;
2940 if (result->mask & NFS_ACLCNT)
2941 aclcnt = &result->acl_access_count;
2942 error = nfsacl_decode(xdr->buf, hdrlen, aclcnt, acl);
2943 if (unlikely(error <= 0))
2947 if (result->mask & NFS_DFACL)
2948 acl = &result->acl_default;
2950 if (result->mask & NFS_DFACLCNT)
2951 aclcnt = &result->acl_default_count;
2952 error = nfsacl_decode(xdr->buf, hdrlen + error, aclcnt, acl);
2953 if (unlikely(error <= 0))
2960 static int nfs3_xdr_dec_getacl3res(struct rpc_rqst *req, __be32 *p,
2961 struct nfs3_getaclres *result)
2963 struct xdr_stream xdr;
2964 enum nfs_stat status;
2967 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2968 error = decode_nfsstat3(&xdr, &status);
2969 if (unlikely(error))
2971 if (status != NFS3_OK)
2973 error = decode_getacl3resok(&xdr, result);
2977 return nfs_stat_to_errno(status);
2981 * Decode setacl reply.
2984 nfs3_xdr_setaclres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
2986 int status = ntohl(*p++);
2989 return nfs_stat_to_errno(status);
2990 xdr_decode_post_op_attr(p, fattr);
2994 static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req, __be32 *p,
2995 struct nfs_fattr *result)
2997 struct xdr_stream xdr;
2998 enum nfs_stat status;
3001 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
3002 error = decode_nfsstat3(&xdr, &status);
3003 if (unlikely(error))
3005 if (status != NFS3_OK)
3007 error = decode_post_op_attr(&xdr, result);
3011 return nfs_stat_to_errno(status);
3014 #endif /* CONFIG_NFS_V3_ACL */
3016 #define PROC(proc, argtype, restype, timer) \
3017 [NFS3PROC_##proc] = { \
3018 .p_proc = NFS3PROC_##proc, \
3019 .p_encode = (kxdrproc_t)nfs3_xdr_enc_##argtype##3args, \
3020 .p_decode = (kxdrproc_t) nfs3_xdr_##restype, \
3021 .p_arglen = NFS3_##argtype##args_sz, \
3022 .p_replen = NFS3_##restype##_sz, \
3024 .p_statidx = NFS3PROC_##proc, \
3028 struct rpc_procinfo nfs3_procedures[] = {
3029 PROC(GETATTR, getattr, attrstat, 1),
3030 PROC(SETATTR, setattr, wccstat, 0),
3031 PROC(LOOKUP, lookup, lookupres, 2),
3032 PROC(ACCESS, access, accessres, 1),
3033 PROC(READLINK, readlink, readlinkres, 3),
3034 PROC(READ, read, readres, 3),
3035 PROC(WRITE, write, writeres, 4),
3036 PROC(CREATE, create, createres, 0),
3037 PROC(MKDIR, mkdir, createres, 0),
3038 PROC(SYMLINK, symlink, createres, 0),
3039 PROC(MKNOD, mknod, createres, 0),
3040 PROC(REMOVE, remove, removeres, 0),
3041 PROC(RMDIR, lookup, wccstat, 0),
3042 PROC(RENAME, rename, renameres, 0),
3043 PROC(LINK, link, linkres, 0),
3044 PROC(READDIR, readdir, readdirres, 3),
3045 PROC(READDIRPLUS, readdirplus, readdirres, 3),
3046 PROC(FSSTAT, getattr, fsstatres, 0),
3047 PROC(FSINFO, getattr, fsinfores, 0),
3048 PROC(PATHCONF, getattr, pathconfres, 0),
3049 PROC(COMMIT, commit, commitres, 5),
3052 struct rpc_version nfs_version3 = {
3054 .nrprocs = ARRAY_SIZE(nfs3_procedures),
3055 .procs = nfs3_procedures
3058 #ifdef CONFIG_NFS_V3_ACL
3059 static struct rpc_procinfo nfs3_acl_procedures[] = {
3060 [ACLPROC3_GETACL] = {
3061 .p_proc = ACLPROC3_GETACL,
3062 .p_encode = (kxdrproc_t)nfs3_xdr_enc_getacl3args,
3063 .p_decode = (kxdrproc_t) nfs3_xdr_getaclres,
3064 .p_arglen = ACL3_getaclargs_sz,
3065 .p_replen = ACL3_getaclres_sz,
3069 [ACLPROC3_SETACL] = {
3070 .p_proc = ACLPROC3_SETACL,
3071 .p_encode = (kxdrproc_t)nfs3_xdr_enc_setacl3args,
3072 .p_decode = (kxdrproc_t) nfs3_xdr_setaclres,
3073 .p_arglen = ACL3_setaclargs_sz,
3074 .p_replen = ACL3_setaclres_sz,
3080 struct rpc_version nfsacl_version3 = {
3082 .nrprocs = sizeof(nfs3_acl_procedures)/
3083 sizeof(nfs3_acl_procedures[0]),
3084 .procs = nfs3_acl_procedures,
3086 #endif /* CONFIG_NFS_V3_ACL */