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
134 * Encode/decode time.
136 static inline __be32 *
137 xdr_decode_time3(__be32 *p, struct timespec *timep)
139 timep->tv_sec = ntohl(*p++);
140 timep->tv_nsec = ntohl(*p++);
145 xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
147 unsigned int type, major, minor;
153 fmode = nfs_type2fmt[type];
154 fattr->mode = (ntohl(*p++) & ~S_IFMT) | fmode;
155 fattr->nlink = ntohl(*p++);
156 fattr->uid = ntohl(*p++);
157 fattr->gid = ntohl(*p++);
158 p = xdr_decode_hyper(p, &fattr->size);
159 p = xdr_decode_hyper(p, &fattr->du.nfs3.used);
161 /* Turn remote device info into Linux-specific dev_t */
164 fattr->rdev = MKDEV(major, minor);
165 if (MAJOR(fattr->rdev) != major || MINOR(fattr->rdev) != minor)
168 p = xdr_decode_hyper(p, &fattr->fsid.major);
169 fattr->fsid.minor = 0;
170 p = xdr_decode_hyper(p, &fattr->fileid);
171 p = xdr_decode_time3(p, &fattr->atime);
172 p = xdr_decode_time3(p, &fattr->mtime);
173 p = xdr_decode_time3(p, &fattr->ctime);
175 /* Update the mode bits */
176 fattr->valid |= NFS_ATTR_FATTR_V3;
180 static inline __be32 *
181 xdr_decode_wcc_attr(__be32 *p, struct nfs_fattr *fattr)
183 p = xdr_decode_hyper(p, &fattr->pre_size);
184 p = xdr_decode_time3(p, &fattr->pre_mtime);
185 p = xdr_decode_time3(p, &fattr->pre_ctime);
186 fattr->valid |= NFS_ATTR_FATTR_PRESIZE
187 | NFS_ATTR_FATTR_PREMTIME
188 | NFS_ATTR_FATTR_PRECTIME;
193 * Encode/decode NFSv3 basic data types
195 * Basic NFSv3 data types are defined in section 2.5 of RFC 1813:
196 * "NFS Version 3 Protocol Specification".
198 * Not all basic data types have their own encoding and decoding
199 * functions. For run-time efficiency, some data types are encoded
203 static void encode_uint32(struct xdr_stream *xdr, u32 value)
205 __be32 *p = xdr_reserve_space(xdr, 4);
206 *p = cpu_to_be32(value);
209 static int decode_uint32(struct xdr_stream *xdr, u32 *value)
213 p = xdr_inline_decode(xdr, 4);
214 if (unlikely(p == NULL))
216 *value = be32_to_cpup(p);
219 print_overflow_msg(__func__, xdr);
223 static int decode_uint64(struct xdr_stream *xdr, u64 *value)
227 p = xdr_inline_decode(xdr, 8);
228 if (unlikely(p == NULL))
230 xdr_decode_hyper(p, value);
233 print_overflow_msg(__func__, xdr);
240 * typedef uint64 fileid3;
242 static int decode_fileid3(struct xdr_stream *xdr, u64 *fileid)
244 return decode_uint64(xdr, fileid);
250 * typedef string filename3<>;
252 static void encode_filename3(struct xdr_stream *xdr,
253 const char *name, u32 length)
257 BUG_ON(length > NFS3_MAXNAMLEN);
258 p = xdr_reserve_space(xdr, 4 + length);
259 xdr_encode_opaque(p, name, length);
262 static int decode_inline_filename3(struct xdr_stream *xdr,
263 const char **name, u32 *length)
268 p = xdr_inline_decode(xdr, 4);
269 if (unlikely(p == NULL))
271 count = be32_to_cpup(p);
272 if (count > NFS3_MAXNAMLEN)
273 goto out_nametoolong;
274 p = xdr_inline_decode(xdr, count);
275 if (unlikely(p == NULL))
277 *name = (const char *)p;
282 dprintk("NFS: returned filename too long: %u\n", count);
283 return -ENAMETOOLONG;
285 print_overflow_msg(__func__, xdr);
292 * typedef string nfspath3<>;
294 static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages,
297 BUG_ON(length > NFS3_MAXPATHLEN);
298 encode_uint32(xdr, length);
299 xdr_write_pages(xdr, pages, 0, length);
302 static int decode_nfspath3(struct xdr_stream *xdr)
308 p = xdr_inline_decode(xdr, 4);
309 if (unlikely(p == NULL))
311 count = be32_to_cpup(p);
312 if (unlikely(count >= xdr->buf->page_len || count > NFS3_MAXPATHLEN))
313 goto out_nametoolong;
314 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
315 recvd = xdr->buf->len - hdrlen;
316 if (unlikely(count > recvd))
319 xdr_read_pages(xdr, count);
320 xdr_terminate_string(xdr->buf, count);
324 dprintk("NFS: returned pathname too long: %u\n", count);
325 return -ENAMETOOLONG;
327 dprintk("NFS: server cheating in pathname result: "
328 "count %u > recvd %u\n", count, recvd);
331 print_overflow_msg(__func__, xdr);
338 * typedef uint64 cookie3
340 static __be32 *xdr_encode_cookie3(__be32 *p, u64 cookie)
342 return xdr_encode_hyper(p, cookie);
345 static int decode_cookie3(struct xdr_stream *xdr, u64 *cookie)
347 return decode_uint64(xdr, cookie);
353 * typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
355 static __be32 *xdr_encode_cookieverf3(__be32 *p, const __be32 *verifier)
357 memcpy(p, verifier, NFS3_COOKIEVERFSIZE);
358 return p + XDR_QUADLEN(NFS3_COOKIEVERFSIZE);
361 static int decode_cookieverf3(struct xdr_stream *xdr, __be32 *verifier)
365 p = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE);
366 if (unlikely(p == NULL))
368 memcpy(verifier, p, NFS3_COOKIEVERFSIZE);
371 print_overflow_msg(__func__, xdr);
378 * typedef opaque createverf3[NFS3_CREATEVERFSIZE];
380 static void encode_createverf3(struct xdr_stream *xdr, const __be32 *verifier)
384 p = xdr_reserve_space(xdr, NFS3_CREATEVERFSIZE);
385 memcpy(p, verifier, NFS3_CREATEVERFSIZE);
388 static int decode_writeverf3(struct xdr_stream *xdr, __be32 *verifier)
392 p = xdr_inline_decode(xdr, NFS3_WRITEVERFSIZE);
393 if (unlikely(p == NULL))
395 memcpy(verifier, p, NFS3_WRITEVERFSIZE);
398 print_overflow_msg(__func__, xdr);
405 * typedef uint64 size3;
407 static __be32 *xdr_decode_size3(__be32 *p, u64 *size)
409 return xdr_decode_hyper(p, size);
420 #define NFS3_OK NFS_OK
422 static int decode_nfsstat3(struct xdr_stream *xdr, enum nfs_stat *status)
426 p = xdr_inline_decode(xdr, 4);
427 if (unlikely(p == NULL))
429 *status = be32_to_cpup(p);
432 print_overflow_msg(__func__, xdr);
449 static void encode_ftype3(struct xdr_stream *xdr, const u32 type)
451 BUG_ON(type > NF3FIFO);
452 encode_uint32(xdr, type);
463 static void encode_specdata3(struct xdr_stream *xdr, const dev_t rdev)
467 p = xdr_reserve_space(xdr, 8);
468 *p++ = cpu_to_be32(MAJOR(rdev));
469 *p = cpu_to_be32(MINOR(rdev));
476 * opaque data<NFS3_FHSIZE>;
479 static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh)
483 BUG_ON(fh->size > NFS3_FHSIZE);
484 p = xdr_reserve_space(xdr, 4 + fh->size);
485 xdr_encode_opaque(p, fh->data, fh->size);
488 static int decode_nfs_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
493 p = xdr_inline_decode(xdr, 4);
494 if (unlikely(p == NULL))
496 length = be32_to_cpup(p++);
497 if (unlikely(length > NFS3_FHSIZE))
499 p = xdr_inline_decode(xdr, length);
500 if (unlikely(p == NULL))
503 memcpy(fh->data, p, length);
506 dprintk("NFS: file handle size (%u) too big\n", length);
509 print_overflow_msg(__func__, xdr);
513 static void zero_nfs_fh3(struct nfs_fh *fh)
515 memset(fh, 0, sizeof(*fh));
526 static __be32 *xdr_encode_nfstime3(__be32 *p, const struct timespec *timep)
528 *p++ = cpu_to_be32(timep->tv_sec);
529 *p++ = cpu_to_be32(timep->tv_nsec);
538 * SET_TO_SERVER_TIME = 1,
539 * SET_TO_CLIENT_TIME = 2
542 * union set_mode3 switch (bool set_it) {
549 * union set_uid3 switch (bool set_it) {
556 * union set_gid3 switch (bool set_it) {
563 * union set_size3 switch (bool set_it) {
570 * union set_atime switch (time_how set_it) {
571 * case SET_TO_CLIENT_TIME:
577 * union set_mtime switch (time_how set_it) {
578 * case SET_TO_CLIENT_TIME:
593 static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)
599 * In order to make only a single xdr_reserve_space() call,
600 * pre-compute the total number of bytes to be reserved.
601 * Six boolean values, one for each set_foo field, are always
602 * present in the encoded result, so start there.
605 if (attr->ia_valid & ATTR_MODE)
607 if (attr->ia_valid & ATTR_UID)
609 if (attr->ia_valid & ATTR_GID)
611 if (attr->ia_valid & ATTR_SIZE)
613 if (attr->ia_valid & ATTR_ATIME_SET)
615 if (attr->ia_valid & ATTR_MTIME_SET)
617 p = xdr_reserve_space(xdr, nbytes);
619 if (attr->ia_valid & ATTR_MODE) {
621 *p++ = cpu_to_be32(attr->ia_mode & S_IALLUGO);
625 if (attr->ia_valid & ATTR_UID) {
627 *p++ = cpu_to_be32(attr->ia_uid);
631 if (attr->ia_valid & ATTR_GID) {
633 *p++ = cpu_to_be32(attr->ia_gid);
637 if (attr->ia_valid & ATTR_SIZE) {
639 p = xdr_encode_hyper(p, (u64)attr->ia_size);
643 if (attr->ia_valid & ATTR_ATIME_SET) {
645 p = xdr_encode_nfstime3(p, &attr->ia_atime);
646 } else if (attr->ia_valid & ATTR_ATIME) {
651 if (attr->ia_valid & ATTR_MTIME_SET) {
653 xdr_encode_nfstime3(p, &attr->ia_mtime);
654 } else if (attr->ia_valid & ATTR_MTIME) {
679 static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr)
683 p = xdr_inline_decode(xdr, NFS3_fattr_sz << 2);
684 if (unlikely(p == NULL))
686 xdr_decode_fattr(p, fattr);
689 print_overflow_msg(__func__, xdr);
696 * union post_op_attr switch (bool attributes_follow) {
703 static int decode_post_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
707 p = xdr_inline_decode(xdr, 4);
708 if (unlikely(p == NULL))
711 return decode_fattr3(xdr, fattr);
714 print_overflow_msg(__func__, xdr);
726 static int decode_wcc_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
730 p = xdr_inline_decode(xdr, NFS3_wcc_attr_sz << 2);
731 if (unlikely(p == NULL))
733 xdr_decode_wcc_attr(p, fattr);
736 print_overflow_msg(__func__, xdr);
742 * union pre_op_attr switch (bool attributes_follow) {
744 * wcc_attr attributes;
752 * pre_op_attr before;
753 * post_op_attr after;
756 static int decode_pre_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
760 p = xdr_inline_decode(xdr, 4);
761 if (unlikely(p == NULL))
764 return decode_wcc_attr(xdr, fattr);
767 print_overflow_msg(__func__, xdr);
771 static int decode_wcc_data(struct xdr_stream *xdr, struct nfs_fattr *fattr)
775 error = decode_pre_op_attr(xdr, fattr);
778 error = decode_post_op_attr(xdr, fattr);
786 * union post_op_fh3 switch (bool handle_follows) {
793 static int decode_post_op_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
795 __be32 *p = xdr_inline_decode(xdr, 4);
796 if (unlikely(p == NULL))
799 return decode_nfs_fh3(xdr, fh);
803 print_overflow_msg(__func__, xdr);
810 * struct diropargs3 {
815 static void encode_diropargs3(struct xdr_stream *xdr, const struct nfs_fh *fh,
816 const char *name, u32 length)
818 encode_nfs_fh3(xdr, fh);
819 encode_filename3(xdr, name, length);
824 * NFSv3 XDR encode functions
826 * NFSv3 argument types are defined in section 3.3 of RFC 1813:
827 * "NFS Version 3 Protocol Specification".
833 * struct GETATTR3args {
837 static int nfs3_xdr_enc_getattr3args(struct rpc_rqst *req, __be32 *p,
838 const struct nfs_fh *fh)
840 struct xdr_stream xdr;
842 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
843 encode_nfs_fh3(&xdr, fh);
850 * union sattrguard3 switch (bool check) {
852 * nfstime3 obj_ctime;
857 * struct SETATTR3args {
859 * sattr3 new_attributes;
863 static void encode_sattrguard3(struct xdr_stream *xdr,
864 const struct nfs3_sattrargs *args)
869 p = xdr_reserve_space(xdr, 4 + 8);
871 xdr_encode_nfstime3(p, &args->guardtime);
873 p = xdr_reserve_space(xdr, 4);
878 static int nfs3_xdr_enc_setattr3args(struct rpc_rqst *req, __be32 *p,
879 const struct nfs3_sattrargs *args)
881 struct xdr_stream xdr;
883 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
884 encode_nfs_fh3(&xdr, args->fh);
885 encode_sattr3(&xdr, args->sattr);
886 encode_sattrguard3(&xdr, args);
893 * struct LOOKUP3args {
897 static int nfs3_xdr_enc_lookup3args(struct rpc_rqst *req, __be32 *p,
898 const struct nfs3_diropargs *args)
900 struct xdr_stream xdr;
902 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
903 encode_diropargs3(&xdr, args->fh, args->name, args->len);
910 * struct ACCESS3args {
915 static void encode_access3args(struct xdr_stream *xdr,
916 const struct nfs3_accessargs *args)
918 encode_nfs_fh3(xdr, args->fh);
919 encode_uint32(xdr, args->access);
922 static int nfs3_xdr_enc_access3args(struct rpc_rqst *req, __be32 *p,
923 const struct nfs3_accessargs *args)
925 struct xdr_stream xdr;
927 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
928 encode_access3args(&xdr, args);
933 * 3.3.5 READLINK3args
935 * struct READLINK3args {
939 static int nfs3_xdr_enc_readlink3args(struct rpc_rqst *req, __be32 *p,
940 const struct nfs3_readlinkargs *args)
942 struct xdr_stream xdr;
944 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
945 encode_nfs_fh3(&xdr, args->fh);
946 prepare_reply_buffer(req, args->pages, args->pgbase,
947 args->pglen, NFS3_readlinkres_sz);
960 static void encode_read3args(struct xdr_stream *xdr,
961 const struct nfs_readargs *args)
965 encode_nfs_fh3(xdr, args->fh);
967 p = xdr_reserve_space(xdr, 8 + 4);
968 p = xdr_encode_hyper(p, args->offset);
969 *p = cpu_to_be32(args->count);
972 static int nfs3_xdr_enc_read3args(struct rpc_rqst *req, __be32 *p,
973 const struct nfs_readargs *args)
975 struct xdr_stream xdr;
977 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
978 encode_read3args(&xdr, args);
979 prepare_reply_buffer(req, args->pages, args->pgbase,
980 args->count, NFS3_readres_sz);
981 req->rq_rcv_buf.flags |= XDRBUF_READ;
994 * struct WRITE3args {
1002 static void encode_write3args(struct xdr_stream *xdr,
1003 const struct nfs_writeargs *args)
1007 encode_nfs_fh3(xdr, args->fh);
1009 p = xdr_reserve_space(xdr, 8 + 4 + 4 + 4);
1010 p = xdr_encode_hyper(p, args->offset);
1011 *p++ = cpu_to_be32(args->count);
1013 BUG_ON(args->stable > NFS_FILE_SYNC);
1014 *p++ = cpu_to_be32(args->stable);
1016 *p = cpu_to_be32(args->count);
1017 xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
1020 static int nfs3_xdr_enc_write3args(struct rpc_rqst *req, __be32 *p,
1021 const struct nfs_writeargs *args)
1023 struct xdr_stream xdr;
1025 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1026 encode_write3args(&xdr, args);
1027 xdr.buf->flags |= XDRBUF_WRITE;
1034 * enum createmode3 {
1040 * union createhow3 switch (createmode3 mode) {
1043 * sattr3 obj_attributes;
1048 * struct CREATE3args {
1053 static void encode_createhow3(struct xdr_stream *xdr,
1054 const struct nfs3_createargs *args)
1056 encode_uint32(xdr, args->createmode);
1057 switch (args->createmode) {
1058 case NFS3_CREATE_UNCHECKED:
1059 case NFS3_CREATE_GUARDED:
1060 encode_sattr3(xdr, args->sattr);
1062 case NFS3_CREATE_EXCLUSIVE:
1063 encode_createverf3(xdr, args->verifier);
1070 static int nfs3_xdr_enc_create3args(struct rpc_rqst *req, __be32 *p,
1071 const struct nfs3_createargs *args)
1073 struct xdr_stream xdr;
1075 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1076 encode_diropargs3(&xdr, args->fh, args->name, args->len);
1077 encode_createhow3(&xdr, args);
1084 * struct MKDIR3args {
1086 * sattr3 attributes;
1089 static int nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req, __be32 *p,
1090 const struct nfs3_mkdirargs *args)
1092 struct xdr_stream xdr;
1094 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1095 encode_diropargs3(&xdr, args->fh, args->name, args->len);
1096 encode_sattr3(&xdr, args->sattr);
1101 * 3.3.10 SYMLINK3args
1103 * struct symlinkdata3 {
1104 * sattr3 symlink_attributes;
1105 * nfspath3 symlink_data;
1108 * struct SYMLINK3args {
1110 * symlinkdata3 symlink;
1113 static void encode_symlinkdata3(struct xdr_stream *xdr,
1114 const struct nfs3_symlinkargs *args)
1116 encode_sattr3(xdr, args->sattr);
1117 encode_nfspath3(xdr, args->pages, args->pathlen);
1120 static int nfs3_xdr_enc_symlink3args(struct rpc_rqst *req, __be32 *p,
1121 const struct nfs3_symlinkargs *args)
1123 struct xdr_stream xdr;
1125 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1126 encode_diropargs3(&xdr, args->fromfh, args->fromname, args->fromlen);
1127 encode_symlinkdata3(&xdr, args);
1134 * struct devicedata3 {
1135 * sattr3 dev_attributes;
1139 * union mknoddata3 switch (ftype3 type) {
1142 * devicedata3 device;
1145 * sattr3 pipe_attributes;
1150 * struct MKNOD3args {
1155 static void encode_devicedata3(struct xdr_stream *xdr,
1156 const struct nfs3_mknodargs *args)
1158 encode_sattr3(xdr, args->sattr);
1159 encode_specdata3(xdr, args->rdev);
1162 static void encode_mknoddata3(struct xdr_stream *xdr,
1163 const struct nfs3_mknodargs *args)
1165 encode_ftype3(xdr, args->type);
1166 switch (args->type) {
1169 encode_devicedata3(xdr, args);
1173 encode_sattr3(xdr, args->sattr);
1183 static int nfs3_xdr_enc_mknod3args(struct rpc_rqst *req, __be32 *p,
1184 const struct nfs3_mknodargs *args)
1186 struct xdr_stream xdr;
1188 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1189 encode_diropargs3(&xdr, args->fh, args->name, args->len);
1190 encode_mknoddata3(&xdr, args);
1195 * 3.3.12 REMOVE3args
1197 * struct REMOVE3args {
1198 * diropargs3 object;
1201 static int nfs3_xdr_enc_remove3args(struct rpc_rqst *req, __be32 *p,
1202 const struct nfs_removeargs *args)
1204 struct xdr_stream xdr;
1206 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1207 encode_diropargs3(&xdr, args->fh, args->name.name, args->name.len);
1212 * 3.3.14 RENAME3args
1214 * struct RENAME3args {
1219 static int nfs3_xdr_enc_rename3args(struct rpc_rqst *req, __be32 *p,
1220 const struct nfs_renameargs *args)
1222 const struct qstr *old = args->old_name;
1223 const struct qstr *new = args->new_name;
1224 struct xdr_stream xdr;
1226 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1227 encode_diropargs3(&xdr, args->old_dir, old->name, old->len);
1228 encode_diropargs3(&xdr, args->new_dir, new->name, new->len);
1235 * struct LINK3args {
1240 static int nfs3_xdr_enc_link3args(struct rpc_rqst *req, __be32 *p,
1241 const struct nfs3_linkargs *args)
1243 struct xdr_stream xdr;
1245 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1246 encode_nfs_fh3(&xdr, args->fromfh);
1247 encode_diropargs3(&xdr, args->tofh, args->toname, args->tolen);
1252 * 3.3.16 READDIR3args
1254 * struct READDIR3args {
1257 * cookieverf3 cookieverf;
1261 static void encode_readdir3args(struct xdr_stream *xdr,
1262 const struct nfs3_readdirargs *args)
1266 encode_nfs_fh3(xdr, args->fh);
1268 p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4);
1269 p = xdr_encode_cookie3(p, args->cookie);
1270 p = xdr_encode_cookieverf3(p, args->verf);
1271 *p = cpu_to_be32(args->count);
1274 static int nfs3_xdr_enc_readdir3args(struct rpc_rqst *req, __be32 *p,
1275 const struct nfs3_readdirargs *args)
1277 struct xdr_stream xdr;
1279 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1280 encode_readdir3args(&xdr, args);
1281 prepare_reply_buffer(req, args->pages, 0,
1282 args->count, NFS3_readdirres_sz);
1287 * 3.3.17 READDIRPLUS3args
1289 * struct READDIRPLUS3args {
1292 * cookieverf3 cookieverf;
1297 static void encode_readdirplus3args(struct xdr_stream *xdr,
1298 const struct nfs3_readdirargs *args)
1302 encode_nfs_fh3(xdr, args->fh);
1304 p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4 + 4);
1305 p = xdr_encode_cookie3(p, args->cookie);
1306 p = xdr_encode_cookieverf3(p, args->verf);
1309 * readdirplus: need dircount + buffer size.
1310 * We just make sure we make dircount big enough
1312 *p++ = cpu_to_be32(args->count >> 3);
1314 *p = cpu_to_be32(args->count);
1317 static int nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req, __be32 *p,
1318 const struct nfs3_readdirargs *args)
1320 struct xdr_stream xdr;
1322 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1323 encode_readdirplus3args(&xdr, args);
1324 prepare_reply_buffer(req, args->pages, 0,
1325 args->count, NFS3_readdirres_sz);
1330 * 3.3.21 COMMIT3args
1332 * struct COMMIT3args {
1338 static void encode_commit3args(struct xdr_stream *xdr,
1339 const struct nfs_writeargs *args)
1343 encode_nfs_fh3(xdr, args->fh);
1345 p = xdr_reserve_space(xdr, 8 + 4);
1346 p = xdr_encode_hyper(p, args->offset);
1347 *p = cpu_to_be32(args->count);
1350 static int nfs3_xdr_enc_commit3args(struct rpc_rqst *req, __be32 *p,
1351 const struct nfs_writeargs *args)
1353 struct xdr_stream xdr;
1355 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1356 encode_commit3args(&xdr, args);
1360 #ifdef CONFIG_NFS_V3_ACL
1362 static int nfs3_xdr_enc_getacl3args(struct rpc_rqst *req, __be32 *p,
1363 const struct nfs3_getaclargs *args)
1365 struct xdr_stream xdr;
1367 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1368 encode_nfs_fh3(&xdr, args->fh);
1369 encode_uint32(&xdr, args->mask);
1370 if (args->mask & (NFS_ACL | NFS_DFACL))
1371 prepare_reply_buffer(req, args->pages, 0,
1372 NFSACL_MAXPAGES << PAGE_SHIFT,
1377 static int nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, __be32 *p,
1378 const struct nfs3_setaclargs *args)
1380 struct xdr_stream xdr;
1384 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1385 encode_nfs_fh3(&xdr, NFS_FH(args->inode));
1386 encode_uint32(&xdr, args->mask);
1387 if (args->npages != 0)
1388 xdr_write_pages(&xdr, args->pages, 0, args->len);
1390 base = req->rq_slen;
1391 error = nfsacl_encode(xdr.buf, base, args->inode,
1392 (args->mask & NFS_ACL) ?
1393 args->acl_access : NULL, 1, 0);
1395 error = nfsacl_encode(xdr.buf, base + error, args->inode,
1396 (args->mask & NFS_DFACL) ?
1397 args->acl_default : NULL, 1,
1403 #endif /* CONFIG_NFS_V3_ACL */
1406 * NFSv3 XDR decode functions
1408 * NFSv3 result types are defined in section 3.3 of RFC 1813:
1409 * "NFS Version 3 Protocol Specification".
1415 * struct GETATTR3resok {
1416 * fattr3 obj_attributes;
1419 * union GETATTR3res switch (nfsstat3 status) {
1421 * GETATTR3resok resok;
1426 static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req, __be32 *p,
1427 struct nfs_fattr *result)
1429 struct xdr_stream xdr;
1430 enum nfs_stat status;
1433 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1434 error = decode_nfsstat3(&xdr, &status);
1435 if (unlikely(error))
1437 if (status != NFS3_OK)
1439 error = decode_fattr3(&xdr, result);
1443 return nfs_stat_to_errno(status);
1449 * struct SETATTR3resok {
1453 * struct SETATTR3resfail {
1457 * union SETATTR3res switch (nfsstat3 status) {
1459 * SETATTR3resok resok;
1461 * SETATTR3resfail resfail;
1464 static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req, __be32 *p,
1465 struct nfs_fattr *result)
1467 struct xdr_stream xdr;
1468 enum nfs_stat status;
1471 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1472 error = decode_nfsstat3(&xdr, &status);
1473 if (unlikely(error))
1475 error = decode_wcc_data(&xdr, result);
1476 if (unlikely(error))
1478 if (status != NFS3_OK)
1483 return nfs_stat_to_errno(status);
1489 * struct LOOKUP3resok {
1491 * post_op_attr obj_attributes;
1492 * post_op_attr dir_attributes;
1495 * struct LOOKUP3resfail {
1496 * post_op_attr dir_attributes;
1499 * union LOOKUP3res switch (nfsstat3 status) {
1501 * LOOKUP3resok resok;
1503 * LOOKUP3resfail resfail;
1506 static int nfs3_xdr_dec_lookup3res(struct rpc_rqst *req, __be32 *p,
1507 struct nfs3_diropres *result)
1509 struct xdr_stream xdr;
1510 enum nfs_stat status;
1513 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1514 error = decode_nfsstat3(&xdr, &status);
1515 if (unlikely(error))
1517 if (status != NFS3_OK)
1519 error = decode_nfs_fh3(&xdr, result->fh);
1520 if (unlikely(error))
1522 error = decode_post_op_attr(&xdr, result->fattr);
1523 if (unlikely(error))
1525 error = decode_post_op_attr(&xdr, result->dir_attr);
1529 error = decode_post_op_attr(&xdr, result->dir_attr);
1530 if (unlikely(error))
1532 return nfs_stat_to_errno(status);
1538 * struct ACCESS3resok {
1539 * post_op_attr obj_attributes;
1543 * struct ACCESS3resfail {
1544 * post_op_attr obj_attributes;
1547 * union ACCESS3res switch (nfsstat3 status) {
1549 * ACCESS3resok resok;
1551 * ACCESS3resfail resfail;
1554 static int nfs3_xdr_dec_access3res(struct rpc_rqst *req, __be32 *p,
1555 struct nfs3_accessres *result)
1557 struct xdr_stream xdr;
1558 enum nfs_stat status;
1561 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1562 error = decode_nfsstat3(&xdr, &status);
1563 if (unlikely(error))
1565 error = decode_post_op_attr(&xdr, result->fattr);
1566 if (unlikely(error))
1568 if (status != NFS3_OK)
1570 error = decode_uint32(&xdr, &result->access);
1574 return nfs_stat_to_errno(status);
1578 * 3.3.5 READLINK3res
1580 * struct READLINK3resok {
1581 * post_op_attr symlink_attributes;
1585 * struct READLINK3resfail {
1586 * post_op_attr symlink_attributes;
1589 * union READLINK3res switch (nfsstat3 status) {
1591 * READLINK3resok resok;
1593 * READLINK3resfail resfail;
1596 static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req, __be32 *p,
1597 struct nfs_fattr *result)
1599 struct xdr_stream xdr;
1600 enum nfs_stat status;
1603 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1604 error = decode_nfsstat3(&xdr, &status);
1605 if (unlikely(error))
1607 error = decode_post_op_attr(&xdr, result);
1608 if (unlikely(error))
1610 if (status != NFS3_OK)
1612 error = decode_nfspath3(&xdr);
1616 return nfs_stat_to_errno(status);
1622 * struct READ3resok {
1623 * post_op_attr file_attributes;
1629 * struct READ3resfail {
1630 * post_op_attr file_attributes;
1633 * union READ3res switch (nfsstat3 status) {
1637 * READ3resfail resfail;
1640 static int decode_read3resok(struct xdr_stream *xdr,
1641 struct nfs_readres *result)
1643 u32 eof, count, ocount, recvd;
1647 p = xdr_inline_decode(xdr, 4 + 4 + 4);
1648 if (unlikely(p == NULL))
1650 count = be32_to_cpup(p++);
1651 eof = be32_to_cpup(p++);
1652 ocount = be32_to_cpup(p++);
1653 if (unlikely(ocount != count))
1655 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
1656 recvd = xdr->buf->len - hdrlen;
1657 if (unlikely(count > recvd))
1661 xdr_read_pages(xdr, count);
1663 result->count = count;
1666 dprintk("NFS: READ count doesn't match length of opaque: "
1667 "count %u != ocount %u\n", count, ocount);
1670 dprintk("NFS: server cheating in read result: "
1671 "count %u > recvd %u\n", count, recvd);
1676 print_overflow_msg(__func__, xdr);
1680 static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, __be32 *p,
1681 struct nfs_readres *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 error = decode_post_op_attr(&xdr, result->fattr);
1692 if (unlikely(error))
1694 if (status != NFS3_OK)
1696 error = decode_read3resok(&xdr, result);
1700 return nfs_stat_to_errno(status);
1712 * struct WRITE3resok {
1713 * wcc_data file_wcc;
1715 * stable_how committed;
1719 * struct WRITE3resfail {
1720 * wcc_data file_wcc;
1723 * union WRITE3res switch (nfsstat3 status) {
1725 * WRITE3resok resok;
1727 * WRITE3resfail resfail;
1730 static int decode_write3resok(struct xdr_stream *xdr,
1731 struct nfs_writeres *result)
1735 p = xdr_inline_decode(xdr, 4 + 4 + NFS3_WRITEVERFSIZE);
1736 if (unlikely(p == NULL))
1738 result->count = be32_to_cpup(p++);
1739 result->verf->committed = be32_to_cpup(p++);
1740 if (unlikely(result->verf->committed > NFS_FILE_SYNC))
1742 memcpy(result->verf->verifier, p, NFS3_WRITEVERFSIZE);
1743 return result->count;
1745 dprintk("NFS: bad stable_how value: %u\n", result->verf->committed);
1748 print_overflow_msg(__func__, xdr);
1752 static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, __be32 *p,
1753 struct nfs_writeres *result)
1755 struct xdr_stream xdr;
1756 enum nfs_stat status;
1759 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1760 error = decode_nfsstat3(&xdr, &status);
1761 if (unlikely(error))
1763 error = decode_wcc_data(&xdr, result->fattr);
1764 if (unlikely(error))
1766 if (status != NFS3_OK)
1768 error = decode_write3resok(&xdr, result);
1772 return nfs_stat_to_errno(status);
1778 * struct CREATE3resok {
1780 * post_op_attr obj_attributes;
1784 * struct CREATE3resfail {
1788 * union CREATE3res switch (nfsstat3 status) {
1790 * CREATE3resok resok;
1792 * CREATE3resfail resfail;
1795 static int decode_create3resok(struct xdr_stream *xdr,
1796 struct nfs3_diropres *result)
1800 error = decode_post_op_fh3(xdr, result->fh);
1801 if (unlikely(error))
1803 error = decode_post_op_attr(xdr, result->fattr);
1804 if (unlikely(error))
1806 /* The server isn't required to return a file handle.
1807 * If it didn't, force the client to perform a LOOKUP
1808 * to determine the correct file handle and attribute
1809 * values for the new object. */
1810 if (result->fh->size == 0)
1811 result->fattr->valid = 0;
1812 error = decode_wcc_data(xdr, result->dir_attr);
1817 static int nfs3_xdr_dec_create3res(struct rpc_rqst *req, __be32 *p,
1818 struct nfs3_diropres *result)
1820 struct xdr_stream xdr;
1821 enum nfs_stat status;
1824 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1825 error = decode_nfsstat3(&xdr, &status);
1826 if (unlikely(error))
1828 if (status != NFS3_OK)
1830 error = decode_create3resok(&xdr, result);
1834 error = decode_wcc_data(&xdr, result->dir_attr);
1835 if (unlikely(error))
1837 return nfs_stat_to_errno(status);
1843 * struct REMOVE3resok {
1847 * struct REMOVE3resfail {
1851 * union REMOVE3res switch (nfsstat3 status) {
1853 * REMOVE3resok resok;
1855 * REMOVE3resfail resfail;
1858 static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req, __be32 *p,
1859 struct nfs_removeres *result)
1861 struct xdr_stream xdr;
1862 enum nfs_stat status;
1865 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1866 error = decode_nfsstat3(&xdr, &status);
1867 if (unlikely(error))
1869 error = decode_wcc_data(&xdr, result->dir_attr);
1870 if (unlikely(error))
1872 if (status != NFS3_OK)
1877 return nfs_stat_to_errno(status);
1883 * struct RENAME3resok {
1884 * wcc_data fromdir_wcc;
1885 * wcc_data todir_wcc;
1888 * struct RENAME3resfail {
1889 * wcc_data fromdir_wcc;
1890 * wcc_data todir_wcc;
1893 * union RENAME3res switch (nfsstat3 status) {
1895 * RENAME3resok resok;
1897 * RENAME3resfail resfail;
1900 static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req, __be32 *p,
1901 struct nfs_renameres *result)
1903 struct xdr_stream xdr;
1904 enum nfs_stat status;
1907 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1908 error = decode_nfsstat3(&xdr, &status);
1909 if (unlikely(error))
1911 error = decode_wcc_data(&xdr, result->old_fattr);
1912 if (unlikely(error))
1914 error = decode_wcc_data(&xdr, result->new_fattr);
1915 if (unlikely(error))
1917 if (status != NFS3_OK)
1922 return nfs_stat_to_errno(status);
1928 * struct LINK3resok {
1929 * post_op_attr file_attributes;
1930 * wcc_data linkdir_wcc;
1933 * struct LINK3resfail {
1934 * post_op_attr file_attributes;
1935 * wcc_data linkdir_wcc;
1938 * union LINK3res switch (nfsstat3 status) {
1942 * LINK3resfail resfail;
1945 static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, __be32 *p,
1946 struct nfs3_linkres *result)
1948 struct xdr_stream xdr;
1949 enum nfs_stat status;
1952 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
1953 error = decode_nfsstat3(&xdr, &status);
1954 if (unlikely(error))
1956 error = decode_post_op_attr(&xdr, result->fattr);
1957 if (unlikely(error))
1959 error = decode_wcc_data(&xdr, result->dir_attr);
1960 if (unlikely(error))
1962 if (status != NFS3_OK)
1967 return nfs_stat_to_errno(status);
1971 * nfs3_decode_dirent - Decode a single NFSv3 directory entry stored in
1972 * the local page cache
1973 * @xdr: XDR stream where entry resides
1974 * @entry: buffer to fill in with entry data
1975 * @server: nfs_server data for this directory
1976 * @plus: boolean indicating whether this should be a readdirplus entry
1978 * Returns the position of the next item in the buffer, or an ERR_PTR.
1980 * This function is not invoked during READDIR reply decoding, but
1981 * rather whenever an application invokes the getdents(2) system call
1982 * on a directory already in our cache.
1990 * fhandle3 filehandle;
1991 * post_op_attr3 attributes;
1992 * entry3 *nextentry;
1996 * struct entryplus3 {
2000 * post_op_attr name_attributes;
2001 * post_op_fh3 name_handle;
2002 * entryplus3 *nextentry;
2005 __be32 *nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
2006 struct nfs_server *server, int plus)
2008 struct nfs_entry old = *entry;
2012 p = xdr_inline_decode(xdr, 4);
2013 if (unlikely(p == NULL))
2015 if (*p == xdr_zero) {
2016 p = xdr_inline_decode(xdr, 4);
2017 if (unlikely(p == NULL))
2020 return ERR_PTR(-EAGAIN);
2022 return ERR_PTR(-EBADCOOKIE);
2025 error = decode_fileid3(xdr, &entry->ino);
2026 if (unlikely(error))
2027 return ERR_PTR(error);
2029 error = decode_inline_filename3(xdr, &entry->name, &entry->len);
2030 if (unlikely(error))
2031 return ERR_PTR(error);
2033 entry->prev_cookie = entry->cookie;
2034 error = decode_cookie3(xdr, &entry->cookie);
2035 if (unlikely(error))
2036 return ERR_PTR(error);
2038 entry->d_type = DT_UNKNOWN;
2041 entry->fattr->valid = 0;
2042 error = decode_post_op_attr(xdr, entry->fattr);
2043 if (unlikely(error))
2044 return ERR_PTR(error);
2045 if (entry->fattr->valid & NFS_ATTR_FATTR_V3)
2046 entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
2048 /* In fact, a post_op_fh3: */
2049 p = xdr_inline_decode(xdr, 4);
2050 if (unlikely(p == NULL))
2052 if (*p != xdr_zero) {
2053 error = decode_nfs_fh3(xdr, entry->fh);
2054 if (unlikely(error)) {
2055 if (error == -E2BIG)
2057 return ERR_PTR(error);
2060 zero_nfs_fh3(entry->fh);
2063 /* Peek at the next entry to see if we're at EOD */
2064 p = xdr_inline_peek(xdr, 4 + 4);
2067 entry->eof = (p[0] == xdr_zero) && (p[1] != xdr_zero);
2071 print_overflow_msg(__func__, xdr);
2072 return ERR_PTR(-EAGAIN);
2074 dprintk("NFS: directory entry contains invalid file handle\n");
2076 return ERR_PTR(-EAGAIN);
2080 * 3.3.16 READDIR3res
2087 * struct READDIR3resok {
2088 * post_op_attr dir_attributes;
2089 * cookieverf3 cookieverf;
2093 * struct READDIR3resfail {
2094 * post_op_attr dir_attributes;
2097 * union READDIR3res switch (nfsstat3 status) {
2099 * READDIR3resok resok;
2101 * READDIR3resfail resfail;
2104 * Read the directory contents into the page cache, but otherwise
2105 * don't touch them. The actual decoding is done by nfs3_decode_entry()
2106 * during subsequent nfs_readdir() calls.
2108 static int decode_dirlist3(struct xdr_stream *xdr)
2113 pglen = xdr->buf->page_len;
2114 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
2115 recvd = xdr->buf->len - hdrlen;
2116 if (unlikely(pglen > recvd))
2119 xdr_read_pages(xdr, pglen);
2122 dprintk("NFS: server cheating in readdir result: "
2123 "pglen %u > recvd %u\n", pglen, recvd);
2128 static int decode_readdir3resok(struct xdr_stream *xdr,
2129 struct nfs3_readdirres *result)
2133 error = decode_post_op_attr(xdr, result->dir_attr);
2134 if (unlikely(error))
2136 /* XXX: do we need to check if result->verf != NULL ? */
2137 error = decode_cookieverf3(xdr, result->verf);
2138 if (unlikely(error))
2140 error = decode_dirlist3(xdr);
2145 static int nfs3_xdr_dec_readdir3res(struct rpc_rqst *req, __be32 *p,
2146 struct nfs3_readdirres *result)
2148 struct xdr_stream xdr;
2149 enum nfs_stat status;
2152 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2153 error = decode_nfsstat3(&xdr, &status);
2154 if (unlikely(error))
2156 if (status != NFS3_OK)
2158 error = decode_readdir3resok(&xdr, result);
2162 error = decode_post_op_attr(&xdr, result->dir_attr);
2163 if (unlikely(error))
2165 return nfs_stat_to_errno(status);
2171 * struct FSSTAT3resok {
2172 * post_op_attr obj_attributes;
2182 * struct FSSTAT3resfail {
2183 * post_op_attr obj_attributes;
2186 * union FSSTAT3res switch (nfsstat3 status) {
2188 * FSSTAT3resok resok;
2190 * FSSTAT3resfail resfail;
2193 static int decode_fsstat3resok(struct xdr_stream *xdr,
2194 struct nfs_fsstat *result)
2198 p = xdr_inline_decode(xdr, 8 * 6 + 4);
2199 if (unlikely(p == NULL))
2201 p = xdr_decode_size3(p, &result->tbytes);
2202 p = xdr_decode_size3(p, &result->fbytes);
2203 p = xdr_decode_size3(p, &result->abytes);
2204 p = xdr_decode_size3(p, &result->tfiles);
2205 p = xdr_decode_size3(p, &result->ffiles);
2206 xdr_decode_size3(p, &result->afiles);
2207 /* ignore invarsec */
2210 print_overflow_msg(__func__, xdr);
2214 static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req, __be32 *p,
2215 struct nfs_fsstat *result)
2217 struct xdr_stream xdr;
2218 enum nfs_stat status;
2221 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2222 error = decode_nfsstat3(&xdr, &status);
2223 if (unlikely(error))
2225 error = decode_post_op_attr(&xdr, result->fattr);
2226 if (unlikely(error))
2228 if (status != NFS3_OK)
2230 error = decode_fsstat3resok(&xdr, result);
2234 return nfs_stat_to_errno(status);
2240 * struct FSINFO3resok {
2241 * post_op_attr obj_attributes;
2249 * size3 maxfilesize;
2250 * nfstime3 time_delta;
2251 * uint32 properties;
2254 * struct FSINFO3resfail {
2255 * post_op_attr obj_attributes;
2258 * union FSINFO3res switch (nfsstat3 status) {
2260 * FSINFO3resok resok;
2262 * FSINFO3resfail resfail;
2265 static int decode_fsinfo3resok(struct xdr_stream *xdr,
2266 struct nfs_fsinfo *result)
2270 p = xdr_inline_decode(xdr, 4 * 7 + 8 + 8 + 4);
2271 if (unlikely(p == NULL))
2273 result->rtmax = be32_to_cpup(p++);
2274 result->rtpref = be32_to_cpup(p++);
2275 result->rtmult = be32_to_cpup(p++);
2276 result->wtmax = be32_to_cpup(p++);
2277 result->wtpref = be32_to_cpup(p++);
2278 result->wtmult = be32_to_cpup(p++);
2279 result->dtpref = be32_to_cpup(p++);
2280 p = xdr_decode_size3(p, &result->maxfilesize);
2281 xdr_decode_time3(p, &result->time_delta);
2283 /* ignore properties */
2284 result->lease_time = 0;
2287 print_overflow_msg(__func__, xdr);
2291 static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req, __be32 *p,
2292 struct nfs_fsinfo *result)
2294 struct xdr_stream xdr;
2295 enum nfs_stat status;
2298 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2299 error = decode_nfsstat3(&xdr, &status);
2300 if (unlikely(error))
2302 error = decode_post_op_attr(&xdr, result->fattr);
2303 if (unlikely(error))
2305 if (status != NFS3_OK)
2307 error = decode_fsinfo3resok(&xdr, result);
2311 return nfs_stat_to_errno(status);
2315 * 3.3.20 PATHCONF3res
2317 * struct PATHCONF3resok {
2318 * post_op_attr obj_attributes;
2322 * bool chown_restricted;
2323 * bool case_insensitive;
2324 * bool case_preserving;
2327 * struct PATHCONF3resfail {
2328 * post_op_attr obj_attributes;
2331 * union PATHCONF3res switch (nfsstat3 status) {
2333 * PATHCONF3resok resok;
2335 * PATHCONF3resfail resfail;
2338 static int decode_pathconf3resok(struct xdr_stream *xdr,
2339 struct nfs_pathconf *result)
2343 p = xdr_inline_decode(xdr, 4 * 6);
2344 if (unlikely(p == NULL))
2346 result->max_link = be32_to_cpup(p++);
2347 result->max_namelen = be32_to_cpup(p);
2348 /* ignore remaining fields */
2351 print_overflow_msg(__func__, xdr);
2355 static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req, __be32 *p,
2356 struct nfs_pathconf *result)
2358 struct xdr_stream xdr;
2359 enum nfs_stat status;
2362 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2363 error = decode_nfsstat3(&xdr, &status);
2364 if (unlikely(error))
2366 error = decode_post_op_attr(&xdr, result->fattr);
2367 if (unlikely(error))
2369 if (status != NFS3_OK)
2371 error = decode_pathconf3resok(&xdr, result);
2375 return nfs_stat_to_errno(status);
2381 * struct COMMIT3resok {
2382 * wcc_data file_wcc;
2386 * struct COMMIT3resfail {
2387 * wcc_data file_wcc;
2390 * union COMMIT3res switch (nfsstat3 status) {
2392 * COMMIT3resok resok;
2394 * COMMIT3resfail resfail;
2397 static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req, __be32 *p,
2398 struct nfs_writeres *result)
2400 struct xdr_stream xdr;
2401 enum nfs_stat status;
2404 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2405 error = decode_nfsstat3(&xdr, &status);
2406 if (unlikely(error))
2408 error = decode_wcc_data(&xdr, result->fattr);
2409 if (unlikely(error))
2411 if (status != NFS3_OK)
2413 error = decode_writeverf3(&xdr, result->verf->verifier);
2417 return nfs_stat_to_errno(status);
2420 #ifdef CONFIG_NFS_V3_ACL
2422 static inline int decode_getacl3resok(struct xdr_stream *xdr,
2423 struct nfs3_getaclres *result)
2425 struct posix_acl **acl;
2426 unsigned int *aclcnt;
2430 error = decode_post_op_attr(xdr, result->fattr);
2431 if (unlikely(error))
2433 error = decode_uint32(xdr, &result->mask);
2434 if (unlikely(error))
2437 if (result->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
2440 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
2443 if (result->mask & NFS_ACL)
2444 acl = &result->acl_access;
2446 if (result->mask & NFS_ACLCNT)
2447 aclcnt = &result->acl_access_count;
2448 error = nfsacl_decode(xdr->buf, hdrlen, aclcnt, acl);
2449 if (unlikely(error <= 0))
2453 if (result->mask & NFS_DFACL)
2454 acl = &result->acl_default;
2456 if (result->mask & NFS_DFACLCNT)
2457 aclcnt = &result->acl_default_count;
2458 error = nfsacl_decode(xdr->buf, hdrlen + error, aclcnt, acl);
2459 if (unlikely(error <= 0))
2466 static int nfs3_xdr_dec_getacl3res(struct rpc_rqst *req, __be32 *p,
2467 struct nfs3_getaclres *result)
2469 struct xdr_stream xdr;
2470 enum nfs_stat status;
2473 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2474 error = decode_nfsstat3(&xdr, &status);
2475 if (unlikely(error))
2477 if (status != NFS3_OK)
2479 error = decode_getacl3resok(&xdr, result);
2483 return nfs_stat_to_errno(status);
2486 static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req, __be32 *p,
2487 struct nfs_fattr *result)
2489 struct xdr_stream xdr;
2490 enum nfs_stat status;
2493 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
2494 error = decode_nfsstat3(&xdr, &status);
2495 if (unlikely(error))
2497 if (status != NFS3_OK)
2499 error = decode_post_op_attr(&xdr, result);
2503 return nfs_stat_to_errno(status);
2506 #endif /* CONFIG_NFS_V3_ACL */
2508 #define PROC(proc, argtype, restype, timer) \
2509 [NFS3PROC_##proc] = { \
2510 .p_proc = NFS3PROC_##proc, \
2511 .p_encode = (kxdrproc_t)nfs3_xdr_enc_##argtype##3args, \
2512 .p_decode = (kxdrproc_t)nfs3_xdr_dec_##restype##3res, \
2513 .p_arglen = NFS3_##argtype##args_sz, \
2514 .p_replen = NFS3_##restype##res_sz, \
2516 .p_statidx = NFS3PROC_##proc, \
2520 struct rpc_procinfo nfs3_procedures[] = {
2521 PROC(GETATTR, getattr, getattr, 1),
2522 PROC(SETATTR, setattr, setattr, 0),
2523 PROC(LOOKUP, lookup, lookup, 2),
2524 PROC(ACCESS, access, access, 1),
2525 PROC(READLINK, readlink, readlink, 3),
2526 PROC(READ, read, read, 3),
2527 PROC(WRITE, write, write, 4),
2528 PROC(CREATE, create, create, 0),
2529 PROC(MKDIR, mkdir, create, 0),
2530 PROC(SYMLINK, symlink, create, 0),
2531 PROC(MKNOD, mknod, create, 0),
2532 PROC(REMOVE, remove, remove, 0),
2533 PROC(RMDIR, lookup, setattr, 0),
2534 PROC(RENAME, rename, rename, 0),
2535 PROC(LINK, link, link, 0),
2536 PROC(READDIR, readdir, readdir, 3),
2537 PROC(READDIRPLUS, readdirplus, readdir, 3),
2538 PROC(FSSTAT, getattr, fsstat, 0),
2539 PROC(FSINFO, getattr, fsinfo, 0),
2540 PROC(PATHCONF, getattr, pathconf, 0),
2541 PROC(COMMIT, commit, commit, 5),
2544 struct rpc_version nfs_version3 = {
2546 .nrprocs = ARRAY_SIZE(nfs3_procedures),
2547 .procs = nfs3_procedures
2550 #ifdef CONFIG_NFS_V3_ACL
2551 static struct rpc_procinfo nfs3_acl_procedures[] = {
2552 [ACLPROC3_GETACL] = {
2553 .p_proc = ACLPROC3_GETACL,
2554 .p_encode = (kxdrproc_t)nfs3_xdr_enc_getacl3args,
2555 .p_decode = (kxdrproc_t)nfs3_xdr_dec_getacl3res,
2556 .p_arglen = ACL3_getaclargs_sz,
2557 .p_replen = ACL3_getaclres_sz,
2561 [ACLPROC3_SETACL] = {
2562 .p_proc = ACLPROC3_SETACL,
2563 .p_encode = (kxdrproc_t)nfs3_xdr_enc_setacl3args,
2564 .p_decode = (kxdrproc_t)nfs3_xdr_dec_setacl3res,
2565 .p_arglen = ACL3_setaclargs_sz,
2566 .p_replen = ACL3_setaclres_sz,
2572 struct rpc_version nfsacl_version3 = {
2574 .nrprocs = sizeof(nfs3_acl_procedures)/
2575 sizeof(nfs3_acl_procedures[0]),
2576 .procs = nfs3_acl_procedures,
2578 #endif /* CONFIG_NFS_V3_ACL */