2 * linux/fs/nfs/nfs3xdr.c
4 * XDR functions to encode/decode NFSv3 RPC arguments and results.
6 * Copyright (C) 1996, 1997 Olaf Kirch
9 #include <linux/param.h>
10 #include <linux/time.h>
12 #include <linux/errno.h>
13 #include <linux/string.h>
15 #include <linux/pagemap.h>
16 #include <linux/proc_fs.h>
17 #include <linux/kdev_t.h>
18 #include <linux/sunrpc/clnt.h>
19 #include <linux/nfs.h>
20 #include <linux/nfs3.h>
21 #include <linux/nfs_fs.h>
22 #include <linux/nfsacl.h>
25 #define NFSDBG_FACILITY NFSDBG_XDR
27 /* Mapping from NFS error code to "errno" error code. */
28 #define errno_NFSERR_IO EIO
31 * Declare the space requirements for NFS arguments and replies as
32 * number of 32bit-words
34 #define NFS3_fhandle_sz (1+16)
35 #define NFS3_fh_sz (NFS3_fhandle_sz) /* shorthand */
36 #define NFS3_sattr_sz (15)
37 #define NFS3_filename_sz (1+(NFS3_MAXNAMLEN>>2))
38 #define NFS3_path_sz (1+(NFS3_MAXPATHLEN>>2))
39 #define NFS3_fattr_sz (21)
40 #define NFS3_cookieverf_sz (NFS3_COOKIEVERFSIZE>>2)
41 #define NFS3_wcc_attr_sz (6)
42 #define NFS3_pre_op_attr_sz (1+NFS3_wcc_attr_sz)
43 #define NFS3_post_op_attr_sz (1+NFS3_fattr_sz)
44 #define NFS3_wcc_data_sz (NFS3_pre_op_attr_sz+NFS3_post_op_attr_sz)
45 #define NFS3_fsstat_sz
46 #define NFS3_fsinfo_sz
47 #define NFS3_pathconf_sz
48 #define NFS3_entry_sz (NFS3_filename_sz+3)
49 #define NFS3_diropargs_sz (NFS3_fh_sz+NFS3_filename_sz)
51 #define NFS3_getattrargs_sz (NFS3_fh_sz)
52 #define NFS3_setattrargs_sz (NFS3_fh_sz+NFS3_sattr_sz+3)
53 #define NFS3_lookupargs_sz (NFS3_fh_sz+NFS3_filename_sz)
54 #define NFS3_accessargs_sz (NFS3_fh_sz+1)
55 #define NFS3_readlinkargs_sz (NFS3_fh_sz)
56 #define NFS3_readargs_sz (NFS3_fh_sz+3)
57 #define NFS3_writeargs_sz (NFS3_fh_sz+5)
58 #define NFS3_createargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz)
59 #define NFS3_mkdirargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz)
60 #define NFS3_symlinkargs_sz (NFS3_diropargs_sz+1+NFS3_sattr_sz)
61 #define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz)
62 #define NFS3_removeargs_sz (NFS3_fh_sz+NFS3_filename_sz)
63 #define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz)
64 #define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz)
65 #define NFS3_readdirargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+3)
66 #define NFS3_readdirplusargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+4)
67 #define NFS3_commitargs_sz (NFS3_fh_sz+3)
69 #define NFS3_attrstat_sz (1+NFS3_fattr_sz)
70 #define NFS3_wccstat_sz (1+NFS3_wcc_data_sz)
71 #define NFS3_removeres_sz (NFS3_wccstat_sz)
72 #define NFS3_lookupres_sz (1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz))
73 #define NFS3_accessres_sz (1+NFS3_post_op_attr_sz+1)
74 #define NFS3_readlinkres_sz (1+NFS3_post_op_attr_sz+1)
75 #define NFS3_readres_sz (1+NFS3_post_op_attr_sz+3)
76 #define NFS3_writeres_sz (1+NFS3_wcc_data_sz+4)
77 #define NFS3_createres_sz (1+NFS3_fh_sz+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
78 #define NFS3_renameres_sz (1+(2 * NFS3_wcc_data_sz))
79 #define NFS3_linkres_sz (1+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
80 #define NFS3_readdirres_sz (1+NFS3_post_op_attr_sz+2)
81 #define NFS3_fsstatres_sz (1+NFS3_post_op_attr_sz+13)
82 #define NFS3_fsinfores_sz (1+NFS3_post_op_attr_sz+12)
83 #define NFS3_pathconfres_sz (1+NFS3_post_op_attr_sz+6)
84 #define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2)
86 #define ACL3_getaclargs_sz (NFS3_fh_sz+1)
87 #define ACL3_setaclargs_sz (NFS3_fh_sz+1+ \
88 XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
89 #define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+ \
90 XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
91 #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz)
94 * Map file type to S_IFMT bits
96 static const umode_t nfs_type2fmt[] = {
103 [NF3SOCK] = S_IFSOCK,
107 static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
109 dprintk("nfs: %s: prematurely hit end of receive buffer. "
110 "Remaining buffer length is %tu words.\n",
111 func, xdr->end - xdr->p);
115 * While encoding arguments, set up the reply buffer in advance to
116 * receive reply data directly into the page cache.
118 static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
119 unsigned int base, unsigned int len,
120 unsigned int bufsize)
122 struct rpc_auth *auth = req->rq_cred->cr_auth;
125 replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
126 xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
131 * Common NFS XDR functions as inlines
133 static inline __be32 *
134 xdr_decode_fhandle(__be32 *p, struct nfs_fh *fh)
136 if ((fh->size = ntohl(*p++)) <= NFS3_FHSIZE) {
137 memcpy(fh->data, p, fh->size);
138 return p + XDR_QUADLEN(fh->size);
143 static inline __be32 *
144 xdr_decode_fhandle_stream(struct xdr_stream *xdr, struct nfs_fh *fh)
147 p = xdr_inline_decode(xdr, 4);
150 fh->size = ntohl(*p++);
152 if (fh->size <= NFS3_FHSIZE) {
153 p = xdr_inline_decode(xdr, fh->size);
156 memcpy(fh->data, p, fh->size);
157 return p + XDR_QUADLEN(fh->size);
162 print_overflow_msg(__func__, xdr);
163 return ERR_PTR(-EIO);
167 * Encode/decode time.
169 static inline __be32 *
170 xdr_encode_time3(__be32 *p, const struct timespec *timep)
172 *p++ = htonl(timep->tv_sec);
173 *p++ = htonl(timep->tv_nsec);
177 static inline __be32 *
178 xdr_decode_time3(__be32 *p, struct timespec *timep)
180 timep->tv_sec = ntohl(*p++);
181 timep->tv_nsec = ntohl(*p++);
186 xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
188 unsigned int type, major, minor;
194 fmode = nfs_type2fmt[type];
195 fattr->mode = (ntohl(*p++) & ~S_IFMT) | fmode;
196 fattr->nlink = ntohl(*p++);
197 fattr->uid = ntohl(*p++);
198 fattr->gid = ntohl(*p++);
199 p = xdr_decode_hyper(p, &fattr->size);
200 p = xdr_decode_hyper(p, &fattr->du.nfs3.used);
202 /* Turn remote device info into Linux-specific dev_t */
205 fattr->rdev = MKDEV(major, minor);
206 if (MAJOR(fattr->rdev) != major || MINOR(fattr->rdev) != minor)
209 p = xdr_decode_hyper(p, &fattr->fsid.major);
210 fattr->fsid.minor = 0;
211 p = xdr_decode_hyper(p, &fattr->fileid);
212 p = xdr_decode_time3(p, &fattr->atime);
213 p = xdr_decode_time3(p, &fattr->mtime);
214 p = xdr_decode_time3(p, &fattr->ctime);
216 /* Update the mode bits */
217 fattr->valid |= NFS_ATTR_FATTR_V3;
221 static inline __be32 *
222 xdr_encode_sattr(__be32 *p, const struct iattr *attr)
224 if (attr->ia_valid & ATTR_MODE) {
226 *p++ = htonl(attr->ia_mode & S_IALLUGO);
230 if (attr->ia_valid & ATTR_UID) {
232 *p++ = htonl(attr->ia_uid);
236 if (attr->ia_valid & ATTR_GID) {
238 *p++ = htonl(attr->ia_gid);
242 if (attr->ia_valid & ATTR_SIZE) {
244 p = xdr_encode_hyper(p, (__u64) attr->ia_size);
248 if (attr->ia_valid & ATTR_ATIME_SET) {
250 p = xdr_encode_time3(p, &attr->ia_atime);
251 } else if (attr->ia_valid & ATTR_ATIME) {
256 if (attr->ia_valid & ATTR_MTIME_SET) {
258 p = xdr_encode_time3(p, &attr->ia_mtime);
259 } else if (attr->ia_valid & ATTR_MTIME) {
267 static inline __be32 *
268 xdr_decode_wcc_attr(__be32 *p, struct nfs_fattr *fattr)
270 p = xdr_decode_hyper(p, &fattr->pre_size);
271 p = xdr_decode_time3(p, &fattr->pre_mtime);
272 p = xdr_decode_time3(p, &fattr->pre_ctime);
273 fattr->valid |= NFS_ATTR_FATTR_PRESIZE
274 | NFS_ATTR_FATTR_PREMTIME
275 | NFS_ATTR_FATTR_PRECTIME;
279 static inline __be32 *
280 xdr_decode_post_op_attr(__be32 *p, struct nfs_fattr *fattr)
283 p = xdr_decode_fattr(p, fattr);
287 static inline __be32 *
288 xdr_decode_post_op_attr_stream(struct xdr_stream *xdr, struct nfs_fattr *fattr)
292 p = xdr_inline_decode(xdr, 4);
296 p = xdr_inline_decode(xdr, 84);
299 p = xdr_decode_fattr(p, fattr);
303 print_overflow_msg(__func__, xdr);
304 return ERR_PTR(-EIO);
307 static inline __be32 *
308 xdr_decode_pre_op_attr(__be32 *p, struct nfs_fattr *fattr)
311 return xdr_decode_wcc_attr(p, fattr);
316 static inline __be32 *
317 xdr_decode_wcc_data(__be32 *p, struct nfs_fattr *fattr)
319 p = xdr_decode_pre_op_attr(p, fattr);
320 return xdr_decode_post_op_attr(p, fattr);
325 * Encode/decode NFSv3 basic data types
327 * Basic NFSv3 data types are defined in section 2.5 of RFC 1813:
328 * "NFS Version 3 Protocol Specification".
330 * Not all basic data types have their own encoding and decoding
331 * functions. For run-time efficiency, some data types are encoded
335 static void encode_uint32(struct xdr_stream *xdr, u32 value)
337 __be32 *p = xdr_reserve_space(xdr, 4);
338 *p = cpu_to_be32(value);
344 * typedef string filename3<>;
346 static void encode_filename3(struct xdr_stream *xdr,
347 const char *name, u32 length)
351 BUG_ON(length > NFS3_MAXNAMLEN);
352 p = xdr_reserve_space(xdr, 4 + length);
353 xdr_encode_opaque(p, name, length);
359 * typedef string nfspath3<>;
361 static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages,
364 BUG_ON(length > NFS3_MAXPATHLEN);
365 encode_uint32(xdr, length);
366 xdr_write_pages(xdr, pages, 0, length);
372 * typedef uint64 cookie3
374 static __be32 *xdr_encode_cookie3(__be32 *p, u64 cookie)
376 return xdr_encode_hyper(p, cookie);
382 * typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
384 static __be32 *xdr_encode_cookieverf3(__be32 *p, const __be32 *verifier)
386 memcpy(p, verifier, NFS3_COOKIEVERFSIZE);
387 return p + XDR_QUADLEN(NFS3_COOKIEVERFSIZE);
393 * typedef opaque createverf3[NFS3_CREATEVERFSIZE];
395 static void encode_createverf3(struct xdr_stream *xdr, const __be32 *verifier)
399 p = xdr_reserve_space(xdr, NFS3_CREATEVERFSIZE);
400 memcpy(p, verifier, NFS3_CREATEVERFSIZE);
416 static void encode_ftype3(struct xdr_stream *xdr, const u32 type)
418 BUG_ON(type > NF3FIFO);
419 encode_uint32(xdr, type);
430 static void encode_specdata3(struct xdr_stream *xdr, const dev_t rdev)
434 p = xdr_reserve_space(xdr, 8);
435 *p++ = cpu_to_be32(MAJOR(rdev));
436 *p = cpu_to_be32(MINOR(rdev));
443 * opaque data<NFS3_FHSIZE>;
446 static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh)
450 BUG_ON(fh->size > NFS3_FHSIZE);
451 p = xdr_reserve_space(xdr, 4 + fh->size);
452 xdr_encode_opaque(p, fh->data, fh->size);
460 * SET_TO_SERVER_TIME = 1,
461 * SET_TO_CLIENT_TIME = 2
464 * union set_mode3 switch (bool set_it) {
471 * union set_uid3 switch (bool set_it) {
478 * union set_gid3 switch (bool set_it) {
485 * union set_size3 switch (bool set_it) {
492 * union set_atime switch (time_how set_it) {
493 * case SET_TO_CLIENT_TIME:
499 * union set_mtime switch (time_how set_it) {
500 * case SET_TO_CLIENT_TIME:
515 static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)
521 * In order to make only a single xdr_reserve_space() call,
522 * pre-compute the total number of bytes to be reserved.
523 * Six boolean values, one for each set_foo field, are always
524 * present in the encoded result, so start there.
527 if (attr->ia_valid & ATTR_MODE)
529 if (attr->ia_valid & ATTR_UID)
531 if (attr->ia_valid & ATTR_GID)
533 if (attr->ia_valid & ATTR_SIZE)
535 if (attr->ia_valid & ATTR_ATIME_SET)
537 if (attr->ia_valid & ATTR_MTIME_SET)
539 p = xdr_reserve_space(xdr, nbytes);
541 xdr_encode_sattr(p, attr);
547 * struct diropargs3 {
552 static void encode_diropargs3(struct xdr_stream *xdr, const struct nfs_fh *fh,
553 const char *name, u32 length)
555 encode_nfs_fh3(xdr, fh);
556 encode_filename3(xdr, name, length);
561 * NFSv3 XDR encode functions
563 * NFSv3 argument types are defined in section 3.3 of RFC 1813:
564 * "NFS Version 3 Protocol Specification".
570 * struct GETATTR3args {
574 static int nfs3_xdr_enc_getattr3args(struct rpc_rqst *req, __be32 *p,
575 const struct nfs_fh *fh)
577 struct xdr_stream xdr;
579 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
580 encode_nfs_fh3(&xdr, fh);
587 * union sattrguard3 switch (bool check) {
589 * nfstime3 obj_ctime;
594 * struct SETATTR3args {
596 * sattr3 new_attributes;
600 static void encode_sattrguard3(struct xdr_stream *xdr,
601 const struct nfs3_sattrargs *args)
606 p = xdr_reserve_space(xdr, 4 + 8);
608 xdr_encode_time3(p, &args->guardtime);
610 p = xdr_reserve_space(xdr, 4);
615 static int nfs3_xdr_enc_setattr3args(struct rpc_rqst *req, __be32 *p,
616 const struct nfs3_sattrargs *args)
618 struct xdr_stream xdr;
620 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
621 encode_nfs_fh3(&xdr, args->fh);
622 encode_sattr3(&xdr, args->sattr);
623 encode_sattrguard3(&xdr, args);
630 * struct LOOKUP3args {
634 static int nfs3_xdr_enc_lookup3args(struct rpc_rqst *req, __be32 *p,
635 const struct nfs3_diropargs *args)
637 struct xdr_stream xdr;
639 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
640 encode_diropargs3(&xdr, args->fh, args->name, args->len);
647 * struct ACCESS3args {
652 static void encode_access3args(struct xdr_stream *xdr,
653 const struct nfs3_accessargs *args)
655 encode_nfs_fh3(xdr, args->fh);
656 encode_uint32(xdr, args->access);
659 static int nfs3_xdr_enc_access3args(struct rpc_rqst *req, __be32 *p,
660 const struct nfs3_accessargs *args)
662 struct xdr_stream xdr;
664 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
665 encode_access3args(&xdr, args);
670 * 3.3.5 READLINK3args
672 * struct READLINK3args {
676 static int nfs3_xdr_enc_readlink3args(struct rpc_rqst *req, __be32 *p,
677 const struct nfs3_readlinkargs *args)
679 struct xdr_stream xdr;
681 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
682 encode_nfs_fh3(&xdr, args->fh);
683 prepare_reply_buffer(req, args->pages, args->pgbase,
684 args->pglen, NFS3_readlinkres_sz);
697 static void encode_read3args(struct xdr_stream *xdr,
698 const struct nfs_readargs *args)
702 encode_nfs_fh3(xdr, args->fh);
704 p = xdr_reserve_space(xdr, 8 + 4);
705 p = xdr_encode_hyper(p, args->offset);
706 *p = cpu_to_be32(args->count);
709 static int nfs3_xdr_enc_read3args(struct rpc_rqst *req, __be32 *p,
710 const struct nfs_readargs *args)
712 struct xdr_stream xdr;
714 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
715 encode_read3args(&xdr, args);
716 prepare_reply_buffer(req, args->pages, args->pgbase,
717 args->count, NFS3_readres_sz);
718 req->rq_rcv_buf.flags |= XDRBUF_READ;
731 * struct WRITE3args {
739 static void encode_write3args(struct xdr_stream *xdr,
740 const struct nfs_writeargs *args)
744 encode_nfs_fh3(xdr, args->fh);
746 p = xdr_reserve_space(xdr, 8 + 4 + 4 + 4);
747 p = xdr_encode_hyper(p, args->offset);
748 *p++ = cpu_to_be32(args->count);
750 BUG_ON(args->stable > NFS_FILE_SYNC);
751 *p++ = cpu_to_be32(args->stable);
753 *p = cpu_to_be32(args->count);
754 xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
757 static int nfs3_xdr_enc_write3args(struct rpc_rqst *req, __be32 *p,
758 const struct nfs_writeargs *args)
760 struct xdr_stream xdr;
762 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
763 encode_write3args(&xdr, args);
764 xdr.buf->flags |= XDRBUF_WRITE;
777 * union createhow3 switch (createmode3 mode) {
780 * sattr3 obj_attributes;
785 * struct CREATE3args {
790 static void encode_createhow3(struct xdr_stream *xdr,
791 const struct nfs3_createargs *args)
793 encode_uint32(xdr, args->createmode);
794 switch (args->createmode) {
795 case NFS3_CREATE_UNCHECKED:
796 case NFS3_CREATE_GUARDED:
797 encode_sattr3(xdr, args->sattr);
799 case NFS3_CREATE_EXCLUSIVE:
800 encode_createverf3(xdr, args->verifier);
807 static int nfs3_xdr_enc_create3args(struct rpc_rqst *req, __be32 *p,
808 const struct nfs3_createargs *args)
810 struct xdr_stream xdr;
812 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
813 encode_diropargs3(&xdr, args->fh, args->name, args->len);
814 encode_createhow3(&xdr, args);
821 * struct MKDIR3args {
826 static int nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req, __be32 *p,
827 const struct nfs3_mkdirargs *args)
829 struct xdr_stream xdr;
831 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
832 encode_diropargs3(&xdr, args->fh, args->name, args->len);
833 encode_sattr3(&xdr, args->sattr);
838 * 3.3.10 SYMLINK3args
840 * struct symlinkdata3 {
841 * sattr3 symlink_attributes;
842 * nfspath3 symlink_data;
845 * struct SYMLINK3args {
847 * symlinkdata3 symlink;
850 static void encode_symlinkdata3(struct xdr_stream *xdr,
851 const struct nfs3_symlinkargs *args)
853 encode_sattr3(xdr, args->sattr);
854 encode_nfspath3(xdr, args->pages, args->pathlen);
857 static int nfs3_xdr_enc_symlink3args(struct rpc_rqst *req, __be32 *p,
858 const struct nfs3_symlinkargs *args)
860 struct xdr_stream xdr;
862 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
863 encode_diropargs3(&xdr, args->fromfh, args->fromname, args->fromlen);
864 encode_symlinkdata3(&xdr, args);
871 * struct devicedata3 {
872 * sattr3 dev_attributes;
876 * union mknoddata3 switch (ftype3 type) {
879 * devicedata3 device;
882 * sattr3 pipe_attributes;
887 * struct MKNOD3args {
892 static void encode_devicedata3(struct xdr_stream *xdr,
893 const struct nfs3_mknodargs *args)
895 encode_sattr3(xdr, args->sattr);
896 encode_specdata3(xdr, args->rdev);
899 static void encode_mknoddata3(struct xdr_stream *xdr,
900 const struct nfs3_mknodargs *args)
902 encode_ftype3(xdr, args->type);
903 switch (args->type) {
906 encode_devicedata3(xdr, args);
910 encode_sattr3(xdr, args->sattr);
920 static int nfs3_xdr_enc_mknod3args(struct rpc_rqst *req, __be32 *p,
921 const struct nfs3_mknodargs *args)
923 struct xdr_stream xdr;
925 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
926 encode_diropargs3(&xdr, args->fh, args->name, args->len);
927 encode_mknoddata3(&xdr, args);
934 * struct REMOVE3args {
938 static int nfs3_xdr_enc_remove3args(struct rpc_rqst *req, __be32 *p,
939 const struct nfs_removeargs *args)
941 struct xdr_stream xdr;
943 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
944 encode_diropargs3(&xdr, args->fh, args->name.name, args->name.len);
951 * struct RENAME3args {
956 static int nfs3_xdr_enc_rename3args(struct rpc_rqst *req, __be32 *p,
957 const struct nfs_renameargs *args)
959 const struct qstr *old = args->old_name;
960 const struct qstr *new = args->new_name;
961 struct xdr_stream xdr;
963 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
964 encode_diropargs3(&xdr, args->old_dir, old->name, old->len);
965 encode_diropargs3(&xdr, args->new_dir, new->name, new->len);
977 static int nfs3_xdr_enc_link3args(struct rpc_rqst *req, __be32 *p,
978 const struct nfs3_linkargs *args)
980 struct xdr_stream xdr;
982 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
983 encode_nfs_fh3(&xdr, args->fromfh);
984 encode_diropargs3(&xdr, args->tofh, args->toname, args->tolen);
989 * 3.3.16 READDIR3args
991 * struct READDIR3args {
994 * cookieverf3 cookieverf;
998 static void encode_readdir3args(struct xdr_stream *xdr,
999 const struct nfs3_readdirargs *args)
1003 encode_nfs_fh3(xdr, args->fh);
1005 p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4);
1006 p = xdr_encode_cookie3(p, args->cookie);
1007 p = xdr_encode_cookieverf3(p, args->verf);
1008 *p = cpu_to_be32(args->count);
1011 static int nfs3_xdr_enc_readdir3args(struct rpc_rqst *req, __be32 *p,
1012 const struct nfs3_readdirargs *args)
1014 struct xdr_stream xdr;
1016 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1017 encode_readdir3args(&xdr, args);
1018 prepare_reply_buffer(req, args->pages, 0,
1019 args->count, NFS3_readdirres_sz);
1024 * 3.3.17 READDIRPLUS3args
1026 * struct READDIRPLUS3args {
1029 * cookieverf3 cookieverf;
1034 static void encode_readdirplus3args(struct xdr_stream *xdr,
1035 const struct nfs3_readdirargs *args)
1039 encode_nfs_fh3(xdr, args->fh);
1041 p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4 + 4);
1042 p = xdr_encode_cookie3(p, args->cookie);
1043 p = xdr_encode_cookieverf3(p, args->verf);
1046 * readdirplus: need dircount + buffer size.
1047 * We just make sure we make dircount big enough
1049 *p++ = cpu_to_be32(args->count >> 3);
1051 *p = cpu_to_be32(args->count);
1054 static int nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req, __be32 *p,
1055 const struct nfs3_readdirargs *args)
1057 struct xdr_stream xdr;
1059 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1060 encode_readdirplus3args(&xdr, args);
1061 prepare_reply_buffer(req, args->pages, 0,
1062 args->count, NFS3_readdirres_sz);
1067 * Decode the result of a readdir call.
1068 * We just check for syntactical correctness.
1071 nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res)
1073 struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
1074 struct kvec *iov = rcvbuf->head;
1080 status = ntohl(*p++);
1081 /* Decode post_op_attrs */
1082 p = xdr_decode_post_op_attr(p, res->dir_attr);
1084 return nfs_stat_to_errno(status);
1085 /* Decode verifier cookie */
1087 res->verf[0] = *p++;
1088 res->verf[1] = *p++;
1093 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
1094 if (iov->iov_len < hdrlen) {
1095 dprintk("NFS: READDIR reply header overflowed:"
1096 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1097 return -errno_NFSERR_IO;
1098 } else if (iov->iov_len != hdrlen) {
1099 dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
1100 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
1103 pglen = rcvbuf->page_len;
1104 recvd = rcvbuf->len - hdrlen;
1107 page = rcvbuf->pages;
1113 nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_server *server, int plus)
1116 struct nfs_entry old = *entry;
1118 p = xdr_inline_decode(xdr, 4);
1122 p = xdr_inline_decode(xdr, 4);
1126 return ERR_PTR(-EAGAIN);
1128 return ERR_PTR(-EBADCOOKIE);
1131 p = xdr_inline_decode(xdr, 12);
1134 p = xdr_decode_hyper(p, &entry->ino);
1135 entry->len = ntohl(*p++);
1137 p = xdr_inline_decode(xdr, entry->len + 8);
1140 entry->name = (const char *) p;
1141 p += XDR_QUADLEN(entry->len);
1142 entry->prev_cookie = entry->cookie;
1143 p = xdr_decode_hyper(p, &entry->cookie);
1145 entry->d_type = DT_UNKNOWN;
1147 entry->fattr->valid = 0;
1148 p = xdr_decode_post_op_attr_stream(xdr, entry->fattr);
1150 goto out_overflow_exit;
1151 entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
1152 /* In fact, a post_op_fh3: */
1153 p = xdr_inline_decode(xdr, 4);
1157 p = xdr_decode_fhandle_stream(xdr, entry->fh);
1159 goto out_overflow_exit;
1160 /* Ugh -- server reply was truncated */
1162 dprintk("NFS: FH truncated\n");
1164 return ERR_PTR(-EAGAIN);
1167 memset((u8*)(entry->fh), 0, sizeof(*entry->fh));
1170 p = xdr_inline_peek(xdr, 8);
1172 entry->eof = !p[0] && p[1];
1179 print_overflow_msg(__func__, xdr);
1181 return ERR_PTR(-EAGAIN);
1185 * 3.3.21 COMMIT3args
1187 * struct COMMIT3args {
1193 static void encode_commit3args(struct xdr_stream *xdr,
1194 const struct nfs_writeargs *args)
1198 encode_nfs_fh3(xdr, args->fh);
1200 p = xdr_reserve_space(xdr, 8 + 4);
1201 p = xdr_encode_hyper(p, args->offset);
1202 *p = cpu_to_be32(args->count);
1205 static int nfs3_xdr_enc_commit3args(struct rpc_rqst *req, __be32 *p,
1206 const struct nfs_writeargs *args)
1208 struct xdr_stream xdr;
1210 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1211 encode_commit3args(&xdr, args);
1215 #ifdef CONFIG_NFS_V3_ACL
1217 static int nfs3_xdr_enc_getacl3args(struct rpc_rqst *req, __be32 *p,
1218 const struct nfs3_getaclargs *args)
1220 struct xdr_stream xdr;
1222 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1223 encode_nfs_fh3(&xdr, args->fh);
1224 encode_uint32(&xdr, args->mask);
1225 if (args->mask & (NFS_ACL | NFS_DFACL))
1226 prepare_reply_buffer(req, args->pages, 0,
1227 NFSACL_MAXPAGES << PAGE_SHIFT,
1232 static int nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, __be32 *p,
1233 const struct nfs3_setaclargs *args)
1235 struct xdr_stream xdr;
1239 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1240 encode_nfs_fh3(&xdr, NFS_FH(args->inode));
1241 encode_uint32(&xdr, args->mask);
1242 if (args->npages != 0)
1243 xdr_write_pages(&xdr, args->pages, 0, args->len);
1245 base = req->rq_slen;
1246 error = nfsacl_encode(xdr.buf, base, args->inode,
1247 (args->mask & NFS_ACL) ?
1248 args->acl_access : NULL, 1, 0);
1250 error = nfsacl_encode(xdr.buf, base + error, args->inode,
1251 (args->mask & NFS_DFACL) ?
1252 args->acl_default : NULL, 1,
1258 #endif /* CONFIG_NFS_V3_ACL */
1261 * NFS XDR decode functions
1265 * Decode attrstat reply.
1268 nfs3_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1272 if ((status = ntohl(*p++)))
1273 return nfs_stat_to_errno(status);
1274 xdr_decode_fattr(p, fattr);
1279 * Decode status+wcc_data reply
1280 * SATTR, REMOVE, RMDIR
1283 nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1287 if ((status = ntohl(*p++)))
1288 status = nfs_stat_to_errno(status);
1289 xdr_decode_wcc_data(p, fattr);
1294 nfs3_xdr_removeres(struct rpc_rqst *req, __be32 *p, struct nfs_removeres *res)
1296 return nfs3_xdr_wccstat(req, p, res->dir_attr);
1300 * Decode LOOKUP reply
1303 nfs3_xdr_lookupres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
1307 if ((status = ntohl(*p++))) {
1308 status = nfs_stat_to_errno(status);
1310 if (!(p = xdr_decode_fhandle(p, res->fh)))
1311 return -errno_NFSERR_IO;
1312 p = xdr_decode_post_op_attr(p, res->fattr);
1314 xdr_decode_post_op_attr(p, res->dir_attr);
1319 * Decode ACCESS reply
1322 nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res)
1324 int status = ntohl(*p++);
1326 p = xdr_decode_post_op_attr(p, res->fattr);
1328 return nfs_stat_to_errno(status);
1329 res->access = ntohl(*p++);
1334 * Decode READLINK reply
1337 nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1339 struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
1340 struct kvec *iov = rcvbuf->head;
1345 status = ntohl(*p++);
1346 p = xdr_decode_post_op_attr(p, fattr);
1349 return nfs_stat_to_errno(status);
1351 /* Convert length of symlink */
1353 if (len >= rcvbuf->page_len) {
1354 dprintk("nfs: server returned giant symlink!\n");
1355 return -ENAMETOOLONG;
1358 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
1359 if (iov->iov_len < hdrlen) {
1360 dprintk("NFS: READLINK reply header overflowed:"
1361 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1362 return -errno_NFSERR_IO;
1363 } else if (iov->iov_len != hdrlen) {
1364 dprintk("NFS: READLINK header is short. "
1365 "iovec will be shifted.\n");
1366 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
1368 recvd = req->rq_rcv_buf.len - hdrlen;
1370 dprintk("NFS: server cheating in readlink reply: "
1371 "count %u > recvd %u\n", len, recvd);
1375 xdr_terminate_string(rcvbuf, len);
1383 nfs3_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
1385 struct kvec *iov = req->rq_rcv_buf.head;
1387 u32 count, ocount, recvd;
1390 status = ntohl(*p++);
1391 p = xdr_decode_post_op_attr(p, res->fattr);
1394 return nfs_stat_to_errno(status);
1396 /* Decode reply count and EOF flag. NFSv3 is somewhat redundant
1397 * in that it puts the count both in the res struct and in the
1398 * opaque data count. */
1399 count = ntohl(*p++);
1400 res->eof = ntohl(*p++);
1401 ocount = ntohl(*p++);
1403 if (ocount != count) {
1404 dprintk("NFS: READ count doesn't match RPC opaque count.\n");
1405 return -errno_NFSERR_IO;
1408 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
1409 if (iov->iov_len < hdrlen) {
1410 dprintk("NFS: READ reply header overflowed:"
1411 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1412 return -errno_NFSERR_IO;
1413 } else if (iov->iov_len != hdrlen) {
1414 dprintk("NFS: READ header is short. iovec will be shifted.\n");
1415 xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
1418 recvd = req->rq_rcv_buf.len - hdrlen;
1419 if (count > recvd) {
1420 dprintk("NFS: server cheating in read reply: "
1421 "count %u > recvd %u\n", count, recvd);
1426 if (count < res->count)
1433 * Decode WRITE response
1436 nfs3_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
1440 status = ntohl(*p++);
1441 p = xdr_decode_wcc_data(p, res->fattr);
1444 return nfs_stat_to_errno(status);
1446 res->count = ntohl(*p++);
1447 res->verf->committed = (enum nfs3_stable_how)ntohl(*p++);
1448 res->verf->verifier[0] = *p++;
1449 res->verf->verifier[1] = *p++;
1455 * Decode a CREATE response
1458 nfs3_xdr_createres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
1462 status = ntohl(*p++);
1465 if (!(p = xdr_decode_fhandle(p, res->fh)))
1466 return -errno_NFSERR_IO;
1467 p = xdr_decode_post_op_attr(p, res->fattr);
1469 memset(res->fh, 0, sizeof(*res->fh));
1470 /* Do decode post_op_attr but set it to NULL */
1471 p = xdr_decode_post_op_attr(p, res->fattr);
1472 res->fattr->valid = 0;
1475 status = nfs_stat_to_errno(status);
1477 p = xdr_decode_wcc_data(p, res->dir_attr);
1482 * Decode RENAME reply
1485 nfs3_xdr_renameres(struct rpc_rqst *req, __be32 *p, struct nfs_renameres *res)
1489 if ((status = ntohl(*p++)) != 0)
1490 status = nfs_stat_to_errno(status);
1491 p = xdr_decode_wcc_data(p, res->old_fattr);
1492 p = xdr_decode_wcc_data(p, res->new_fattr);
1500 nfs3_xdr_linkres(struct rpc_rqst *req, __be32 *p, struct nfs3_linkres *res)
1504 if ((status = ntohl(*p++)) != 0)
1505 status = nfs_stat_to_errno(status);
1506 p = xdr_decode_post_op_attr(p, res->fattr);
1507 p = xdr_decode_wcc_data(p, res->dir_attr);
1512 * Decode FSSTAT reply
1515 nfs3_xdr_fsstatres(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *res)
1519 status = ntohl(*p++);
1521 p = xdr_decode_post_op_attr(p, res->fattr);
1523 return nfs_stat_to_errno(status);
1525 p = xdr_decode_hyper(p, &res->tbytes);
1526 p = xdr_decode_hyper(p, &res->fbytes);
1527 p = xdr_decode_hyper(p, &res->abytes);
1528 p = xdr_decode_hyper(p, &res->tfiles);
1529 p = xdr_decode_hyper(p, &res->ffiles);
1530 p = xdr_decode_hyper(p, &res->afiles);
1532 /* ignore invarsec */
1537 * Decode FSINFO reply
1540 nfs3_xdr_fsinfores(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *res)
1544 status = ntohl(*p++);
1546 p = xdr_decode_post_op_attr(p, res->fattr);
1548 return nfs_stat_to_errno(status);
1550 res->rtmax = ntohl(*p++);
1551 res->rtpref = ntohl(*p++);
1552 res->rtmult = ntohl(*p++);
1553 res->wtmax = ntohl(*p++);
1554 res->wtpref = ntohl(*p++);
1555 res->wtmult = ntohl(*p++);
1556 res->dtpref = ntohl(*p++);
1557 p = xdr_decode_hyper(p, &res->maxfilesize);
1558 p = xdr_decode_time3(p, &res->time_delta);
1560 /* ignore properties */
1561 res->lease_time = 0;
1566 * Decode PATHCONF reply
1569 nfs3_xdr_pathconfres(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *res)
1573 status = ntohl(*p++);
1575 p = xdr_decode_post_op_attr(p, res->fattr);
1577 return nfs_stat_to_errno(status);
1578 res->max_link = ntohl(*p++);
1579 res->max_namelen = ntohl(*p++);
1581 /* ignore remaining fields */
1586 * Decode COMMIT reply
1589 nfs3_xdr_commitres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
1593 status = ntohl(*p++);
1594 p = xdr_decode_wcc_data(p, res->fattr);
1596 return nfs_stat_to_errno(status);
1598 res->verf->verifier[0] = *p++;
1599 res->verf->verifier[1] = *p++;
1603 #ifdef CONFIG_NFS_V3_ACL
1605 * Decode GETACL reply
1608 nfs3_xdr_getaclres(struct rpc_rqst *req, __be32 *p,
1609 struct nfs3_getaclres *res)
1611 struct xdr_buf *buf = &req->rq_rcv_buf;
1612 int status = ntohl(*p++);
1613 struct posix_acl **acl;
1614 unsigned int *aclcnt;
1618 return nfs_stat_to_errno(status);
1619 p = xdr_decode_post_op_attr(p, res->fattr);
1620 res->mask = ntohl(*p++);
1621 if (res->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
1623 base = (char *)p - (char *)req->rq_rcv_buf.head->iov_base;
1625 acl = (res->mask & NFS_ACL) ? &res->acl_access : NULL;
1626 aclcnt = (res->mask & NFS_ACLCNT) ? &res->acl_access_count : NULL;
1627 err = nfsacl_decode(buf, base, aclcnt, acl);
1629 acl = (res->mask & NFS_DFACL) ? &res->acl_default : NULL;
1630 aclcnt = (res->mask & NFS_DFACLCNT) ? &res->acl_default_count : NULL;
1632 err = nfsacl_decode(buf, base + err, aclcnt, acl);
1633 return (err > 0) ? 0 : err;
1637 * Decode setacl reply.
1640 nfs3_xdr_setaclres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1642 int status = ntohl(*p++);
1645 return nfs_stat_to_errno(status);
1646 xdr_decode_post_op_attr(p, fattr);
1649 #endif /* CONFIG_NFS_V3_ACL */
1651 #define PROC(proc, argtype, restype, timer) \
1652 [NFS3PROC_##proc] = { \
1653 .p_proc = NFS3PROC_##proc, \
1654 .p_encode = (kxdrproc_t)nfs3_xdr_enc_##argtype##3args, \
1655 .p_decode = (kxdrproc_t) nfs3_xdr_##restype, \
1656 .p_arglen = NFS3_##argtype##args_sz, \
1657 .p_replen = NFS3_##restype##_sz, \
1659 .p_statidx = NFS3PROC_##proc, \
1663 struct rpc_procinfo nfs3_procedures[] = {
1664 PROC(GETATTR, getattr, attrstat, 1),
1665 PROC(SETATTR, setattr, wccstat, 0),
1666 PROC(LOOKUP, lookup, lookupres, 2),
1667 PROC(ACCESS, access, accessres, 1),
1668 PROC(READLINK, readlink, readlinkres, 3),
1669 PROC(READ, read, readres, 3),
1670 PROC(WRITE, write, writeres, 4),
1671 PROC(CREATE, create, createres, 0),
1672 PROC(MKDIR, mkdir, createres, 0),
1673 PROC(SYMLINK, symlink, createres, 0),
1674 PROC(MKNOD, mknod, createres, 0),
1675 PROC(REMOVE, remove, removeres, 0),
1676 PROC(RMDIR, lookup, wccstat, 0),
1677 PROC(RENAME, rename, renameres, 0),
1678 PROC(LINK, link, linkres, 0),
1679 PROC(READDIR, readdir, readdirres, 3),
1680 PROC(READDIRPLUS, readdirplus, readdirres, 3),
1681 PROC(FSSTAT, getattr, fsstatres, 0),
1682 PROC(FSINFO, getattr, fsinfores, 0),
1683 PROC(PATHCONF, getattr, pathconfres, 0),
1684 PROC(COMMIT, commit, commitres, 5),
1687 struct rpc_version nfs_version3 = {
1689 .nrprocs = ARRAY_SIZE(nfs3_procedures),
1690 .procs = nfs3_procedures
1693 #ifdef CONFIG_NFS_V3_ACL
1694 static struct rpc_procinfo nfs3_acl_procedures[] = {
1695 [ACLPROC3_GETACL] = {
1696 .p_proc = ACLPROC3_GETACL,
1697 .p_encode = (kxdrproc_t)nfs3_xdr_enc_getacl3args,
1698 .p_decode = (kxdrproc_t) nfs3_xdr_getaclres,
1699 .p_arglen = ACL3_getaclargs_sz,
1700 .p_replen = ACL3_getaclres_sz,
1704 [ACLPROC3_SETACL] = {
1705 .p_proc = ACLPROC3_SETACL,
1706 .p_encode = (kxdrproc_t)nfs3_xdr_enc_setacl3args,
1707 .p_decode = (kxdrproc_t) nfs3_xdr_setaclres,
1708 .p_arglen = ACL3_setaclargs_sz,
1709 .p_replen = ACL3_setaclres_sz,
1715 struct rpc_version nfsacl_version3 = {
1717 .nrprocs = sizeof(nfs3_acl_procedures)/
1718 sizeof(nfs3_acl_procedures[0]),
1719 .procs = nfs3_acl_procedures,
1721 #endif /* CONFIG_NFS_V3_ACL */