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