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 */