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_diropargs_sz (NFS3_fh_sz+NFS3_filename_sz)
47 #define NFS3_getattrargs_sz (NFS3_fh_sz)
48 #define NFS3_setattrargs_sz (NFS3_fh_sz+NFS3_sattr_sz+3)
49 #define NFS3_lookupargs_sz (NFS3_fh_sz+NFS3_filename_sz)
50 #define NFS3_accessargs_sz (NFS3_fh_sz+1)
51 #define NFS3_readlinkargs_sz (NFS3_fh_sz)
52 #define NFS3_readargs_sz (NFS3_fh_sz+3)
53 #define NFS3_writeargs_sz (NFS3_fh_sz+5)
54 #define NFS3_createargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz)
55 #define NFS3_mkdirargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz)
56 #define NFS3_symlinkargs_sz (NFS3_diropargs_sz+1+NFS3_sattr_sz)
57 #define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz)
58 #define NFS3_removeargs_sz (NFS3_fh_sz+NFS3_filename_sz)
59 #define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz)
60 #define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz)
61 #define NFS3_readdirargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+3)
62 #define NFS3_readdirplusargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+4)
63 #define NFS3_commitargs_sz (NFS3_fh_sz+3)
65 #define NFS3_getattrres_sz (1+NFS3_fattr_sz)
66 #define NFS3_setattrres_sz (1+NFS3_wcc_data_sz)
67 #define NFS3_removeres_sz (NFS3_setattrres_sz)
68 #define NFS3_lookupres_sz (1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz))
69 #define NFS3_accessres_sz (1+NFS3_post_op_attr_sz+1)
70 #define NFS3_readlinkres_sz (1+NFS3_post_op_attr_sz+1)
71 #define NFS3_readres_sz (1+NFS3_post_op_attr_sz+3)
72 #define NFS3_writeres_sz (1+NFS3_wcc_data_sz+4)
73 #define NFS3_createres_sz (1+NFS3_fh_sz+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
74 #define NFS3_renameres_sz (1+(2 * NFS3_wcc_data_sz))
75 #define NFS3_linkres_sz (1+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
76 #define NFS3_readdirres_sz (1+NFS3_post_op_attr_sz+2)
77 #define NFS3_fsstatres_sz (1+NFS3_post_op_attr_sz+13)
78 #define NFS3_fsinfores_sz (1+NFS3_post_op_attr_sz+12)
79 #define NFS3_pathconfres_sz (1+NFS3_post_op_attr_sz+6)
80 #define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2)
82 #define ACL3_getaclargs_sz (NFS3_fh_sz+1)
83 #define ACL3_setaclargs_sz (NFS3_fh_sz+1+ \
84 XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
85 #define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+ \
86 XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
87 #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz)
90 * Map file type to S_IFMT bits
92 static const umode_t nfs_type2fmt[] = {
104 * While encoding arguments, set up the reply buffer in advance to
105 * receive reply data directly into the page cache.
107 static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
108 unsigned int base, unsigned int len,
109 unsigned int bufsize)
111 struct rpc_auth *auth = req->rq_cred->cr_auth;
114 replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
115 xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
119 * Handle decode buffer overflows out-of-line.
121 static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
123 dprintk("NFS: %s prematurely hit the end of our receive buffer. "
124 "Remaining buffer length is %tu words.\n",
125 func, xdr->end - xdr->p);
130 * Common NFS XDR functions as inlines
132 static inline __be32 *
133 xdr_decode_fhandle(__be32 *p, struct nfs_fh *fh)
135 if ((fh->size = ntohl(*p++)) <= NFS3_FHSIZE) {
136 memcpy(fh->data, p, fh->size);
137 return p + XDR_QUADLEN(fh->size);
142 static inline __be32 *
143 xdr_decode_fhandle_stream(struct xdr_stream *xdr, struct nfs_fh *fh)
146 p = xdr_inline_decode(xdr, 4);
149 fh->size = ntohl(*p++);
151 if (fh->size <= NFS3_FHSIZE) {
152 p = xdr_inline_decode(xdr, fh->size);
155 memcpy(fh->data, p, fh->size);
156 return p + XDR_QUADLEN(fh->size);
161 print_overflow_msg(__func__, xdr);
162 return ERR_PTR(-EIO);
166 * Encode/decode time.
168 static inline __be32 *
169 xdr_decode_time3(__be32 *p, struct timespec *timep)
171 timep->tv_sec = ntohl(*p++);
172 timep->tv_nsec = ntohl(*p++);
177 xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
179 unsigned int type, major, minor;
185 fmode = nfs_type2fmt[type];
186 fattr->mode = (ntohl(*p++) & ~S_IFMT) | fmode;
187 fattr->nlink = ntohl(*p++);
188 fattr->uid = ntohl(*p++);
189 fattr->gid = ntohl(*p++);
190 p = xdr_decode_hyper(p, &fattr->size);
191 p = xdr_decode_hyper(p, &fattr->du.nfs3.used);
193 /* Turn remote device info into Linux-specific dev_t */
196 fattr->rdev = MKDEV(major, minor);
197 if (MAJOR(fattr->rdev) != major || MINOR(fattr->rdev) != minor)
200 p = xdr_decode_hyper(p, &fattr->fsid.major);
201 fattr->fsid.minor = 0;
202 p = xdr_decode_hyper(p, &fattr->fileid);
203 p = xdr_decode_time3(p, &fattr->atime);
204 p = xdr_decode_time3(p, &fattr->mtime);
205 p = xdr_decode_time3(p, &fattr->ctime);
207 /* Update the mode bits */
208 fattr->valid |= NFS_ATTR_FATTR_V3;
212 static inline __be32 *
213 xdr_decode_wcc_attr(__be32 *p, struct nfs_fattr *fattr)
215 p = xdr_decode_hyper(p, &fattr->pre_size);
216 p = xdr_decode_time3(p, &fattr->pre_mtime);
217 p = xdr_decode_time3(p, &fattr->pre_ctime);
218 fattr->valid |= NFS_ATTR_FATTR_PRESIZE
219 | NFS_ATTR_FATTR_PREMTIME
220 | NFS_ATTR_FATTR_PRECTIME;
224 static inline __be32 *
225 xdr_decode_post_op_attr(__be32 *p, struct nfs_fattr *fattr)
228 p = xdr_decode_fattr(p, fattr);
232 static inline __be32 *
233 xdr_decode_post_op_attr_stream(struct xdr_stream *xdr, struct nfs_fattr *fattr)
237 p = xdr_inline_decode(xdr, 4);
241 p = xdr_inline_decode(xdr, 84);
244 p = xdr_decode_fattr(p, fattr);
248 print_overflow_msg(__func__, xdr);
249 return ERR_PTR(-EIO);
252 static inline __be32 *
253 xdr_decode_pre_op_attr(__be32 *p, struct nfs_fattr *fattr)
256 return xdr_decode_wcc_attr(p, fattr);
261 static inline __be32 *
262 xdr_decode_wcc_data(__be32 *p, struct nfs_fattr *fattr)
264 p = xdr_decode_pre_op_attr(p, fattr);
265 return xdr_decode_post_op_attr(p, fattr);
270 * Encode/decode NFSv3 basic data types
272 * Basic NFSv3 data types are defined in section 2.5 of RFC 1813:
273 * "NFS Version 3 Protocol Specification".
275 * Not all basic data types have their own encoding and decoding
276 * functions. For run-time efficiency, some data types are encoded
280 static void encode_uint32(struct xdr_stream *xdr, u32 value)
282 __be32 *p = xdr_reserve_space(xdr, 4);
283 *p = cpu_to_be32(value);
286 static int decode_uint32(struct xdr_stream *xdr, u32 *value)
290 p = xdr_inline_decode(xdr, 4);
291 if (unlikely(p == NULL))
293 *value = be32_to_cpup(p);
296 print_overflow_msg(__func__, xdr);
300 static int decode_uint64(struct xdr_stream *xdr, u64 *value)
304 p = xdr_inline_decode(xdr, 8);
305 if (unlikely(p == NULL))
307 xdr_decode_hyper(p, value);
310 print_overflow_msg(__func__, xdr);
317 * typedef uint64 fileid3;
319 static int decode_fileid3(struct xdr_stream *xdr, u64 *fileid)
321 return decode_uint64(xdr, fileid);
327 * typedef string filename3<>;
329 static void encode_filename3(struct xdr_stream *xdr,
330 const char *name, u32 length)
334 BUG_ON(length > NFS3_MAXNAMLEN);
335 p = xdr_reserve_space(xdr, 4 + length);
336 xdr_encode_opaque(p, name, length);
339 static int decode_inline_filename3(struct xdr_stream *xdr,
340 const char **name, u32 *length)
345 p = xdr_inline_decode(xdr, 4);
346 if (unlikely(p == NULL))
348 count = be32_to_cpup(p);
349 if (count > NFS3_MAXNAMLEN)
350 goto out_nametoolong;
351 p = xdr_inline_decode(xdr, count);
352 if (unlikely(p == NULL))
354 *name = (const char *)p;
359 dprintk("NFS: returned filename too long: %u\n", count);
360 return -ENAMETOOLONG;
362 print_overflow_msg(__func__, xdr);
369 * typedef string nfspath3<>;
371 static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages,
374 BUG_ON(length > NFS3_MAXPATHLEN);
375 encode_uint32(xdr, length);
376 xdr_write_pages(xdr, pages, 0, length);
379 static int decode_nfspath3(struct xdr_stream *xdr)
385 p = xdr_inline_decode(xdr, 4);
386 if (unlikely(p == NULL))
388 count = be32_to_cpup(p);
389 if (unlikely(count >= xdr->buf->page_len || count > NFS3_MAXPATHLEN))
390 goto out_nametoolong;
391 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
392 recvd = xdr->buf->len - hdrlen;
393 if (unlikely(count > recvd))
396 xdr_read_pages(xdr, count);
397 xdr_terminate_string(xdr->buf, count);
401 dprintk("NFS: returned pathname too long: %u\n", count);
402 return -ENAMETOOLONG;
404 dprintk("NFS: server cheating in pathname result: "
405 "count %u > recvd %u\n", count, recvd);
408 print_overflow_msg(__func__, xdr);
415 * typedef uint64 cookie3
417 static __be32 *xdr_encode_cookie3(__be32 *p, u64 cookie)
419 return xdr_encode_hyper(p, cookie);
422 static int decode_cookie3(struct xdr_stream *xdr, u64 *cookie)
424 return decode_uint64(xdr, cookie);
430 * typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
432 static __be32 *xdr_encode_cookieverf3(__be32 *p, const __be32 *verifier)
434 memcpy(p, verifier, NFS3_COOKIEVERFSIZE);
435 return p + XDR_QUADLEN(NFS3_COOKIEVERFSIZE);
438 static int decode_cookieverf3(struct xdr_stream *xdr, __be32 *verifier)
442 p = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE);
443 if (unlikely(p == NULL))
445 memcpy(verifier, p, NFS3_COOKIEVERFSIZE);
448 print_overflow_msg(__func__, xdr);
455 * typedef opaque createverf3[NFS3_CREATEVERFSIZE];
457 static void encode_createverf3(struct xdr_stream *xdr, const __be32 *verifier)
461 p = xdr_reserve_space(xdr, NFS3_CREATEVERFSIZE);
462 memcpy(p, verifier, NFS3_CREATEVERFSIZE);
465 static int decode_writeverf3(struct xdr_stream *xdr, __be32 *verifier)
469 p = xdr_inline_decode(xdr, NFS3_WRITEVERFSIZE);
470 if (unlikely(p == NULL))
472 memcpy(verifier, p, NFS3_WRITEVERFSIZE);
475 print_overflow_msg(__func__, xdr);
482 * typedef uint64 size3;
484 static __be32 *xdr_decode_size3(__be32 *p, u64 *size)
486 return xdr_decode_hyper(p, size);
497 #define NFS3_OK NFS_OK
499 static int decode_nfsstat3(struct xdr_stream *xdr, enum nfs_stat *status)
503 p = xdr_inline_decode(xdr, 4);
504 if (unlikely(p == NULL))
506 *status = be32_to_cpup(p);
509 print_overflow_msg(__func__, xdr);
526 static void encode_ftype3(struct xdr_stream *xdr, const u32 type)
528 BUG_ON(type > NF3FIFO);
529 encode_uint32(xdr, type);
540 static void encode_specdata3(struct xdr_stream *xdr, const dev_t rdev)
544 p = xdr_reserve_space(xdr, 8);
545 *p++ = cpu_to_be32(MAJOR(rdev));
546 *p = cpu_to_be32(MINOR(rdev));
553 * opaque data<NFS3_FHSIZE>;
556 static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh)
560 BUG_ON(fh->size > NFS3_FHSIZE);
561 p = xdr_reserve_space(xdr, 4 + fh->size);
562 xdr_encode_opaque(p, fh->data, fh->size);
565 static int decode_nfs_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
570 p = xdr_inline_decode(xdr, 4);
571 if (unlikely(p == NULL))
573 length = be32_to_cpup(p++);
574 if (unlikely(length > NFS3_FHSIZE))
576 p = xdr_inline_decode(xdr, length);
577 if (unlikely(p == NULL))
580 memcpy(fh->data, p, length);
583 dprintk("NFS: file handle size (%u) too big\n", length);
586 print_overflow_msg(__func__, xdr);
590 static void zero_nfs_fh3(struct nfs_fh *fh)
592 memset(fh, 0, sizeof(*fh));
603 static __be32 *xdr_encode_nfstime3(__be32 *p, const struct timespec *timep)
605 *p++ = cpu_to_be32(timep->tv_sec);
606 *p++ = cpu_to_be32(timep->tv_nsec);
615 * SET_TO_SERVER_TIME = 1,
616 * SET_TO_CLIENT_TIME = 2
619 * union set_mode3 switch (bool set_it) {
626 * union set_uid3 switch (bool set_it) {
633 * union set_gid3 switch (bool set_it) {
640 * union set_size3 switch (bool set_it) {
647 * union set_atime switch (time_how set_it) {
648 * case SET_TO_CLIENT_TIME:
654 * union set_mtime switch (time_how set_it) {
655 * case SET_TO_CLIENT_TIME:
670 static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)
676 * In order to make only a single xdr_reserve_space() call,
677 * pre-compute the total number of bytes to be reserved.
678 * Six boolean values, one for each set_foo field, are always
679 * present in the encoded result, so start there.
682 if (attr->ia_valid & ATTR_MODE)
684 if (attr->ia_valid & ATTR_UID)
686 if (attr->ia_valid & ATTR_GID)
688 if (attr->ia_valid & ATTR_SIZE)
690 if (attr->ia_valid & ATTR_ATIME_SET)
692 if (attr->ia_valid & ATTR_MTIME_SET)
694 p = xdr_reserve_space(xdr, nbytes);
696 if (attr->ia_valid & ATTR_MODE) {
698 *p++ = cpu_to_be32(attr->ia_mode & S_IALLUGO);
702 if (attr->ia_valid & ATTR_UID) {
704 *p++ = cpu_to_be32(attr->ia_uid);
708 if (attr->ia_valid & ATTR_GID) {
710 *p++ = cpu_to_be32(attr->ia_gid);
714 if (attr->ia_valid & ATTR_SIZE) {
716 p = xdr_encode_hyper(p, (u64)attr->ia_size);
720 if (attr->ia_valid & ATTR_ATIME_SET) {
722 p = xdr_encode_nfstime3(p, &attr->ia_atime);
723 } else if (attr->ia_valid & ATTR_ATIME) {
728 if (attr->ia_valid & ATTR_MTIME_SET) {
730 xdr_encode_nfstime3(p, &attr->ia_mtime);
731 } else if (attr->ia_valid & ATTR_MTIME) {
756 static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr)
760 p = xdr_inline_decode(xdr, NFS3_fattr_sz << 2);
761 if (unlikely(p == NULL))
763 xdr_decode_fattr(p, fattr);
766 print_overflow_msg(__func__, xdr);
773 * union post_op_attr switch (bool attributes_follow) {
780 static int decode_post_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
784 p = xdr_inline_decode(xdr, 4);
785 if (unlikely(p == NULL))
788 return decode_fattr3(xdr, fattr);
791 print_overflow_msg(__func__, xdr);
803 static int decode_wcc_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
807 p = xdr_inline_decode(xdr, NFS3_wcc_attr_sz << 2);
808 if (unlikely(p == NULL))
810 xdr_decode_wcc_attr(p, fattr);
813 print_overflow_msg(__func__, xdr);
819 * union pre_op_attr switch (bool attributes_follow) {
821 * wcc_attr attributes;
829 * pre_op_attr before;
830 * post_op_attr after;
833 static int decode_pre_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
837 p = xdr_inline_decode(xdr, 4);
838 if (unlikely(p == NULL))
841 return decode_wcc_attr(xdr, fattr);
844 print_overflow_msg(__func__, xdr);
848 static int decode_wcc_data(struct xdr_stream *xdr, struct nfs_fattr *fattr)
852 error = decode_pre_op_attr(xdr, fattr);
855 error = decode_post_op_attr(xdr, fattr);
863 * union post_op_fh3 switch (bool handle_follows) {
870 static int decode_post_op_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
872 __be32 *p = xdr_inline_decode(xdr, 4);
873 if (unlikely(p == NULL))
876 return decode_nfs_fh3(xdr, fh);
880 print_overflow_msg(__func__, xdr);
887 * struct diropargs3 {
892 static void encode_diropargs3(struct xdr_stream *xdr, const struct nfs_fh *fh,
893 const char *name, u32 length)
895 encode_nfs_fh3(xdr, fh);
896 encode_filename3(xdr, name, length);
901 * NFSv3 XDR encode functions
903 * NFSv3 argument types are defined in section 3.3 of RFC 1813:
904 * "NFS Version 3 Protocol Specification".
910 * struct GETATTR3args {
914 static int nfs3_xdr_enc_getattr3args(struct rpc_rqst *req, __be32 *p,
915 const struct nfs_fh *fh)
917 struct xdr_stream xdr;
919 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
920 encode_nfs_fh3(&xdr, fh);
927 * union sattrguard3 switch (bool check) {
929 * nfstime3 obj_ctime;
934 * struct SETATTR3args {
936 * sattr3 new_attributes;
940 static void encode_sattrguard3(struct xdr_stream *xdr,
941 const struct nfs3_sattrargs *args)
946 p = xdr_reserve_space(xdr, 4 + 8);
948 xdr_encode_nfstime3(p, &args->guardtime);
950 p = xdr_reserve_space(xdr, 4);
955 static int nfs3_xdr_enc_setattr3args(struct rpc_rqst *req, __be32 *p,
956 const struct nfs3_sattrargs *args)
958 struct xdr_stream xdr;
960 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
961 encode_nfs_fh3(&xdr, args->fh);
962 encode_sattr3(&xdr, args->sattr);
963 encode_sattrguard3(&xdr, args);
970 * struct LOOKUP3args {
974 static int nfs3_xdr_enc_lookup3args(struct rpc_rqst *req, __be32 *p,
975 const struct nfs3_diropargs *args)
977 struct xdr_stream xdr;
979 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
980 encode_diropargs3(&xdr, args->fh, args->name, args->len);
987 * struct ACCESS3args {
992 static void encode_access3args(struct xdr_stream *xdr,
993 const struct nfs3_accessargs *args)
995 encode_nfs_fh3(xdr, args->fh);
996 encode_uint32(xdr, args->access);
999 static int nfs3_xdr_enc_access3args(struct rpc_rqst *req, __be32 *p,
1000 const struct nfs3_accessargs *args)
1002 struct xdr_stream xdr;
1004 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1005 encode_access3args(&xdr, args);
1010 * 3.3.5 READLINK3args
1012 * struct READLINK3args {
1016 static int nfs3_xdr_enc_readlink3args(struct rpc_rqst *req, __be32 *p,
1017 const struct nfs3_readlinkargs *args)
1019 struct xdr_stream xdr;
1021 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1022 encode_nfs_fh3(&xdr, args->fh);
1023 prepare_reply_buffer(req, args->pages, args->pgbase,
1024 args->pglen, NFS3_readlinkres_sz);
1031 * struct READ3args {
1037 static void encode_read3args(struct xdr_stream *xdr,
1038 const struct nfs_readargs *args)
1042 encode_nfs_fh3(xdr, args->fh);
1044 p = xdr_reserve_space(xdr, 8 + 4);
1045 p = xdr_encode_hyper(p, args->offset);
1046 *p = cpu_to_be32(args->count);
1049 static int nfs3_xdr_enc_read3args(struct rpc_rqst *req, __be32 *p,
1050 const struct nfs_readargs *args)
1052 struct xdr_stream xdr;
1054 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1055 encode_read3args(&xdr, args);
1056 prepare_reply_buffer(req, args->pages, args->pgbase,
1057 args->count, NFS3_readres_sz);
1058 req->rq_rcv_buf.flags |= XDRBUF_READ;
1071 * struct WRITE3args {
1075 * stable_how stable;
1079 static void encode_write3args(struct xdr_stream *xdr,
1080 const struct nfs_writeargs *args)
1084 encode_nfs_fh3(xdr, args->fh);
1086 p = xdr_reserve_space(xdr, 8 + 4 + 4 + 4);
1087 p = xdr_encode_hyper(p, args->offset);
1088 *p++ = cpu_to_be32(args->count);
1090 BUG_ON(args->stable > NFS_FILE_SYNC);
1091 *p++ = cpu_to_be32(args->stable);
1093 *p = cpu_to_be32(args->count);
1094 xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
1097 static int nfs3_xdr_enc_write3args(struct rpc_rqst *req, __be32 *p,
1098 const struct nfs_writeargs *args)
1100 struct xdr_stream xdr;
1102 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1103 encode_write3args(&xdr, args);
1104 xdr.buf->flags |= XDRBUF_WRITE;
1111 * enum createmode3 {
1117 * union createhow3 switch (createmode3 mode) {
1120 * sattr3 obj_attributes;
1125 * struct CREATE3args {
1130 static void encode_createhow3(struct xdr_stream *xdr,
1131 const struct nfs3_createargs *args)
1133 encode_uint32(xdr, args->createmode);
1134 switch (args->createmode) {
1135 case NFS3_CREATE_UNCHECKED:
1136 case NFS3_CREATE_GUARDED:
1137 encode_sattr3(xdr, args->sattr);
1139 case NFS3_CREATE_EXCLUSIVE:
1140 encode_createverf3(xdr, args->verifier);
1147 static int nfs3_xdr_enc_create3args(struct rpc_rqst *req, __be32 *p,
1148 const struct nfs3_createargs *args)
1150 struct xdr_stream xdr;
1152 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1153 encode_diropargs3(&xdr, args->fh, args->name, args->len);
1154 encode_createhow3(&xdr, args);
1161 * struct MKDIR3args {
1163 * sattr3 attributes;
1166 static int nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req, __be32 *p,
1167 const struct nfs3_mkdirargs *args)
1169 struct xdr_stream xdr;
1171 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1172 encode_diropargs3(&xdr, args->fh, args->name, args->len);
1173 encode_sattr3(&xdr, args->sattr);
1178 * 3.3.10 SYMLINK3args
1180 * struct symlinkdata3 {
1181 * sattr3 symlink_attributes;
1182 * nfspath3 symlink_data;
1185 * struct SYMLINK3args {
1187 * symlinkdata3 symlink;
1190 static void encode_symlinkdata3(struct xdr_stream *xdr,
1191 const struct nfs3_symlinkargs *args)
1193 encode_sattr3(xdr, args->sattr);
1194 encode_nfspath3(xdr, args->pages, args->pathlen);
1197 static int nfs3_xdr_enc_symlink3args(struct rpc_rqst *req, __be32 *p,
1198 const struct nfs3_symlinkargs *args)
1200 struct xdr_stream xdr;
1202 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1203 encode_diropargs3(&xdr, args->fromfh, args->fromname, args->fromlen);
1204 encode_symlinkdata3(&xdr, args);
1211 * struct devicedata3 {
1212 * sattr3 dev_attributes;
1216 * union mknoddata3 switch (ftype3 type) {
1219 * devicedata3 device;
1222 * sattr3 pipe_attributes;
1227 * struct MKNOD3args {
1232 static void encode_devicedata3(struct xdr_stream *xdr,
1233 const struct nfs3_mknodargs *args)
1235 encode_sattr3(xdr, args->sattr);
1236 encode_specdata3(xdr, args->rdev);
1239 static void encode_mknoddata3(struct xdr_stream *xdr,
1240 const struct nfs3_mknodargs *args)
1242 encode_ftype3(xdr, args->type);
1243 switch (args->type) {
1246 encode_devicedata3(xdr, args);
1250 encode_sattr3(xdr, args->sattr);
1260 static int nfs3_xdr_enc_mknod3args(struct rpc_rqst *req, __be32 *p,
1261 const struct nfs3_mknodargs *args)
1263 struct xdr_stream xdr;
1265 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1266 encode_diropargs3(&xdr, args->fh, args->name, args->len);
1267 encode_mknoddata3(&xdr, args);
1272 * 3.3.12 REMOVE3args
1274 * struct REMOVE3args {
1275 * diropargs3 object;
1278 static int nfs3_xdr_enc_remove3args(struct rpc_rqst *req, __be32 *p,
1279 const struct nfs_removeargs *args)
1281 struct xdr_stream xdr;
1283 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1284 encode_diropargs3(&xdr, args->fh, args->name.name, args->name.len);
1289 * 3.3.14 RENAME3args
1291 * struct RENAME3args {
1296 static int nfs3_xdr_enc_rename3args(struct rpc_rqst *req, __be32 *p,
1297 const struct nfs_renameargs *args)
1299 const struct qstr *old = args->old_name;
1300 const struct qstr *new = args->new_name;
1301 struct xdr_stream xdr;
1303 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1304 encode_diropargs3(&xdr, args->old_dir, old->name, old->len);
1305 encode_diropargs3(&xdr, args->new_dir, new->name, new->len);
1312 * struct LINK3args {
1317 static int nfs3_xdr_enc_link3args(struct rpc_rqst *req, __be32 *p,
1318 const struct nfs3_linkargs *args)
1320 struct xdr_stream xdr;
1322 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1323 encode_nfs_fh3(&xdr, args->fromfh);
1324 encode_diropargs3(&xdr, args->tofh, args->toname, args->tolen);
1329 * 3.3.16 READDIR3args
1331 * struct READDIR3args {
1334 * cookieverf3 cookieverf;
1338 static void encode_readdir3args(struct xdr_stream *xdr,
1339 const struct nfs3_readdirargs *args)
1343 encode_nfs_fh3(xdr, args->fh);
1345 p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4);
1346 p = xdr_encode_cookie3(p, args->cookie);
1347 p = xdr_encode_cookieverf3(p, args->verf);
1348 *p = cpu_to_be32(args->count);
1351 static int nfs3_xdr_enc_readdir3args(struct rpc_rqst *req, __be32 *p,
1352 const struct nfs3_readdirargs *args)
1354 struct xdr_stream xdr;
1356 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1357 encode_readdir3args(&xdr, args);
1358 prepare_reply_buffer(req, args->pages, 0,
1359 args->count, NFS3_readdirres_sz);
1364 * 3.3.17 READDIRPLUS3args
1366 * struct READDIRPLUS3args {
1369 * cookieverf3 cookieverf;
1374 static void encode_readdirplus3args(struct xdr_stream *xdr,
1375 const struct nfs3_readdirargs *args)
1379 encode_nfs_fh3(xdr, args->fh);
1381 p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4 + 4);
1382 p = xdr_encode_cookie3(p, args->cookie);
1383 p = xdr_encode_cookieverf3(p, args->verf);
1386 * readdirplus: need dircount + buffer size.
1387 * We just make sure we make dircount big enough
1389 *p++ = cpu_to_be32(args->count >> 3);
1391 *p = cpu_to_be32(args->count);
1394 static int nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req, __be32 *p,
1395 const struct nfs3_readdirargs *args)
1397 struct xdr_stream xdr;
1399 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1400 encode_readdirplus3args(&xdr, args);
1401 prepare_reply_buffer(req, args->pages, 0,
1402 args->count, NFS3_readdirres_sz);
1407 * Decode the result of a readdir call.
1408 * We just check for syntactical correctness.
1411 nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res)
1413 struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
1414 struct kvec *iov = rcvbuf->head;
1420 status = ntohl(*p++);
1421 /* Decode post_op_attrs */
1422 p = xdr_decode_post_op_attr(p, res->dir_attr);
1424 return nfs_stat_to_errno(status);
1425 /* Decode verifier cookie */
1427 res->verf[0] = *p++;
1428 res->verf[1] = *p++;
1433 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
1434 if (iov->iov_len < hdrlen) {
1435 dprintk("NFS: READDIR reply header overflowed:"
1436 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1437 return -errno_NFSERR_IO;
1438 } else if (iov->iov_len != hdrlen) {
1439 dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
1440 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
1443 pglen = rcvbuf->page_len;
1444 recvd = rcvbuf->len - hdrlen;
1447 page = rcvbuf->pages;
1453 * 3.3.21 COMMIT3args
1455 * struct COMMIT3args {
1461 static void encode_commit3args(struct xdr_stream *xdr,
1462 const struct nfs_writeargs *args)
1466 encode_nfs_fh3(xdr, args->fh);
1468 p = xdr_reserve_space(xdr, 8 + 4);
1469 p = xdr_encode_hyper(p, args->offset);
1470 *p = cpu_to_be32(args->count);
1473 static int nfs3_xdr_enc_commit3args(struct rpc_rqst *req, __be32 *p,
1474 const struct nfs_writeargs *args)
1476 struct xdr_stream xdr;
1478 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1479 encode_commit3args(&xdr, args);
1483 #ifdef CONFIG_NFS_V3_ACL
1485 static int nfs3_xdr_enc_getacl3args(struct rpc_rqst *req, __be32 *p,
1486 const struct nfs3_getaclargs *args)
1488 struct xdr_stream xdr;
1490 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1491 encode_nfs_fh3(&xdr, args->fh);
1492 encode_uint32(&xdr, args->mask);
1493 if (args->mask & (NFS_ACL | NFS_DFACL))
1494 prepare_reply_buffer(req, args->pages, 0,
1495 NFSACL_MAXPAGES << PAGE_SHIFT,
1500 static int nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, __be32 *p,
1501 const struct nfs3_setaclargs *args)
1503 struct xdr_stream xdr;
1507 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1508 encode_nfs_fh3(&xdr, NFS_FH(args->inode));
1509 encode_uint32(&xdr, args->mask);
1510 if (args->npages != 0)
1511 xdr_write_pages(&xdr, args->pages, 0, args->len);
1513 base = req->rq_slen;
1514 error = nfsacl_encode(xdr.buf, base, args->inode,
1515 (args->mask & NFS_ACL) ?
1516 args->acl_access : NULL, 1, 0);
1518 error = nfsacl_encode(xdr.buf, base + error, args->inode,
1519 (args->mask & NFS_DFACL) ?
1520 args->acl_default : NULL, 1,
1526 #endif /* CONFIG_NFS_V3_ACL */
1529 * NFS XDR decode functions
1533 * Decode attrstat reply.
1536 nfs3_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1540 if ((status = ntohl(*p++)))
1541 return nfs_stat_to_errno(status);
1542 xdr_decode_fattr(p, fattr);
1549 * struct GETATTR3resok {
1550 * fattr3 obj_attributes;
1553 * union GETATTR3res switch (nfsstat3 status) {
1555 * GETATTR3resok resok;
1560 static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req, __be32 *p,
1561 struct nfs_fattr *result)
1563 struct xdr_stream xdr;
1564 enum nfs_stat status;
1567 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1568 error = decode_nfsstat3(&xdr, &status);
1569 if (unlikely(error))
1571 if (status != NFS3_OK)
1573 error = decode_fattr3(&xdr, result);
1577 return nfs_stat_to_errno(status);
1581 * Decode status+wcc_data reply
1582 * SATTR, REMOVE, RMDIR
1585 nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1589 if ((status = ntohl(*p++)))
1590 status = nfs_stat_to_errno(status);
1591 xdr_decode_wcc_data(p, fattr);
1598 * struct SETATTR3resok {
1602 * struct SETATTR3resfail {
1606 * union SETATTR3res switch (nfsstat3 status) {
1608 * SETATTR3resok resok;
1610 * SETATTR3resfail resfail;
1613 static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req, __be32 *p,
1614 struct nfs_fattr *result)
1616 struct xdr_stream xdr;
1617 enum nfs_stat status;
1620 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1621 error = decode_nfsstat3(&xdr, &status);
1622 if (unlikely(error))
1624 error = decode_wcc_data(&xdr, result);
1625 if (unlikely(error))
1627 if (status != NFS3_OK)
1632 return nfs_stat_to_errno(status);
1636 nfs3_xdr_removeres(struct rpc_rqst *req, __be32 *p, struct nfs_removeres *res)
1638 return nfs3_xdr_wccstat(req, p, res->dir_attr);
1642 * Decode LOOKUP reply
1645 nfs3_xdr_lookupres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
1649 if ((status = ntohl(*p++))) {
1650 status = nfs_stat_to_errno(status);
1652 if (!(p = xdr_decode_fhandle(p, res->fh)))
1653 return -errno_NFSERR_IO;
1654 p = xdr_decode_post_op_attr(p, res->fattr);
1656 xdr_decode_post_op_attr(p, res->dir_attr);
1663 * struct LOOKUP3resok {
1665 * post_op_attr obj_attributes;
1666 * post_op_attr dir_attributes;
1669 * struct LOOKUP3resfail {
1670 * post_op_attr dir_attributes;
1673 * union LOOKUP3res switch (nfsstat3 status) {
1675 * LOOKUP3resok resok;
1677 * LOOKUP3resfail resfail;
1680 static int nfs3_xdr_dec_lookup3res(struct rpc_rqst *req, __be32 *p,
1681 struct nfs3_diropres *result)
1683 struct xdr_stream xdr;
1684 enum nfs_stat status;
1687 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1688 error = decode_nfsstat3(&xdr, &status);
1689 if (unlikely(error))
1691 if (status != NFS3_OK)
1693 error = decode_nfs_fh3(&xdr, result->fh);
1694 if (unlikely(error))
1696 error = decode_post_op_attr(&xdr, result->fattr);
1697 if (unlikely(error))
1699 error = decode_post_op_attr(&xdr, result->dir_attr);
1703 error = decode_post_op_attr(&xdr, result->dir_attr);
1704 if (unlikely(error))
1706 return nfs_stat_to_errno(status);
1710 * Decode ACCESS reply
1713 nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res)
1715 int status = ntohl(*p++);
1717 p = xdr_decode_post_op_attr(p, res->fattr);
1719 return nfs_stat_to_errno(status);
1720 res->access = ntohl(*p++);
1727 * struct ACCESS3resok {
1728 * post_op_attr obj_attributes;
1732 * struct ACCESS3resfail {
1733 * post_op_attr obj_attributes;
1736 * union ACCESS3res switch (nfsstat3 status) {
1738 * ACCESS3resok resok;
1740 * ACCESS3resfail resfail;
1743 static int nfs3_xdr_dec_access3res(struct rpc_rqst *req, __be32 *p,
1744 struct nfs3_accessres *result)
1746 struct xdr_stream xdr;
1747 enum nfs_stat status;
1750 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1751 error = decode_nfsstat3(&xdr, &status);
1752 if (unlikely(error))
1754 error = decode_post_op_attr(&xdr, result->fattr);
1755 if (unlikely(error))
1757 if (status != NFS3_OK)
1759 error = decode_uint32(&xdr, &result->access);
1763 return nfs_stat_to_errno(status);
1767 * Decode READLINK reply
1770 nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1772 struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
1773 struct kvec *iov = rcvbuf->head;
1778 status = ntohl(*p++);
1779 p = xdr_decode_post_op_attr(p, fattr);
1782 return nfs_stat_to_errno(status);
1784 /* Convert length of symlink */
1786 if (len >= rcvbuf->page_len) {
1787 dprintk("nfs: server returned giant symlink!\n");
1788 return -ENAMETOOLONG;
1791 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
1792 if (iov->iov_len < hdrlen) {
1793 dprintk("NFS: READLINK reply header overflowed:"
1794 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1795 return -errno_NFSERR_IO;
1796 } else if (iov->iov_len != hdrlen) {
1797 dprintk("NFS: READLINK header is short. "
1798 "iovec will be shifted.\n");
1799 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
1801 recvd = req->rq_rcv_buf.len - hdrlen;
1803 dprintk("NFS: server cheating in readlink reply: "
1804 "count %u > recvd %u\n", len, recvd);
1808 xdr_terminate_string(rcvbuf, len);
1813 * 3.3.5 READLINK3res
1815 * struct READLINK3resok {
1816 * post_op_attr symlink_attributes;
1820 * struct READLINK3resfail {
1821 * post_op_attr symlink_attributes;
1824 * union READLINK3res switch (nfsstat3 status) {
1826 * READLINK3resok resok;
1828 * READLINK3resfail resfail;
1831 static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req, __be32 *p,
1832 struct nfs_fattr *result)
1834 struct xdr_stream xdr;
1835 enum nfs_stat status;
1838 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1839 error = decode_nfsstat3(&xdr, &status);
1840 if (unlikely(error))
1842 error = decode_post_op_attr(&xdr, result);
1843 if (unlikely(error))
1845 if (status != NFS3_OK)
1847 error = decode_nfspath3(&xdr);
1851 return nfs_stat_to_errno(status);
1858 nfs3_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
1860 struct kvec *iov = req->rq_rcv_buf.head;
1862 u32 count, ocount, recvd;
1865 status = ntohl(*p++);
1866 p = xdr_decode_post_op_attr(p, res->fattr);
1869 return nfs_stat_to_errno(status);
1871 /* Decode reply count and EOF flag. NFSv3 is somewhat redundant
1872 * in that it puts the count both in the res struct and in the
1873 * opaque data count. */
1874 count = ntohl(*p++);
1875 res->eof = ntohl(*p++);
1876 ocount = ntohl(*p++);
1878 if (ocount != count) {
1879 dprintk("NFS: READ count doesn't match RPC opaque count.\n");
1880 return -errno_NFSERR_IO;
1883 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
1884 if (iov->iov_len < hdrlen) {
1885 dprintk("NFS: READ reply header overflowed:"
1886 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1887 return -errno_NFSERR_IO;
1888 } else if (iov->iov_len != hdrlen) {
1889 dprintk("NFS: READ header is short. iovec will be shifted.\n");
1890 xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
1893 recvd = req->rq_rcv_buf.len - hdrlen;
1894 if (count > recvd) {
1895 dprintk("NFS: server cheating in read reply: "
1896 "count %u > recvd %u\n", count, recvd);
1901 if (count < res->count)
1910 * struct READ3resok {
1911 * post_op_attr file_attributes;
1917 * struct READ3resfail {
1918 * post_op_attr file_attributes;
1921 * union READ3res switch (nfsstat3 status) {
1925 * READ3resfail resfail;
1928 static int decode_read3resok(struct xdr_stream *xdr,
1929 struct nfs_readres *result)
1931 u32 eof, count, ocount, recvd;
1935 p = xdr_inline_decode(xdr, 4 + 4 + 4);
1936 if (unlikely(p == NULL))
1938 count = be32_to_cpup(p++);
1939 eof = be32_to_cpup(p++);
1940 ocount = be32_to_cpup(p++);
1941 if (unlikely(ocount != count))
1943 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
1944 recvd = xdr->buf->len - hdrlen;
1945 if (unlikely(count > recvd))
1949 xdr_read_pages(xdr, count);
1951 result->count = count;
1954 dprintk("NFS: READ count doesn't match length of opaque: "
1955 "count %u != ocount %u\n", count, ocount);
1958 dprintk("NFS: server cheating in read result: "
1959 "count %u > recvd %u\n", count, recvd);
1964 print_overflow_msg(__func__, xdr);
1968 static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, __be32 *p,
1969 struct nfs_readres *result)
1971 struct xdr_stream xdr;
1972 enum nfs_stat status;
1975 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1976 error = decode_nfsstat3(&xdr, &status);
1977 if (unlikely(error))
1979 error = decode_post_op_attr(&xdr, result->fattr);
1980 if (unlikely(error))
1982 if (status != NFS3_OK)
1984 error = decode_read3resok(&xdr, result);
1988 return nfs_stat_to_errno(status);
1992 * Decode WRITE response
1995 nfs3_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
1999 status = ntohl(*p++);
2000 p = xdr_decode_wcc_data(p, res->fattr);
2003 return nfs_stat_to_errno(status);
2005 res->count = ntohl(*p++);
2006 res->verf->committed = (enum nfs3_stable_how)ntohl(*p++);
2007 res->verf->verifier[0] = *p++;
2008 res->verf->verifier[1] = *p++;
2022 * struct WRITE3resok {
2023 * wcc_data file_wcc;
2025 * stable_how committed;
2029 * struct WRITE3resfail {
2030 * wcc_data file_wcc;
2033 * union WRITE3res switch (nfsstat3 status) {
2035 * WRITE3resok resok;
2037 * WRITE3resfail resfail;
2040 static int decode_write3resok(struct xdr_stream *xdr,
2041 struct nfs_writeres *result)
2045 p = xdr_inline_decode(xdr, 4 + 4 + NFS3_WRITEVERFSIZE);
2046 if (unlikely(p == NULL))
2048 result->count = be32_to_cpup(p++);
2049 result->verf->committed = be32_to_cpup(p++);
2050 if (unlikely(result->verf->committed > NFS_FILE_SYNC))
2052 memcpy(result->verf->verifier, p, NFS3_WRITEVERFSIZE);
2053 return result->count;
2055 dprintk("NFS: bad stable_how value: %u\n", result->verf->committed);
2058 print_overflow_msg(__func__, xdr);
2062 static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, __be32 *p,
2063 struct nfs_writeres *result)
2065 struct xdr_stream xdr;
2066 enum nfs_stat status;
2069 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2070 error = decode_nfsstat3(&xdr, &status);
2071 if (unlikely(error))
2073 error = decode_wcc_data(&xdr, result->fattr);
2074 if (unlikely(error))
2076 if (status != NFS3_OK)
2078 error = decode_write3resok(&xdr, result);
2082 return nfs_stat_to_errno(status);
2086 * Decode a CREATE response
2089 nfs3_xdr_createres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
2093 status = ntohl(*p++);
2096 if (!(p = xdr_decode_fhandle(p, res->fh)))
2097 return -errno_NFSERR_IO;
2098 p = xdr_decode_post_op_attr(p, res->fattr);
2100 memset(res->fh, 0, sizeof(*res->fh));
2101 /* Do decode post_op_attr but set it to NULL */
2102 p = xdr_decode_post_op_attr(p, res->fattr);
2103 res->fattr->valid = 0;
2106 status = nfs_stat_to_errno(status);
2108 p = xdr_decode_wcc_data(p, res->dir_attr);
2115 * struct CREATE3resok {
2117 * post_op_attr obj_attributes;
2121 * struct CREATE3resfail {
2125 * union CREATE3res switch (nfsstat3 status) {
2127 * CREATE3resok resok;
2129 * CREATE3resfail resfail;
2132 static int decode_create3resok(struct xdr_stream *xdr,
2133 struct nfs3_diropres *result)
2137 error = decode_post_op_fh3(xdr, result->fh);
2138 if (unlikely(error))
2140 error = decode_post_op_attr(xdr, result->fattr);
2141 if (unlikely(error))
2143 /* The server isn't required to return a file handle.
2144 * If it didn't, force the client to perform a LOOKUP
2145 * to determine the correct file handle and attribute
2146 * values for the new object. */
2147 if (result->fh->size == 0)
2148 result->fattr->valid = 0;
2149 error = decode_wcc_data(xdr, result->dir_attr);
2154 static int nfs3_xdr_dec_create3res(struct rpc_rqst *req, __be32 *p,
2155 struct nfs3_diropres *result)
2157 struct xdr_stream xdr;
2158 enum nfs_stat status;
2161 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2162 error = decode_nfsstat3(&xdr, &status);
2163 if (unlikely(error))
2165 if (status != NFS3_OK)
2167 error = decode_create3resok(&xdr, result);
2171 error = decode_wcc_data(&xdr, result->dir_attr);
2172 if (unlikely(error))
2174 return nfs_stat_to_errno(status);
2180 * struct REMOVE3resok {
2184 * struct REMOVE3resfail {
2188 * union REMOVE3res switch (nfsstat3 status) {
2190 * REMOVE3resok resok;
2192 * REMOVE3resfail resfail;
2195 static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req, __be32 *p,
2196 struct nfs_removeres *result)
2198 struct xdr_stream xdr;
2199 enum nfs_stat status;
2202 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2203 error = decode_nfsstat3(&xdr, &status);
2204 if (unlikely(error))
2206 error = decode_wcc_data(&xdr, result->dir_attr);
2207 if (unlikely(error))
2209 if (status != NFS3_OK)
2214 return nfs_stat_to_errno(status);
2218 * Decode RENAME reply
2221 nfs3_xdr_renameres(struct rpc_rqst *req, __be32 *p, struct nfs_renameres *res)
2225 if ((status = ntohl(*p++)) != 0)
2226 status = nfs_stat_to_errno(status);
2227 p = xdr_decode_wcc_data(p, res->old_fattr);
2228 p = xdr_decode_wcc_data(p, res->new_fattr);
2235 * struct RENAME3resok {
2236 * wcc_data fromdir_wcc;
2237 * wcc_data todir_wcc;
2240 * struct RENAME3resfail {
2241 * wcc_data fromdir_wcc;
2242 * wcc_data todir_wcc;
2245 * union RENAME3res switch (nfsstat3 status) {
2247 * RENAME3resok resok;
2249 * RENAME3resfail resfail;
2252 static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req, __be32 *p,
2253 struct nfs_renameres *result)
2255 struct xdr_stream xdr;
2256 enum nfs_stat status;
2259 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2260 error = decode_nfsstat3(&xdr, &status);
2261 if (unlikely(error))
2263 error = decode_wcc_data(&xdr, result->old_fattr);
2264 if (unlikely(error))
2266 error = decode_wcc_data(&xdr, result->new_fattr);
2267 if (unlikely(error))
2269 if (status != NFS3_OK)
2274 return nfs_stat_to_errno(status);
2281 nfs3_xdr_linkres(struct rpc_rqst *req, __be32 *p, struct nfs3_linkres *res)
2285 if ((status = ntohl(*p++)) != 0)
2286 status = nfs_stat_to_errno(status);
2287 p = xdr_decode_post_op_attr(p, res->fattr);
2288 p = xdr_decode_wcc_data(p, res->dir_attr);
2295 * struct LINK3resok {
2296 * post_op_attr file_attributes;
2297 * wcc_data linkdir_wcc;
2300 * struct LINK3resfail {
2301 * post_op_attr file_attributes;
2302 * wcc_data linkdir_wcc;
2305 * union LINK3res switch (nfsstat3 status) {
2309 * LINK3resfail resfail;
2312 static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, __be32 *p,
2313 struct nfs3_linkres *result)
2315 struct xdr_stream xdr;
2316 enum nfs_stat status;
2319 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2320 error = decode_nfsstat3(&xdr, &status);
2321 if (unlikely(error))
2323 error = decode_post_op_attr(&xdr, result->fattr);
2324 if (unlikely(error))
2326 error = decode_wcc_data(&xdr, result->dir_attr);
2327 if (unlikely(error))
2329 if (status != NFS3_OK)
2334 return nfs_stat_to_errno(status);
2338 * nfs3_decode_dirent - Decode a single NFSv3 directory entry stored in
2339 * the local page cache
2340 * @xdr: XDR stream where entry resides
2341 * @entry: buffer to fill in with entry data
2342 * @server: nfs_server data for this directory
2343 * @plus: boolean indicating whether this should be a readdirplus entry
2345 * Returns the position of the next item in the buffer, or an ERR_PTR.
2347 * This function is not invoked during READDIR reply decoding, but
2348 * rather whenever an application invokes the getdents(2) system call
2349 * on a directory already in our cache.
2357 * fhandle3 filehandle;
2358 * post_op_attr3 attributes;
2359 * entry3 *nextentry;
2363 * struct entryplus3 {
2367 * post_op_attr name_attributes;
2368 * post_op_fh3 name_handle;
2369 * entryplus3 *nextentry;
2372 __be32 *nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
2373 struct nfs_server *server, int plus)
2375 struct nfs_entry old = *entry;
2379 p = xdr_inline_decode(xdr, 4);
2380 if (unlikely(p == NULL))
2382 if (*p == xdr_zero) {
2383 p = xdr_inline_decode(xdr, 4);
2384 if (unlikely(p == NULL))
2387 return ERR_PTR(-EAGAIN);
2389 return ERR_PTR(-EBADCOOKIE);
2392 error = decode_fileid3(xdr, &entry->ino);
2393 if (unlikely(error))
2394 return ERR_PTR(error);
2396 error = decode_inline_filename3(xdr, &entry->name, &entry->len);
2397 if (unlikely(error))
2398 return ERR_PTR(error);
2400 entry->prev_cookie = entry->cookie;
2401 error = decode_cookie3(xdr, &entry->cookie);
2402 if (unlikely(error))
2403 return ERR_PTR(error);
2405 entry->d_type = DT_UNKNOWN;
2408 entry->fattr->valid = 0;
2409 error = decode_post_op_attr(xdr, entry->fattr);
2410 if (unlikely(error))
2411 return ERR_PTR(error);
2412 if (entry->fattr->valid & NFS_ATTR_FATTR_V3)
2413 entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
2415 /* In fact, a post_op_fh3: */
2416 p = xdr_inline_decode(xdr, 4);
2417 if (unlikely(p == NULL))
2419 if (*p != xdr_zero) {
2420 error = decode_nfs_fh3(xdr, entry->fh);
2421 if (unlikely(error)) {
2422 if (error == -E2BIG)
2424 return ERR_PTR(error);
2427 zero_nfs_fh3(entry->fh);
2430 /* Peek at the next entry to see if we're at EOD */
2431 p = xdr_inline_peek(xdr, 4 + 4);
2434 entry->eof = (p[0] == xdr_zero) && (p[1] != xdr_zero);
2438 print_overflow_msg(__func__, xdr);
2439 return ERR_PTR(-EAGAIN);
2441 dprintk("NFS: directory entry contains invalid file handle\n");
2443 return ERR_PTR(-EAGAIN);
2447 * 3.3.16 READDIR3res
2454 * struct READDIR3resok {
2455 * post_op_attr dir_attributes;
2456 * cookieverf3 cookieverf;
2460 * struct READDIR3resfail {
2461 * post_op_attr dir_attributes;
2464 * union READDIR3res switch (nfsstat3 status) {
2466 * READDIR3resok resok;
2468 * READDIR3resfail resfail;
2471 * Read the directory contents into the page cache, but otherwise
2472 * don't touch them. The actual decoding is done by nfs3_decode_entry()
2473 * during subsequent nfs_readdir() calls.
2475 static int decode_dirlist3(struct xdr_stream *xdr)
2480 pglen = xdr->buf->page_len;
2481 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
2482 recvd = xdr->buf->len - hdrlen;
2483 if (unlikely(pglen > recvd))
2486 xdr_read_pages(xdr, pglen);
2489 dprintk("NFS: server cheating in readdir result: "
2490 "pglen %u > recvd %u\n", pglen, recvd);
2495 static int decode_readdir3resok(struct xdr_stream *xdr,
2496 struct nfs3_readdirres *result)
2500 error = decode_post_op_attr(xdr, result->dir_attr);
2501 if (unlikely(error))
2503 /* XXX: do we need to check if result->verf != NULL ? */
2504 error = decode_cookieverf3(xdr, result->verf);
2505 if (unlikely(error))
2507 error = decode_dirlist3(xdr);
2512 static int nfs3_xdr_dec_readdir3res(struct rpc_rqst *req, __be32 *p,
2513 struct nfs3_readdirres *result)
2515 struct xdr_stream xdr;
2516 enum nfs_stat status;
2519 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2520 error = decode_nfsstat3(&xdr, &status);
2521 if (unlikely(error))
2523 if (status != NFS3_OK)
2525 error = decode_readdir3resok(&xdr, result);
2529 error = decode_post_op_attr(&xdr, result->dir_attr);
2530 if (unlikely(error))
2532 return nfs_stat_to_errno(status);
2536 * Decode FSSTAT reply
2539 nfs3_xdr_fsstatres(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *res)
2543 status = ntohl(*p++);
2545 p = xdr_decode_post_op_attr(p, res->fattr);
2547 return nfs_stat_to_errno(status);
2549 p = xdr_decode_hyper(p, &res->tbytes);
2550 p = xdr_decode_hyper(p, &res->fbytes);
2551 p = xdr_decode_hyper(p, &res->abytes);
2552 p = xdr_decode_hyper(p, &res->tfiles);
2553 p = xdr_decode_hyper(p, &res->ffiles);
2554 p = xdr_decode_hyper(p, &res->afiles);
2556 /* ignore invarsec */
2563 * struct FSSTAT3resok {
2564 * post_op_attr obj_attributes;
2574 * struct FSSTAT3resfail {
2575 * post_op_attr obj_attributes;
2578 * union FSSTAT3res switch (nfsstat3 status) {
2580 * FSSTAT3resok resok;
2582 * FSSTAT3resfail resfail;
2585 static int decode_fsstat3resok(struct xdr_stream *xdr,
2586 struct nfs_fsstat *result)
2590 p = xdr_inline_decode(xdr, 8 * 6 + 4);
2591 if (unlikely(p == NULL))
2593 p = xdr_decode_size3(p, &result->tbytes);
2594 p = xdr_decode_size3(p, &result->fbytes);
2595 p = xdr_decode_size3(p, &result->abytes);
2596 p = xdr_decode_size3(p, &result->tfiles);
2597 p = xdr_decode_size3(p, &result->ffiles);
2598 xdr_decode_size3(p, &result->afiles);
2599 /* ignore invarsec */
2602 print_overflow_msg(__func__, xdr);
2606 static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req, __be32 *p,
2607 struct nfs_fsstat *result)
2609 struct xdr_stream xdr;
2610 enum nfs_stat status;
2613 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2614 error = decode_nfsstat3(&xdr, &status);
2615 if (unlikely(error))
2617 error = decode_post_op_attr(&xdr, result->fattr);
2618 if (unlikely(error))
2620 if (status != NFS3_OK)
2622 error = decode_fsstat3resok(&xdr, result);
2626 return nfs_stat_to_errno(status);
2630 * Decode FSINFO reply
2633 nfs3_xdr_fsinfores(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *res)
2637 status = ntohl(*p++);
2639 p = xdr_decode_post_op_attr(p, res->fattr);
2641 return nfs_stat_to_errno(status);
2643 res->rtmax = ntohl(*p++);
2644 res->rtpref = ntohl(*p++);
2645 res->rtmult = ntohl(*p++);
2646 res->wtmax = ntohl(*p++);
2647 res->wtpref = ntohl(*p++);
2648 res->wtmult = ntohl(*p++);
2649 res->dtpref = ntohl(*p++);
2650 p = xdr_decode_hyper(p, &res->maxfilesize);
2651 p = xdr_decode_time3(p, &res->time_delta);
2653 /* ignore properties */
2654 res->lease_time = 0;
2661 * struct FSINFO3resok {
2662 * post_op_attr obj_attributes;
2670 * size3 maxfilesize;
2671 * nfstime3 time_delta;
2672 * uint32 properties;
2675 * struct FSINFO3resfail {
2676 * post_op_attr obj_attributes;
2679 * union FSINFO3res switch (nfsstat3 status) {
2681 * FSINFO3resok resok;
2683 * FSINFO3resfail resfail;
2686 static int decode_fsinfo3resok(struct xdr_stream *xdr,
2687 struct nfs_fsinfo *result)
2691 p = xdr_inline_decode(xdr, 4 * 7 + 8 + 8 + 4);
2692 if (unlikely(p == NULL))
2694 result->rtmax = be32_to_cpup(p++);
2695 result->rtpref = be32_to_cpup(p++);
2696 result->rtmult = be32_to_cpup(p++);
2697 result->wtmax = be32_to_cpup(p++);
2698 result->wtpref = be32_to_cpup(p++);
2699 result->wtmult = be32_to_cpup(p++);
2700 result->dtpref = be32_to_cpup(p++);
2701 p = xdr_decode_size3(p, &result->maxfilesize);
2702 xdr_decode_time3(p, &result->time_delta);
2704 /* ignore properties */
2705 result->lease_time = 0;
2708 print_overflow_msg(__func__, xdr);
2712 static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req, __be32 *p,
2713 struct nfs_fsinfo *result)
2715 struct xdr_stream xdr;
2716 enum nfs_stat status;
2719 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2720 error = decode_nfsstat3(&xdr, &status);
2721 if (unlikely(error))
2723 error = decode_post_op_attr(&xdr, result->fattr);
2724 if (unlikely(error))
2726 if (status != NFS3_OK)
2728 error = decode_fsinfo3resok(&xdr, result);
2732 return nfs_stat_to_errno(status);
2736 * Decode PATHCONF reply
2739 nfs3_xdr_pathconfres(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *res)
2743 status = ntohl(*p++);
2745 p = xdr_decode_post_op_attr(p, res->fattr);
2747 return nfs_stat_to_errno(status);
2748 res->max_link = ntohl(*p++);
2749 res->max_namelen = ntohl(*p++);
2751 /* ignore remaining fields */
2756 * 3.3.20 PATHCONF3res
2758 * struct PATHCONF3resok {
2759 * post_op_attr obj_attributes;
2763 * bool chown_restricted;
2764 * bool case_insensitive;
2765 * bool case_preserving;
2768 * struct PATHCONF3resfail {
2769 * post_op_attr obj_attributes;
2772 * union PATHCONF3res switch (nfsstat3 status) {
2774 * PATHCONF3resok resok;
2776 * PATHCONF3resfail resfail;
2779 static int decode_pathconf3resok(struct xdr_stream *xdr,
2780 struct nfs_pathconf *result)
2784 p = xdr_inline_decode(xdr, 4 * 6);
2785 if (unlikely(p == NULL))
2787 result->max_link = be32_to_cpup(p++);
2788 result->max_namelen = be32_to_cpup(p);
2789 /* ignore remaining fields */
2792 print_overflow_msg(__func__, xdr);
2796 static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req, __be32 *p,
2797 struct nfs_pathconf *result)
2799 struct xdr_stream xdr;
2800 enum nfs_stat status;
2803 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2804 error = decode_nfsstat3(&xdr, &status);
2805 if (unlikely(error))
2807 error = decode_post_op_attr(&xdr, result->fattr);
2808 if (unlikely(error))
2810 if (status != NFS3_OK)
2812 error = decode_pathconf3resok(&xdr, result);
2816 return nfs_stat_to_errno(status);
2820 * Decode COMMIT reply
2823 nfs3_xdr_commitres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
2827 status = ntohl(*p++);
2828 p = xdr_decode_wcc_data(p, res->fattr);
2830 return nfs_stat_to_errno(status);
2832 res->verf->verifier[0] = *p++;
2833 res->verf->verifier[1] = *p++;
2840 * struct COMMIT3resok {
2841 * wcc_data file_wcc;
2845 * struct COMMIT3resfail {
2846 * wcc_data file_wcc;
2849 * union COMMIT3res switch (nfsstat3 status) {
2851 * COMMIT3resok resok;
2853 * COMMIT3resfail resfail;
2856 static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req, __be32 *p,
2857 struct nfs_writeres *result)
2859 struct xdr_stream xdr;
2860 enum nfs_stat status;
2863 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2864 error = decode_nfsstat3(&xdr, &status);
2865 if (unlikely(error))
2867 error = decode_wcc_data(&xdr, result->fattr);
2868 if (unlikely(error))
2870 if (status != NFS3_OK)
2872 error = decode_writeverf3(&xdr, result->verf->verifier);
2876 return nfs_stat_to_errno(status);
2879 #ifdef CONFIG_NFS_V3_ACL
2881 * Decode GETACL reply
2884 nfs3_xdr_getaclres(struct rpc_rqst *req, __be32 *p,
2885 struct nfs3_getaclres *res)
2887 struct xdr_buf *buf = &req->rq_rcv_buf;
2888 int status = ntohl(*p++);
2889 struct posix_acl **acl;
2890 unsigned int *aclcnt;
2894 return nfs_stat_to_errno(status);
2895 p = xdr_decode_post_op_attr(p, res->fattr);
2896 res->mask = ntohl(*p++);
2897 if (res->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
2899 base = (char *)p - (char *)req->rq_rcv_buf.head->iov_base;
2901 acl = (res->mask & NFS_ACL) ? &res->acl_access : NULL;
2902 aclcnt = (res->mask & NFS_ACLCNT) ? &res->acl_access_count : NULL;
2903 err = nfsacl_decode(buf, base, aclcnt, acl);
2905 acl = (res->mask & NFS_DFACL) ? &res->acl_default : NULL;
2906 aclcnt = (res->mask & NFS_DFACLCNT) ? &res->acl_default_count : NULL;
2908 err = nfsacl_decode(buf, base + err, aclcnt, acl);
2909 return (err > 0) ? 0 : err;
2912 static inline int decode_getacl3resok(struct xdr_stream *xdr,
2913 struct nfs3_getaclres *result)
2915 struct posix_acl **acl;
2916 unsigned int *aclcnt;
2920 error = decode_post_op_attr(xdr, result->fattr);
2921 if (unlikely(error))
2923 error = decode_uint32(xdr, &result->mask);
2924 if (unlikely(error))
2927 if (result->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
2930 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
2933 if (result->mask & NFS_ACL)
2934 acl = &result->acl_access;
2936 if (result->mask & NFS_ACLCNT)
2937 aclcnt = &result->acl_access_count;
2938 error = nfsacl_decode(xdr->buf, hdrlen, aclcnt, acl);
2939 if (unlikely(error <= 0))
2943 if (result->mask & NFS_DFACL)
2944 acl = &result->acl_default;
2946 if (result->mask & NFS_DFACLCNT)
2947 aclcnt = &result->acl_default_count;
2948 error = nfsacl_decode(xdr->buf, hdrlen + error, aclcnt, acl);
2949 if (unlikely(error <= 0))
2956 static int nfs3_xdr_dec_getacl3res(struct rpc_rqst *req, __be32 *p,
2957 struct nfs3_getaclres *result)
2959 struct xdr_stream xdr;
2960 enum nfs_stat status;
2963 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2964 error = decode_nfsstat3(&xdr, &status);
2965 if (unlikely(error))
2967 if (status != NFS3_OK)
2969 error = decode_getacl3resok(&xdr, result);
2973 return nfs_stat_to_errno(status);
2977 * Decode setacl reply.
2980 nfs3_xdr_setaclres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
2982 int status = ntohl(*p++);
2985 return nfs_stat_to_errno(status);
2986 xdr_decode_post_op_attr(p, fattr);
2990 static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req, __be32 *p,
2991 struct nfs_fattr *result)
2993 struct xdr_stream xdr;
2994 enum nfs_stat status;
2997 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2998 error = decode_nfsstat3(&xdr, &status);
2999 if (unlikely(error))
3001 if (status != NFS3_OK)
3003 error = decode_post_op_attr(&xdr, result);
3007 return nfs_stat_to_errno(status);
3010 #endif /* CONFIG_NFS_V3_ACL */
3012 #define PROC(proc, argtype, restype, timer) \
3013 [NFS3PROC_##proc] = { \
3014 .p_proc = NFS3PROC_##proc, \
3015 .p_encode = (kxdrproc_t)nfs3_xdr_enc_##argtype##3args, \
3016 .p_decode = (kxdrproc_t)nfs3_xdr_dec_##restype##3res, \
3017 .p_arglen = NFS3_##argtype##args_sz, \
3018 .p_replen = NFS3_##restype##res_sz, \
3020 .p_statidx = NFS3PROC_##proc, \
3024 struct rpc_procinfo nfs3_procedures[] = {
3025 PROC(GETATTR, getattr, getattr, 1),
3026 PROC(SETATTR, setattr, setattr, 0),
3027 PROC(LOOKUP, lookup, lookup, 2),
3028 PROC(ACCESS, access, access, 1),
3029 PROC(READLINK, readlink, readlink, 3),
3030 PROC(READ, read, read, 3),
3031 PROC(WRITE, write, write, 4),
3032 PROC(CREATE, create, create, 0),
3033 PROC(MKDIR, mkdir, create, 0),
3034 PROC(SYMLINK, symlink, create, 0),
3035 PROC(MKNOD, mknod, create, 0),
3036 PROC(REMOVE, remove, remove, 0),
3037 PROC(RMDIR, lookup, setattr, 0),
3038 PROC(RENAME, rename, rename, 0),
3039 PROC(LINK, link, link, 0),
3040 PROC(READDIR, readdir, readdir, 3),
3041 PROC(READDIRPLUS, readdirplus, readdir, 3),
3042 PROC(FSSTAT, getattr, fsstat, 0),
3043 PROC(FSINFO, getattr, fsinfo, 0),
3044 PROC(PATHCONF, getattr, pathconf, 0),
3045 PROC(COMMIT, commit, commit, 5),
3048 struct rpc_version nfs_version3 = {
3050 .nrprocs = ARRAY_SIZE(nfs3_procedures),
3051 .procs = nfs3_procedures
3054 #ifdef CONFIG_NFS_V3_ACL
3055 static struct rpc_procinfo nfs3_acl_procedures[] = {
3056 [ACLPROC3_GETACL] = {
3057 .p_proc = ACLPROC3_GETACL,
3058 .p_encode = (kxdrproc_t)nfs3_xdr_enc_getacl3args,
3059 .p_decode = (kxdrproc_t)nfs3_xdr_dec_getacl3res,
3060 .p_arglen = ACL3_getaclargs_sz,
3061 .p_replen = ACL3_getaclres_sz,
3065 [ACLPROC3_SETACL] = {
3066 .p_proc = ACLPROC3_SETACL,
3067 .p_encode = (kxdrproc_t)nfs3_xdr_enc_setacl3args,
3068 .p_decode = (kxdrproc_t)nfs3_xdr_dec_setacl3res,
3069 .p_arglen = ACL3_setaclargs_sz,
3070 .p_replen = ACL3_setaclres_sz,
3076 struct rpc_version nfsacl_version3 = {
3078 .nrprocs = sizeof(nfs3_acl_procedures)/
3079 sizeof(nfs3_acl_procedures[0]),
3080 .procs = nfs3_acl_procedures,
3082 #endif /* CONFIG_NFS_V3_ACL */