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 * Encode/decode NFSv3 basic data types
132 * Basic NFSv3 data types are defined in section 2.5 of RFC 1813:
133 * "NFS Version 3 Protocol Specification".
135 * Not all basic data types have their own encoding and decoding
136 * functions. For run-time efficiency, some data types are encoded
140 static void encode_uint32(struct xdr_stream
*xdr
, u32 value
)
142 __be32
*p
= xdr_reserve_space(xdr
, 4);
143 *p
= cpu_to_be32(value
);
146 static int decode_uint32(struct xdr_stream
*xdr
, u32
*value
)
150 p
= xdr_inline_decode(xdr
, 4);
151 if (unlikely(p
== NULL
))
153 *value
= be32_to_cpup(p
);
156 print_overflow_msg(__func__
, xdr
);
160 static int decode_uint64(struct xdr_stream
*xdr
, u64
*value
)
164 p
= xdr_inline_decode(xdr
, 8);
165 if (unlikely(p
== NULL
))
167 xdr_decode_hyper(p
, value
);
170 print_overflow_msg(__func__
, xdr
);
177 * typedef uint64 fileid3;
179 static __be32
*xdr_decode_fileid3(__be32
*p
, u64
*fileid
)
181 return xdr_decode_hyper(p
, fileid
);
184 static int decode_fileid3(struct xdr_stream
*xdr
, u64
*fileid
)
186 return decode_uint64(xdr
, fileid
);
192 * typedef string filename3<>;
194 static void encode_filename3(struct xdr_stream
*xdr
,
195 const char *name
, u32 length
)
199 BUG_ON(length
> NFS3_MAXNAMLEN
);
200 p
= xdr_reserve_space(xdr
, 4 + length
);
201 xdr_encode_opaque(p
, name
, length
);
204 static int decode_inline_filename3(struct xdr_stream
*xdr
,
205 const char **name
, u32
*length
)
210 p
= xdr_inline_decode(xdr
, 4);
211 if (unlikely(p
== NULL
))
213 count
= be32_to_cpup(p
);
214 if (count
> NFS3_MAXNAMLEN
)
215 goto out_nametoolong
;
216 p
= xdr_inline_decode(xdr
, count
);
217 if (unlikely(p
== NULL
))
219 *name
= (const char *)p
;
224 dprintk("NFS: returned filename too long: %u\n", count
);
225 return -ENAMETOOLONG
;
227 print_overflow_msg(__func__
, xdr
);
234 * typedef string nfspath3<>;
236 static void encode_nfspath3(struct xdr_stream
*xdr
, struct page
**pages
,
239 BUG_ON(length
> NFS3_MAXPATHLEN
);
240 encode_uint32(xdr
, length
);
241 xdr_write_pages(xdr
, pages
, 0, length
);
244 static int decode_nfspath3(struct xdr_stream
*xdr
)
250 p
= xdr_inline_decode(xdr
, 4);
251 if (unlikely(p
== NULL
))
253 count
= be32_to_cpup(p
);
254 if (unlikely(count
>= xdr
->buf
->page_len
|| count
> NFS3_MAXPATHLEN
))
255 goto out_nametoolong
;
256 hdrlen
= (u8
*)xdr
->p
- (u8
*)xdr
->iov
->iov_base
;
257 recvd
= xdr
->buf
->len
- hdrlen
;
258 if (unlikely(count
> recvd
))
261 xdr_read_pages(xdr
, count
);
262 xdr_terminate_string(xdr
->buf
, count
);
266 dprintk("NFS: returned pathname too long: %u\n", count
);
267 return -ENAMETOOLONG
;
269 dprintk("NFS: server cheating in pathname result: "
270 "count %u > recvd %u\n", count
, recvd
);
273 print_overflow_msg(__func__
, xdr
);
280 * typedef uint64 cookie3
282 static __be32
*xdr_encode_cookie3(__be32
*p
, u64 cookie
)
284 return xdr_encode_hyper(p
, cookie
);
287 static int decode_cookie3(struct xdr_stream
*xdr
, u64
*cookie
)
289 return decode_uint64(xdr
, cookie
);
295 * typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
297 static __be32
*xdr_encode_cookieverf3(__be32
*p
, const __be32
*verifier
)
299 memcpy(p
, verifier
, NFS3_COOKIEVERFSIZE
);
300 return p
+ XDR_QUADLEN(NFS3_COOKIEVERFSIZE
);
303 static int decode_cookieverf3(struct xdr_stream
*xdr
, __be32
*verifier
)
307 p
= xdr_inline_decode(xdr
, NFS3_COOKIEVERFSIZE
);
308 if (unlikely(p
== NULL
))
310 memcpy(verifier
, p
, NFS3_COOKIEVERFSIZE
);
313 print_overflow_msg(__func__
, xdr
);
320 * typedef opaque createverf3[NFS3_CREATEVERFSIZE];
322 static void encode_createverf3(struct xdr_stream
*xdr
, const __be32
*verifier
)
326 p
= xdr_reserve_space(xdr
, NFS3_CREATEVERFSIZE
);
327 memcpy(p
, verifier
, NFS3_CREATEVERFSIZE
);
330 static int decode_writeverf3(struct xdr_stream
*xdr
, __be32
*verifier
)
334 p
= xdr_inline_decode(xdr
, NFS3_WRITEVERFSIZE
);
335 if (unlikely(p
== NULL
))
337 memcpy(verifier
, p
, NFS3_WRITEVERFSIZE
);
340 print_overflow_msg(__func__
, xdr
);
347 * typedef uint64 size3;
349 static __be32
*xdr_decode_size3(__be32
*p
, u64
*size
)
351 return xdr_decode_hyper(p
, size
);
362 #define NFS3_OK NFS_OK
364 static int decode_nfsstat3(struct xdr_stream
*xdr
, enum nfs_stat
*status
)
368 p
= xdr_inline_decode(xdr
, 4);
369 if (unlikely(p
== NULL
))
371 *status
= be32_to_cpup(p
);
374 print_overflow_msg(__func__
, xdr
);
391 static void encode_ftype3(struct xdr_stream
*xdr
, const u32 type
)
393 BUG_ON(type
> NF3FIFO
);
394 encode_uint32(xdr
, type
);
397 static __be32
*xdr_decode_ftype3(__be32
*p
, umode_t
*mode
)
401 type
= be32_to_cpup(p
++);
404 *mode
= nfs_type2fmt
[type
];
416 static void encode_specdata3(struct xdr_stream
*xdr
, const dev_t rdev
)
420 p
= xdr_reserve_space(xdr
, 8);
421 *p
++ = cpu_to_be32(MAJOR(rdev
));
422 *p
= cpu_to_be32(MINOR(rdev
));
425 static __be32
*xdr_decode_specdata3(__be32
*p
, dev_t
*rdev
)
427 unsigned int major
, minor
;
429 major
= be32_to_cpup(p
++);
430 minor
= be32_to_cpup(p
++);
431 *rdev
= MKDEV(major
, minor
);
432 if (MAJOR(*rdev
) != major
|| MINOR(*rdev
) != minor
)
441 * opaque data<NFS3_FHSIZE>;
444 static void encode_nfs_fh3(struct xdr_stream
*xdr
, const struct nfs_fh
*fh
)
448 BUG_ON(fh
->size
> NFS3_FHSIZE
);
449 p
= xdr_reserve_space(xdr
, 4 + fh
->size
);
450 xdr_encode_opaque(p
, fh
->data
, fh
->size
);
453 static int decode_nfs_fh3(struct xdr_stream
*xdr
, struct nfs_fh
*fh
)
458 p
= xdr_inline_decode(xdr
, 4);
459 if (unlikely(p
== NULL
))
461 length
= be32_to_cpup(p
++);
462 if (unlikely(length
> NFS3_FHSIZE
))
464 p
= xdr_inline_decode(xdr
, length
);
465 if (unlikely(p
== NULL
))
468 memcpy(fh
->data
, p
, length
);
471 dprintk("NFS: file handle size (%u) too big\n", length
);
474 print_overflow_msg(__func__
, xdr
);
478 static void zero_nfs_fh3(struct nfs_fh
*fh
)
480 memset(fh
, 0, sizeof(*fh
));
491 static __be32
*xdr_encode_nfstime3(__be32
*p
, const struct timespec
*timep
)
493 *p
++ = cpu_to_be32(timep
->tv_sec
);
494 *p
++ = cpu_to_be32(timep
->tv_nsec
);
498 static __be32
*xdr_decode_nfstime3(__be32
*p
, struct timespec
*timep
)
500 timep
->tv_sec
= be32_to_cpup(p
++);
501 timep
->tv_nsec
= be32_to_cpup(p
++);
510 * SET_TO_SERVER_TIME = 1,
511 * SET_TO_CLIENT_TIME = 2
514 * union set_mode3 switch (bool set_it) {
521 * union set_uid3 switch (bool set_it) {
528 * union set_gid3 switch (bool set_it) {
535 * union set_size3 switch (bool set_it) {
542 * union set_atime switch (time_how set_it) {
543 * case SET_TO_CLIENT_TIME:
549 * union set_mtime switch (time_how set_it) {
550 * case SET_TO_CLIENT_TIME:
565 static void encode_sattr3(struct xdr_stream
*xdr
, const struct iattr
*attr
)
571 * In order to make only a single xdr_reserve_space() call,
572 * pre-compute the total number of bytes to be reserved.
573 * Six boolean values, one for each set_foo field, are always
574 * present in the encoded result, so start there.
577 if (attr
->ia_valid
& ATTR_MODE
)
579 if (attr
->ia_valid
& ATTR_UID
)
581 if (attr
->ia_valid
& ATTR_GID
)
583 if (attr
->ia_valid
& ATTR_SIZE
)
585 if (attr
->ia_valid
& ATTR_ATIME_SET
)
587 if (attr
->ia_valid
& ATTR_MTIME_SET
)
589 p
= xdr_reserve_space(xdr
, nbytes
);
591 if (attr
->ia_valid
& ATTR_MODE
) {
593 *p
++ = cpu_to_be32(attr
->ia_mode
& S_IALLUGO
);
597 if (attr
->ia_valid
& ATTR_UID
) {
599 *p
++ = cpu_to_be32(attr
->ia_uid
);
603 if (attr
->ia_valid
& ATTR_GID
) {
605 *p
++ = cpu_to_be32(attr
->ia_gid
);
609 if (attr
->ia_valid
& ATTR_SIZE
) {
611 p
= xdr_encode_hyper(p
, (u64
)attr
->ia_size
);
615 if (attr
->ia_valid
& ATTR_ATIME_SET
) {
617 p
= xdr_encode_nfstime3(p
, &attr
->ia_atime
);
618 } else if (attr
->ia_valid
& ATTR_ATIME
) {
623 if (attr
->ia_valid
& ATTR_MTIME_SET
) {
625 xdr_encode_nfstime3(p
, &attr
->ia_mtime
);
626 } else if (attr
->ia_valid
& ATTR_MTIME
) {
651 static int decode_fattr3(struct xdr_stream
*xdr
, struct nfs_fattr
*fattr
)
656 p
= xdr_inline_decode(xdr
, NFS3_fattr_sz
<< 2);
657 if (unlikely(p
== NULL
))
660 p
= xdr_decode_ftype3(p
, &fmode
);
662 fattr
->mode
= (be32_to_cpup(p
++) & ~S_IFMT
) | fmode
;
663 fattr
->nlink
= be32_to_cpup(p
++);
664 fattr
->uid
= be32_to_cpup(p
++);
665 fattr
->gid
= be32_to_cpup(p
++);
667 p
= xdr_decode_size3(p
, &fattr
->size
);
668 p
= xdr_decode_size3(p
, &fattr
->du
.nfs3
.used
);
669 p
= xdr_decode_specdata3(p
, &fattr
->rdev
);
671 p
= xdr_decode_hyper(p
, &fattr
->fsid
.major
);
672 fattr
->fsid
.minor
= 0;
674 p
= xdr_decode_fileid3(p
, &fattr
->fileid
);
675 p
= xdr_decode_nfstime3(p
, &fattr
->atime
);
676 p
= xdr_decode_nfstime3(p
, &fattr
->mtime
);
677 xdr_decode_nfstime3(p
, &fattr
->ctime
);
679 fattr
->valid
|= NFS_ATTR_FATTR_V3
;
682 print_overflow_msg(__func__
, xdr
);
689 * union post_op_attr switch (bool attributes_follow) {
696 static int decode_post_op_attr(struct xdr_stream
*xdr
, struct nfs_fattr
*fattr
)
700 p
= xdr_inline_decode(xdr
, 4);
701 if (unlikely(p
== NULL
))
704 return decode_fattr3(xdr
, fattr
);
707 print_overflow_msg(__func__
, xdr
);
719 static int decode_wcc_attr(struct xdr_stream
*xdr
, struct nfs_fattr
*fattr
)
723 p
= xdr_inline_decode(xdr
, NFS3_wcc_attr_sz
<< 2);
724 if (unlikely(p
== NULL
))
727 fattr
->valid
|= NFS_ATTR_FATTR_PRESIZE
728 | NFS_ATTR_FATTR_PREMTIME
729 | NFS_ATTR_FATTR_PRECTIME
;
731 p
= xdr_decode_size3(p
, &fattr
->pre_size
);
732 p
= xdr_decode_nfstime3(p
, &fattr
->pre_mtime
);
733 xdr_decode_nfstime3(p
, &fattr
->pre_ctime
);
737 print_overflow_msg(__func__
, xdr
);
743 * union pre_op_attr switch (bool attributes_follow) {
745 * wcc_attr attributes;
753 * pre_op_attr before;
754 * post_op_attr after;
757 static int decode_pre_op_attr(struct xdr_stream
*xdr
, struct nfs_fattr
*fattr
)
761 p
= xdr_inline_decode(xdr
, 4);
762 if (unlikely(p
== NULL
))
765 return decode_wcc_attr(xdr
, fattr
);
768 print_overflow_msg(__func__
, xdr
);
772 static int decode_wcc_data(struct xdr_stream
*xdr
, struct nfs_fattr
*fattr
)
776 error
= decode_pre_op_attr(xdr
, fattr
);
779 error
= decode_post_op_attr(xdr
, fattr
);
787 * union post_op_fh3 switch (bool handle_follows) {
794 static int decode_post_op_fh3(struct xdr_stream
*xdr
, struct nfs_fh
*fh
)
796 __be32
*p
= xdr_inline_decode(xdr
, 4);
797 if (unlikely(p
== NULL
))
800 return decode_nfs_fh3(xdr
, fh
);
804 print_overflow_msg(__func__
, xdr
);
811 * struct diropargs3 {
816 static void encode_diropargs3(struct xdr_stream
*xdr
, const struct nfs_fh
*fh
,
817 const char *name
, u32 length
)
819 encode_nfs_fh3(xdr
, fh
);
820 encode_filename3(xdr
, name
, length
);
825 * NFSv3 XDR encode functions
827 * NFSv3 argument types are defined in section 3.3 of RFC 1813:
828 * "NFS Version 3 Protocol Specification".
834 * struct GETATTR3args {
838 static int nfs3_xdr_enc_getattr3args(struct rpc_rqst
*req
, __be32
*p
,
839 const struct nfs_fh
*fh
)
841 struct xdr_stream xdr
;
843 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
844 encode_nfs_fh3(&xdr
, fh
);
851 * union sattrguard3 switch (bool check) {
853 * nfstime3 obj_ctime;
858 * struct SETATTR3args {
860 * sattr3 new_attributes;
864 static void encode_sattrguard3(struct xdr_stream
*xdr
,
865 const struct nfs3_sattrargs
*args
)
870 p
= xdr_reserve_space(xdr
, 4 + 8);
872 xdr_encode_nfstime3(p
, &args
->guardtime
);
874 p
= xdr_reserve_space(xdr
, 4);
879 static int nfs3_xdr_enc_setattr3args(struct rpc_rqst
*req
, __be32
*p
,
880 const struct nfs3_sattrargs
*args
)
882 struct xdr_stream xdr
;
884 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
885 encode_nfs_fh3(&xdr
, args
->fh
);
886 encode_sattr3(&xdr
, args
->sattr
);
887 encode_sattrguard3(&xdr
, args
);
894 * struct LOOKUP3args {
898 static int nfs3_xdr_enc_lookup3args(struct rpc_rqst
*req
, __be32
*p
,
899 const struct nfs3_diropargs
*args
)
901 struct xdr_stream xdr
;
903 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
904 encode_diropargs3(&xdr
, args
->fh
, args
->name
, args
->len
);
911 * struct ACCESS3args {
916 static void encode_access3args(struct xdr_stream
*xdr
,
917 const struct nfs3_accessargs
*args
)
919 encode_nfs_fh3(xdr
, args
->fh
);
920 encode_uint32(xdr
, args
->access
);
923 static int nfs3_xdr_enc_access3args(struct rpc_rqst
*req
, __be32
*p
,
924 const struct nfs3_accessargs
*args
)
926 struct xdr_stream xdr
;
928 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
929 encode_access3args(&xdr
, args
);
934 * 3.3.5 READLINK3args
936 * struct READLINK3args {
940 static int nfs3_xdr_enc_readlink3args(struct rpc_rqst
*req
, __be32
*p
,
941 const struct nfs3_readlinkargs
*args
)
943 struct xdr_stream xdr
;
945 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
946 encode_nfs_fh3(&xdr
, args
->fh
);
947 prepare_reply_buffer(req
, args
->pages
, args
->pgbase
,
948 args
->pglen
, NFS3_readlinkres_sz
);
961 static void encode_read3args(struct xdr_stream
*xdr
,
962 const struct nfs_readargs
*args
)
966 encode_nfs_fh3(xdr
, args
->fh
);
968 p
= xdr_reserve_space(xdr
, 8 + 4);
969 p
= xdr_encode_hyper(p
, args
->offset
);
970 *p
= cpu_to_be32(args
->count
);
973 static int nfs3_xdr_enc_read3args(struct rpc_rqst
*req
, __be32
*p
,
974 const struct nfs_readargs
*args
)
976 struct xdr_stream xdr
;
978 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
979 encode_read3args(&xdr
, args
);
980 prepare_reply_buffer(req
, args
->pages
, args
->pgbase
,
981 args
->count
, NFS3_readres_sz
);
982 req
->rq_rcv_buf
.flags
|= XDRBUF_READ
;
995 * struct WRITE3args {
1003 static void encode_write3args(struct xdr_stream
*xdr
,
1004 const struct nfs_writeargs
*args
)
1008 encode_nfs_fh3(xdr
, args
->fh
);
1010 p
= xdr_reserve_space(xdr
, 8 + 4 + 4 + 4);
1011 p
= xdr_encode_hyper(p
, args
->offset
);
1012 *p
++ = cpu_to_be32(args
->count
);
1013 *p
++ = cpu_to_be32(args
->stable
);
1014 *p
= cpu_to_be32(args
->count
);
1015 xdr_write_pages(xdr
, args
->pages
, args
->pgbase
, args
->count
);
1018 static int nfs3_xdr_enc_write3args(struct rpc_rqst
*req
, __be32
*p
,
1019 const struct nfs_writeargs
*args
)
1021 struct xdr_stream xdr
;
1023 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
1024 encode_write3args(&xdr
, args
);
1025 xdr
.buf
->flags
|= XDRBUF_WRITE
;
1032 * enum createmode3 {
1038 * union createhow3 switch (createmode3 mode) {
1041 * sattr3 obj_attributes;
1046 * struct CREATE3args {
1051 static void encode_createhow3(struct xdr_stream
*xdr
,
1052 const struct nfs3_createargs
*args
)
1054 encode_uint32(xdr
, args
->createmode
);
1055 switch (args
->createmode
) {
1056 case NFS3_CREATE_UNCHECKED
:
1057 case NFS3_CREATE_GUARDED
:
1058 encode_sattr3(xdr
, args
->sattr
);
1060 case NFS3_CREATE_EXCLUSIVE
:
1061 encode_createverf3(xdr
, args
->verifier
);
1068 static int nfs3_xdr_enc_create3args(struct rpc_rqst
*req
, __be32
*p
,
1069 const struct nfs3_createargs
*args
)
1071 struct xdr_stream xdr
;
1073 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
1074 encode_diropargs3(&xdr
, args
->fh
, args
->name
, args
->len
);
1075 encode_createhow3(&xdr
, args
);
1082 * struct MKDIR3args {
1084 * sattr3 attributes;
1087 static int nfs3_xdr_enc_mkdir3args(struct rpc_rqst
*req
, __be32
*p
,
1088 const struct nfs3_mkdirargs
*args
)
1090 struct xdr_stream xdr
;
1092 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
1093 encode_diropargs3(&xdr
, args
->fh
, args
->name
, args
->len
);
1094 encode_sattr3(&xdr
, args
->sattr
);
1099 * 3.3.10 SYMLINK3args
1101 * struct symlinkdata3 {
1102 * sattr3 symlink_attributes;
1103 * nfspath3 symlink_data;
1106 * struct SYMLINK3args {
1108 * symlinkdata3 symlink;
1111 static void encode_symlinkdata3(struct xdr_stream
*xdr
,
1112 const struct nfs3_symlinkargs
*args
)
1114 encode_sattr3(xdr
, args
->sattr
);
1115 encode_nfspath3(xdr
, args
->pages
, args
->pathlen
);
1118 static int nfs3_xdr_enc_symlink3args(struct rpc_rqst
*req
, __be32
*p
,
1119 const struct nfs3_symlinkargs
*args
)
1121 struct xdr_stream xdr
;
1123 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
1124 encode_diropargs3(&xdr
, args
->fromfh
, args
->fromname
, args
->fromlen
);
1125 encode_symlinkdata3(&xdr
, args
);
1132 * struct devicedata3 {
1133 * sattr3 dev_attributes;
1137 * union mknoddata3 switch (ftype3 type) {
1140 * devicedata3 device;
1143 * sattr3 pipe_attributes;
1148 * struct MKNOD3args {
1153 static void encode_devicedata3(struct xdr_stream
*xdr
,
1154 const struct nfs3_mknodargs
*args
)
1156 encode_sattr3(xdr
, args
->sattr
);
1157 encode_specdata3(xdr
, args
->rdev
);
1160 static void encode_mknoddata3(struct xdr_stream
*xdr
,
1161 const struct nfs3_mknodargs
*args
)
1163 encode_ftype3(xdr
, args
->type
);
1164 switch (args
->type
) {
1167 encode_devicedata3(xdr
, args
);
1171 encode_sattr3(xdr
, args
->sattr
);
1181 static int nfs3_xdr_enc_mknod3args(struct rpc_rqst
*req
, __be32
*p
,
1182 const struct nfs3_mknodargs
*args
)
1184 struct xdr_stream xdr
;
1186 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
1187 encode_diropargs3(&xdr
, args
->fh
, args
->name
, args
->len
);
1188 encode_mknoddata3(&xdr
, args
);
1193 * 3.3.12 REMOVE3args
1195 * struct REMOVE3args {
1196 * diropargs3 object;
1199 static int nfs3_xdr_enc_remove3args(struct rpc_rqst
*req
, __be32
*p
,
1200 const struct nfs_removeargs
*args
)
1202 struct xdr_stream xdr
;
1204 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
1205 encode_diropargs3(&xdr
, args
->fh
, args
->name
.name
, args
->name
.len
);
1210 * 3.3.14 RENAME3args
1212 * struct RENAME3args {
1217 static int nfs3_xdr_enc_rename3args(struct rpc_rqst
*req
, __be32
*p
,
1218 const struct nfs_renameargs
*args
)
1220 const struct qstr
*old
= args
->old_name
;
1221 const struct qstr
*new = args
->new_name
;
1222 struct xdr_stream xdr
;
1224 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
1225 encode_diropargs3(&xdr
, args
->old_dir
, old
->name
, old
->len
);
1226 encode_diropargs3(&xdr
, args
->new_dir
, new->name
, new->len
);
1233 * struct LINK3args {
1238 static int nfs3_xdr_enc_link3args(struct rpc_rqst
*req
, __be32
*p
,
1239 const struct nfs3_linkargs
*args
)
1241 struct xdr_stream xdr
;
1243 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
1244 encode_nfs_fh3(&xdr
, args
->fromfh
);
1245 encode_diropargs3(&xdr
, args
->tofh
, args
->toname
, args
->tolen
);
1250 * 3.3.16 READDIR3args
1252 * struct READDIR3args {
1255 * cookieverf3 cookieverf;
1259 static void encode_readdir3args(struct xdr_stream
*xdr
,
1260 const struct nfs3_readdirargs
*args
)
1264 encode_nfs_fh3(xdr
, args
->fh
);
1266 p
= xdr_reserve_space(xdr
, 8 + NFS3_COOKIEVERFSIZE
+ 4);
1267 p
= xdr_encode_cookie3(p
, args
->cookie
);
1268 p
= xdr_encode_cookieverf3(p
, args
->verf
);
1269 *p
= cpu_to_be32(args
->count
);
1272 static int nfs3_xdr_enc_readdir3args(struct rpc_rqst
*req
, __be32
*p
,
1273 const struct nfs3_readdirargs
*args
)
1275 struct xdr_stream xdr
;
1277 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
1278 encode_readdir3args(&xdr
, args
);
1279 prepare_reply_buffer(req
, args
->pages
, 0,
1280 args
->count
, NFS3_readdirres_sz
);
1285 * 3.3.17 READDIRPLUS3args
1287 * struct READDIRPLUS3args {
1290 * cookieverf3 cookieverf;
1295 static void encode_readdirplus3args(struct xdr_stream
*xdr
,
1296 const struct nfs3_readdirargs
*args
)
1300 encode_nfs_fh3(xdr
, args
->fh
);
1302 p
= xdr_reserve_space(xdr
, 8 + NFS3_COOKIEVERFSIZE
+ 4 + 4);
1303 p
= xdr_encode_cookie3(p
, args
->cookie
);
1304 p
= xdr_encode_cookieverf3(p
, args
->verf
);
1307 * readdirplus: need dircount + buffer size.
1308 * We just make sure we make dircount big enough
1310 *p
++ = cpu_to_be32(args
->count
>> 3);
1312 *p
= cpu_to_be32(args
->count
);
1315 static int nfs3_xdr_enc_readdirplus3args(struct rpc_rqst
*req
, __be32
*p
,
1316 const struct nfs3_readdirargs
*args
)
1318 struct xdr_stream xdr
;
1320 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
1321 encode_readdirplus3args(&xdr
, args
);
1322 prepare_reply_buffer(req
, args
->pages
, 0,
1323 args
->count
, NFS3_readdirres_sz
);
1328 * 3.3.21 COMMIT3args
1330 * struct COMMIT3args {
1336 static void encode_commit3args(struct xdr_stream
*xdr
,
1337 const struct nfs_writeargs
*args
)
1341 encode_nfs_fh3(xdr
, args
->fh
);
1343 p
= xdr_reserve_space(xdr
, 8 + 4);
1344 p
= xdr_encode_hyper(p
, args
->offset
);
1345 *p
= cpu_to_be32(args
->count
);
1348 static int nfs3_xdr_enc_commit3args(struct rpc_rqst
*req
, __be32
*p
,
1349 const struct nfs_writeargs
*args
)
1351 struct xdr_stream xdr
;
1353 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
1354 encode_commit3args(&xdr
, args
);
1358 #ifdef CONFIG_NFS_V3_ACL
1360 static int nfs3_xdr_enc_getacl3args(struct rpc_rqst
*req
, __be32
*p
,
1361 const struct nfs3_getaclargs
*args
)
1363 struct xdr_stream xdr
;
1365 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
1366 encode_nfs_fh3(&xdr
, args
->fh
);
1367 encode_uint32(&xdr
, args
->mask
);
1368 if (args
->mask
& (NFS_ACL
| NFS_DFACL
))
1369 prepare_reply_buffer(req
, args
->pages
, 0,
1370 NFSACL_MAXPAGES
<< PAGE_SHIFT
,
1375 static int nfs3_xdr_enc_setacl3args(struct rpc_rqst
*req
, __be32
*p
,
1376 const struct nfs3_setaclargs
*args
)
1378 struct xdr_stream xdr
;
1382 xdr_init_encode(&xdr
, &req
->rq_snd_buf
, p
);
1383 encode_nfs_fh3(&xdr
, NFS_FH(args
->inode
));
1384 encode_uint32(&xdr
, args
->mask
);
1385 if (args
->npages
!= 0)
1386 xdr_write_pages(&xdr
, args
->pages
, 0, args
->len
);
1388 base
= req
->rq_slen
;
1389 error
= nfsacl_encode(xdr
.buf
, base
, args
->inode
,
1390 (args
->mask
& NFS_ACL
) ?
1391 args
->acl_access
: NULL
, 1, 0);
1393 error
= nfsacl_encode(xdr
.buf
, base
+ error
, args
->inode
,
1394 (args
->mask
& NFS_DFACL
) ?
1395 args
->acl_default
: NULL
, 1,
1401 #endif /* CONFIG_NFS_V3_ACL */
1404 * NFSv3 XDR decode functions
1406 * NFSv3 result types are defined in section 3.3 of RFC 1813:
1407 * "NFS Version 3 Protocol Specification".
1413 * struct GETATTR3resok {
1414 * fattr3 obj_attributes;
1417 * union GETATTR3res switch (nfsstat3 status) {
1419 * GETATTR3resok resok;
1424 static int nfs3_xdr_dec_getattr3res(struct rpc_rqst
*req
, __be32
*p
,
1425 struct nfs_fattr
*result
)
1427 struct xdr_stream xdr
;
1428 enum nfs_stat status
;
1431 xdr_init_decode(&xdr
, &req
->rq_rcv_buf
, p
);
1432 error
= decode_nfsstat3(&xdr
, &status
);
1433 if (unlikely(error
))
1435 if (status
!= NFS3_OK
)
1437 error
= decode_fattr3(&xdr
, result
);
1441 return nfs_stat_to_errno(status
);
1447 * struct SETATTR3resok {
1451 * struct SETATTR3resfail {
1455 * union SETATTR3res switch (nfsstat3 status) {
1457 * SETATTR3resok resok;
1459 * SETATTR3resfail resfail;
1462 static int nfs3_xdr_dec_setattr3res(struct rpc_rqst
*req
, __be32
*p
,
1463 struct nfs_fattr
*result
)
1465 struct xdr_stream xdr
;
1466 enum nfs_stat status
;
1469 xdr_init_decode(&xdr
, &req
->rq_rcv_buf
, p
);
1470 error
= decode_nfsstat3(&xdr
, &status
);
1471 if (unlikely(error
))
1473 error
= decode_wcc_data(&xdr
, result
);
1474 if (unlikely(error
))
1476 if (status
!= NFS3_OK
)
1481 return nfs_stat_to_errno(status
);
1487 * struct LOOKUP3resok {
1489 * post_op_attr obj_attributes;
1490 * post_op_attr dir_attributes;
1493 * struct LOOKUP3resfail {
1494 * post_op_attr dir_attributes;
1497 * union LOOKUP3res switch (nfsstat3 status) {
1499 * LOOKUP3resok resok;
1501 * LOOKUP3resfail resfail;
1504 static int nfs3_xdr_dec_lookup3res(struct rpc_rqst
*req
, __be32
*p
,
1505 struct nfs3_diropres
*result
)
1507 struct xdr_stream xdr
;
1508 enum nfs_stat status
;
1511 xdr_init_decode(&xdr
, &req
->rq_rcv_buf
, p
);
1512 error
= decode_nfsstat3(&xdr
, &status
);
1513 if (unlikely(error
))
1515 if (status
!= NFS3_OK
)
1517 error
= decode_nfs_fh3(&xdr
, result
->fh
);
1518 if (unlikely(error
))
1520 error
= decode_post_op_attr(&xdr
, result
->fattr
);
1521 if (unlikely(error
))
1523 error
= decode_post_op_attr(&xdr
, result
->dir_attr
);
1527 error
= decode_post_op_attr(&xdr
, result
->dir_attr
);
1528 if (unlikely(error
))
1530 return nfs_stat_to_errno(status
);
1536 * struct ACCESS3resok {
1537 * post_op_attr obj_attributes;
1541 * struct ACCESS3resfail {
1542 * post_op_attr obj_attributes;
1545 * union ACCESS3res switch (nfsstat3 status) {
1547 * ACCESS3resok resok;
1549 * ACCESS3resfail resfail;
1552 static int nfs3_xdr_dec_access3res(struct rpc_rqst
*req
, __be32
*p
,
1553 struct nfs3_accessres
*result
)
1555 struct xdr_stream xdr
;
1556 enum nfs_stat status
;
1559 xdr_init_decode(&xdr
, &req
->rq_rcv_buf
, p
);
1560 error
= decode_nfsstat3(&xdr
, &status
);
1561 if (unlikely(error
))
1563 error
= decode_post_op_attr(&xdr
, result
->fattr
);
1564 if (unlikely(error
))
1566 if (status
!= NFS3_OK
)
1568 error
= decode_uint32(&xdr
, &result
->access
);
1572 return nfs_stat_to_errno(status
);
1576 * 3.3.5 READLINK3res
1578 * struct READLINK3resok {
1579 * post_op_attr symlink_attributes;
1583 * struct READLINK3resfail {
1584 * post_op_attr symlink_attributes;
1587 * union READLINK3res switch (nfsstat3 status) {
1589 * READLINK3resok resok;
1591 * READLINK3resfail resfail;
1594 static int nfs3_xdr_dec_readlink3res(struct rpc_rqst
*req
, __be32
*p
,
1595 struct nfs_fattr
*result
)
1597 struct xdr_stream xdr
;
1598 enum nfs_stat status
;
1601 xdr_init_decode(&xdr
, &req
->rq_rcv_buf
, p
);
1602 error
= decode_nfsstat3(&xdr
, &status
);
1603 if (unlikely(error
))
1605 error
= decode_post_op_attr(&xdr
, result
);
1606 if (unlikely(error
))
1608 if (status
!= NFS3_OK
)
1610 error
= decode_nfspath3(&xdr
);
1614 return nfs_stat_to_errno(status
);
1620 * struct READ3resok {
1621 * post_op_attr file_attributes;
1627 * struct READ3resfail {
1628 * post_op_attr file_attributes;
1631 * union READ3res switch (nfsstat3 status) {
1635 * READ3resfail resfail;
1638 static int decode_read3resok(struct xdr_stream
*xdr
,
1639 struct nfs_readres
*result
)
1641 u32 eof
, count
, ocount
, recvd
;
1645 p
= xdr_inline_decode(xdr
, 4 + 4 + 4);
1646 if (unlikely(p
== NULL
))
1648 count
= be32_to_cpup(p
++);
1649 eof
= be32_to_cpup(p
++);
1650 ocount
= be32_to_cpup(p
++);
1651 if (unlikely(ocount
!= count
))
1653 hdrlen
= (u8
*)xdr
->p
- (u8
*)xdr
->iov
->iov_base
;
1654 recvd
= xdr
->buf
->len
- hdrlen
;
1655 if (unlikely(count
> recvd
))
1659 xdr_read_pages(xdr
, count
);
1661 result
->count
= count
;
1664 dprintk("NFS: READ count doesn't match length of opaque: "
1665 "count %u != ocount %u\n", count
, ocount
);
1668 dprintk("NFS: server cheating in read result: "
1669 "count %u > recvd %u\n", count
, recvd
);
1674 print_overflow_msg(__func__
, xdr
);
1678 static int nfs3_xdr_dec_read3res(struct rpc_rqst
*req
, __be32
*p
,
1679 struct nfs_readres
*result
)
1681 struct xdr_stream xdr
;
1682 enum nfs_stat status
;
1685 xdr_init_decode(&xdr
, &req
->rq_rcv_buf
, p
);
1686 error
= decode_nfsstat3(&xdr
, &status
);
1687 if (unlikely(error
))
1689 error
= decode_post_op_attr(&xdr
, result
->fattr
);
1690 if (unlikely(error
))
1692 if (status
!= NFS3_OK
)
1694 error
= decode_read3resok(&xdr
, result
);
1698 return nfs_stat_to_errno(status
);
1710 * struct WRITE3resok {
1711 * wcc_data file_wcc;
1713 * stable_how committed;
1717 * struct WRITE3resfail {
1718 * wcc_data file_wcc;
1721 * union WRITE3res switch (nfsstat3 status) {
1723 * WRITE3resok resok;
1725 * WRITE3resfail resfail;
1728 static int decode_write3resok(struct xdr_stream
*xdr
,
1729 struct nfs_writeres
*result
)
1733 p
= xdr_inline_decode(xdr
, 4 + 4 + NFS3_WRITEVERFSIZE
);
1734 if (unlikely(p
== NULL
))
1736 result
->count
= be32_to_cpup(p
++);
1737 result
->verf
->committed
= be32_to_cpup(p
++);
1738 if (unlikely(result
->verf
->committed
> NFS_FILE_SYNC
))
1740 memcpy(result
->verf
->verifier
, p
, NFS3_WRITEVERFSIZE
);
1741 return result
->count
;
1743 dprintk("NFS: bad stable_how value: %u\n", result
->verf
->committed
);
1746 print_overflow_msg(__func__
, xdr
);
1750 static int nfs3_xdr_dec_write3res(struct rpc_rqst
*req
, __be32
*p
,
1751 struct nfs_writeres
*result
)
1753 struct xdr_stream xdr
;
1754 enum nfs_stat status
;
1757 xdr_init_decode(&xdr
, &req
->rq_rcv_buf
, p
);
1758 error
= decode_nfsstat3(&xdr
, &status
);
1759 if (unlikely(error
))
1761 error
= decode_wcc_data(&xdr
, result
->fattr
);
1762 if (unlikely(error
))
1764 if (status
!= NFS3_OK
)
1766 error
= decode_write3resok(&xdr
, result
);
1770 return nfs_stat_to_errno(status
);
1776 * struct CREATE3resok {
1778 * post_op_attr obj_attributes;
1782 * struct CREATE3resfail {
1786 * union CREATE3res switch (nfsstat3 status) {
1788 * CREATE3resok resok;
1790 * CREATE3resfail resfail;
1793 static int decode_create3resok(struct xdr_stream
*xdr
,
1794 struct nfs3_diropres
*result
)
1798 error
= decode_post_op_fh3(xdr
, result
->fh
);
1799 if (unlikely(error
))
1801 error
= decode_post_op_attr(xdr
, result
->fattr
);
1802 if (unlikely(error
))
1804 /* The server isn't required to return a file handle.
1805 * If it didn't, force the client to perform a LOOKUP
1806 * to determine the correct file handle and attribute
1807 * values for the new object. */
1808 if (result
->fh
->size
== 0)
1809 result
->fattr
->valid
= 0;
1810 error
= decode_wcc_data(xdr
, result
->dir_attr
);
1815 static int nfs3_xdr_dec_create3res(struct rpc_rqst
*req
, __be32
*p
,
1816 struct nfs3_diropres
*result
)
1818 struct xdr_stream xdr
;
1819 enum nfs_stat status
;
1822 xdr_init_decode(&xdr
, &req
->rq_rcv_buf
, p
);
1823 error
= decode_nfsstat3(&xdr
, &status
);
1824 if (unlikely(error
))
1826 if (status
!= NFS3_OK
)
1828 error
= decode_create3resok(&xdr
, result
);
1832 error
= decode_wcc_data(&xdr
, result
->dir_attr
);
1833 if (unlikely(error
))
1835 return nfs_stat_to_errno(status
);
1841 * struct REMOVE3resok {
1845 * struct REMOVE3resfail {
1849 * union REMOVE3res switch (nfsstat3 status) {
1851 * REMOVE3resok resok;
1853 * REMOVE3resfail resfail;
1856 static int nfs3_xdr_dec_remove3res(struct rpc_rqst
*req
, __be32
*p
,
1857 struct nfs_removeres
*result
)
1859 struct xdr_stream xdr
;
1860 enum nfs_stat status
;
1863 xdr_init_decode(&xdr
, &req
->rq_rcv_buf
, p
);
1864 error
= decode_nfsstat3(&xdr
, &status
);
1865 if (unlikely(error
))
1867 error
= decode_wcc_data(&xdr
, result
->dir_attr
);
1868 if (unlikely(error
))
1870 if (status
!= NFS3_OK
)
1875 return nfs_stat_to_errno(status
);
1881 * struct RENAME3resok {
1882 * wcc_data fromdir_wcc;
1883 * wcc_data todir_wcc;
1886 * struct RENAME3resfail {
1887 * wcc_data fromdir_wcc;
1888 * wcc_data todir_wcc;
1891 * union RENAME3res switch (nfsstat3 status) {
1893 * RENAME3resok resok;
1895 * RENAME3resfail resfail;
1898 static int nfs3_xdr_dec_rename3res(struct rpc_rqst
*req
, __be32
*p
,
1899 struct nfs_renameres
*result
)
1901 struct xdr_stream xdr
;
1902 enum nfs_stat status
;
1905 xdr_init_decode(&xdr
, &req
->rq_rcv_buf
, p
);
1906 error
= decode_nfsstat3(&xdr
, &status
);
1907 if (unlikely(error
))
1909 error
= decode_wcc_data(&xdr
, result
->old_fattr
);
1910 if (unlikely(error
))
1912 error
= decode_wcc_data(&xdr
, result
->new_fattr
);
1913 if (unlikely(error
))
1915 if (status
!= NFS3_OK
)
1920 return nfs_stat_to_errno(status
);
1926 * struct LINK3resok {
1927 * post_op_attr file_attributes;
1928 * wcc_data linkdir_wcc;
1931 * struct LINK3resfail {
1932 * post_op_attr file_attributes;
1933 * wcc_data linkdir_wcc;
1936 * union LINK3res switch (nfsstat3 status) {
1940 * LINK3resfail resfail;
1943 static int nfs3_xdr_dec_link3res(struct rpc_rqst
*req
, __be32
*p
,
1944 struct nfs3_linkres
*result
)
1946 struct xdr_stream xdr
;
1947 enum nfs_stat status
;
1950 xdr_init_decode(&xdr
, &req
->rq_rcv_buf
, p
);
1951 error
= decode_nfsstat3(&xdr
, &status
);
1952 if (unlikely(error
))
1954 error
= decode_post_op_attr(&xdr
, result
->fattr
);
1955 if (unlikely(error
))
1957 error
= decode_wcc_data(&xdr
, result
->dir_attr
);
1958 if (unlikely(error
))
1960 if (status
!= NFS3_OK
)
1965 return nfs_stat_to_errno(status
);
1969 * nfs3_decode_dirent - Decode a single NFSv3 directory entry stored in
1970 * the local page cache
1971 * @xdr: XDR stream where entry resides
1972 * @entry: buffer to fill in with entry data
1973 * @server: nfs_server data for this directory
1974 * @plus: boolean indicating whether this should be a readdirplus entry
1976 * Returns the position of the next item in the buffer, or an ERR_PTR.
1978 * This function is not invoked during READDIR reply decoding, but
1979 * rather whenever an application invokes the getdents(2) system call
1980 * on a directory already in our cache.
1988 * fhandle3 filehandle;
1989 * post_op_attr3 attributes;
1990 * entry3 *nextentry;
1994 * struct entryplus3 {
1998 * post_op_attr name_attributes;
1999 * post_op_fh3 name_handle;
2000 * entryplus3 *nextentry;
2003 __be32
*nfs3_decode_dirent(struct xdr_stream
*xdr
, struct nfs_entry
*entry
,
2004 struct nfs_server
*server
, int plus
)
2006 struct nfs_entry old
= *entry
;
2010 p
= xdr_inline_decode(xdr
, 4);
2011 if (unlikely(p
== NULL
))
2013 if (*p
== xdr_zero
) {
2014 p
= xdr_inline_decode(xdr
, 4);
2015 if (unlikely(p
== NULL
))
2018 return ERR_PTR(-EAGAIN
);
2020 return ERR_PTR(-EBADCOOKIE
);
2023 error
= decode_fileid3(xdr
, &entry
->ino
);
2024 if (unlikely(error
))
2025 return ERR_PTR(error
);
2027 error
= decode_inline_filename3(xdr
, &entry
->name
, &entry
->len
);
2028 if (unlikely(error
))
2029 return ERR_PTR(error
);
2031 entry
->prev_cookie
= entry
->cookie
;
2032 error
= decode_cookie3(xdr
, &entry
->cookie
);
2033 if (unlikely(error
))
2034 return ERR_PTR(error
);
2036 entry
->d_type
= DT_UNKNOWN
;
2039 entry
->fattr
->valid
= 0;
2040 error
= decode_post_op_attr(xdr
, entry
->fattr
);
2041 if (unlikely(error
))
2042 return ERR_PTR(error
);
2043 if (entry
->fattr
->valid
& NFS_ATTR_FATTR_V3
)
2044 entry
->d_type
= nfs_umode_to_dtype(entry
->fattr
->mode
);
2046 /* In fact, a post_op_fh3: */
2047 p
= xdr_inline_decode(xdr
, 4);
2048 if (unlikely(p
== NULL
))
2050 if (*p
!= xdr_zero
) {
2051 error
= decode_nfs_fh3(xdr
, entry
->fh
);
2052 if (unlikely(error
)) {
2053 if (error
== -E2BIG
)
2055 return ERR_PTR(error
);
2058 zero_nfs_fh3(entry
->fh
);
2061 /* Peek at the next entry to see if we're at EOD */
2062 p
= xdr_inline_peek(xdr
, 4 + 4);
2065 entry
->eof
= (p
[0] == xdr_zero
) && (p
[1] != xdr_zero
);
2069 print_overflow_msg(__func__
, xdr
);
2070 return ERR_PTR(-EAGAIN
);
2072 dprintk("NFS: directory entry contains invalid file handle\n");
2074 return ERR_PTR(-EAGAIN
);
2078 * 3.3.16 READDIR3res
2085 * struct READDIR3resok {
2086 * post_op_attr dir_attributes;
2087 * cookieverf3 cookieverf;
2091 * struct READDIR3resfail {
2092 * post_op_attr dir_attributes;
2095 * union READDIR3res switch (nfsstat3 status) {
2097 * READDIR3resok resok;
2099 * READDIR3resfail resfail;
2102 * Read the directory contents into the page cache, but otherwise
2103 * don't touch them. The actual decoding is done by nfs3_decode_entry()
2104 * during subsequent nfs_readdir() calls.
2106 static int decode_dirlist3(struct xdr_stream
*xdr
)
2111 pglen
= xdr
->buf
->page_len
;
2112 hdrlen
= (u8
*)xdr
->p
- (u8
*)xdr
->iov
->iov_base
;
2113 recvd
= xdr
->buf
->len
- hdrlen
;
2114 if (unlikely(pglen
> recvd
))
2117 xdr_read_pages(xdr
, pglen
);
2120 dprintk("NFS: server cheating in readdir result: "
2121 "pglen %u > recvd %u\n", pglen
, recvd
);
2126 static int decode_readdir3resok(struct xdr_stream
*xdr
,
2127 struct nfs3_readdirres
*result
)
2131 error
= decode_post_op_attr(xdr
, result
->dir_attr
);
2132 if (unlikely(error
))
2134 /* XXX: do we need to check if result->verf != NULL ? */
2135 error
= decode_cookieverf3(xdr
, result
->verf
);
2136 if (unlikely(error
))
2138 error
= decode_dirlist3(xdr
);
2143 static int nfs3_xdr_dec_readdir3res(struct rpc_rqst
*req
, __be32
*p
,
2144 struct nfs3_readdirres
*result
)
2146 struct xdr_stream xdr
;
2147 enum nfs_stat status
;
2150 xdr_init_decode(&xdr
, &req
->rq_rcv_buf
, p
);
2151 error
= decode_nfsstat3(&xdr
, &status
);
2152 if (unlikely(error
))
2154 if (status
!= NFS3_OK
)
2156 error
= decode_readdir3resok(&xdr
, result
);
2160 error
= decode_post_op_attr(&xdr
, result
->dir_attr
);
2161 if (unlikely(error
))
2163 return nfs_stat_to_errno(status
);
2169 * struct FSSTAT3resok {
2170 * post_op_attr obj_attributes;
2180 * struct FSSTAT3resfail {
2181 * post_op_attr obj_attributes;
2184 * union FSSTAT3res switch (nfsstat3 status) {
2186 * FSSTAT3resok resok;
2188 * FSSTAT3resfail resfail;
2191 static int decode_fsstat3resok(struct xdr_stream
*xdr
,
2192 struct nfs_fsstat
*result
)
2196 p
= xdr_inline_decode(xdr
, 8 * 6 + 4);
2197 if (unlikely(p
== NULL
))
2199 p
= xdr_decode_size3(p
, &result
->tbytes
);
2200 p
= xdr_decode_size3(p
, &result
->fbytes
);
2201 p
= xdr_decode_size3(p
, &result
->abytes
);
2202 p
= xdr_decode_size3(p
, &result
->tfiles
);
2203 p
= xdr_decode_size3(p
, &result
->ffiles
);
2204 xdr_decode_size3(p
, &result
->afiles
);
2205 /* ignore invarsec */
2208 print_overflow_msg(__func__
, xdr
);
2212 static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst
*req
, __be32
*p
,
2213 struct nfs_fsstat
*result
)
2215 struct xdr_stream xdr
;
2216 enum nfs_stat status
;
2219 xdr_init_decode(&xdr
, &req
->rq_rcv_buf
, p
);
2220 error
= decode_nfsstat3(&xdr
, &status
);
2221 if (unlikely(error
))
2223 error
= decode_post_op_attr(&xdr
, result
->fattr
);
2224 if (unlikely(error
))
2226 if (status
!= NFS3_OK
)
2228 error
= decode_fsstat3resok(&xdr
, result
);
2232 return nfs_stat_to_errno(status
);
2238 * struct FSINFO3resok {
2239 * post_op_attr obj_attributes;
2247 * size3 maxfilesize;
2248 * nfstime3 time_delta;
2249 * uint32 properties;
2252 * struct FSINFO3resfail {
2253 * post_op_attr obj_attributes;
2256 * union FSINFO3res switch (nfsstat3 status) {
2258 * FSINFO3resok resok;
2260 * FSINFO3resfail resfail;
2263 static int decode_fsinfo3resok(struct xdr_stream
*xdr
,
2264 struct nfs_fsinfo
*result
)
2268 p
= xdr_inline_decode(xdr
, 4 * 7 + 8 + 8 + 4);
2269 if (unlikely(p
== NULL
))
2271 result
->rtmax
= be32_to_cpup(p
++);
2272 result
->rtpref
= be32_to_cpup(p
++);
2273 result
->rtmult
= be32_to_cpup(p
++);
2274 result
->wtmax
= be32_to_cpup(p
++);
2275 result
->wtpref
= be32_to_cpup(p
++);
2276 result
->wtmult
= be32_to_cpup(p
++);
2277 result
->dtpref
= be32_to_cpup(p
++);
2278 p
= xdr_decode_size3(p
, &result
->maxfilesize
);
2279 xdr_decode_nfstime3(p
, &result
->time_delta
);
2281 /* ignore properties */
2282 result
->lease_time
= 0;
2285 print_overflow_msg(__func__
, xdr
);
2289 static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst
*req
, __be32
*p
,
2290 struct nfs_fsinfo
*result
)
2292 struct xdr_stream xdr
;
2293 enum nfs_stat status
;
2296 xdr_init_decode(&xdr
, &req
->rq_rcv_buf
, p
);
2297 error
= decode_nfsstat3(&xdr
, &status
);
2298 if (unlikely(error
))
2300 error
= decode_post_op_attr(&xdr
, result
->fattr
);
2301 if (unlikely(error
))
2303 if (status
!= NFS3_OK
)
2305 error
= decode_fsinfo3resok(&xdr
, result
);
2309 return nfs_stat_to_errno(status
);
2313 * 3.3.20 PATHCONF3res
2315 * struct PATHCONF3resok {
2316 * post_op_attr obj_attributes;
2320 * bool chown_restricted;
2321 * bool case_insensitive;
2322 * bool case_preserving;
2325 * struct PATHCONF3resfail {
2326 * post_op_attr obj_attributes;
2329 * union PATHCONF3res switch (nfsstat3 status) {
2331 * PATHCONF3resok resok;
2333 * PATHCONF3resfail resfail;
2336 static int decode_pathconf3resok(struct xdr_stream
*xdr
,
2337 struct nfs_pathconf
*result
)
2341 p
= xdr_inline_decode(xdr
, 4 * 6);
2342 if (unlikely(p
== NULL
))
2344 result
->max_link
= be32_to_cpup(p
++);
2345 result
->max_namelen
= be32_to_cpup(p
);
2346 /* ignore remaining fields */
2349 print_overflow_msg(__func__
, xdr
);
2353 static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst
*req
, __be32
*p
,
2354 struct nfs_pathconf
*result
)
2356 struct xdr_stream xdr
;
2357 enum nfs_stat status
;
2360 xdr_init_decode(&xdr
, &req
->rq_rcv_buf
, p
);
2361 error
= decode_nfsstat3(&xdr
, &status
);
2362 if (unlikely(error
))
2364 error
= decode_post_op_attr(&xdr
, result
->fattr
);
2365 if (unlikely(error
))
2367 if (status
!= NFS3_OK
)
2369 error
= decode_pathconf3resok(&xdr
, result
);
2373 return nfs_stat_to_errno(status
);
2379 * struct COMMIT3resok {
2380 * wcc_data file_wcc;
2384 * struct COMMIT3resfail {
2385 * wcc_data file_wcc;
2388 * union COMMIT3res switch (nfsstat3 status) {
2390 * COMMIT3resok resok;
2392 * COMMIT3resfail resfail;
2395 static int nfs3_xdr_dec_commit3res(struct rpc_rqst
*req
, __be32
*p
,
2396 struct nfs_writeres
*result
)
2398 struct xdr_stream xdr
;
2399 enum nfs_stat status
;
2402 xdr_init_decode(&xdr
, &req
->rq_rcv_buf
, p
);
2403 error
= decode_nfsstat3(&xdr
, &status
);
2404 if (unlikely(error
))
2406 error
= decode_wcc_data(&xdr
, result
->fattr
);
2407 if (unlikely(error
))
2409 if (status
!= NFS3_OK
)
2411 error
= decode_writeverf3(&xdr
, result
->verf
->verifier
);
2415 return nfs_stat_to_errno(status
);
2418 #ifdef CONFIG_NFS_V3_ACL
2420 static inline int decode_getacl3resok(struct xdr_stream
*xdr
,
2421 struct nfs3_getaclres
*result
)
2423 struct posix_acl
**acl
;
2424 unsigned int *aclcnt
;
2428 error
= decode_post_op_attr(xdr
, result
->fattr
);
2429 if (unlikely(error
))
2431 error
= decode_uint32(xdr
, &result
->mask
);
2432 if (unlikely(error
))
2435 if (result
->mask
& ~(NFS_ACL
|NFS_ACLCNT
|NFS_DFACL
|NFS_DFACLCNT
))
2438 hdrlen
= (u8
*)xdr
->p
- (u8
*)xdr
->iov
->iov_base
;
2441 if (result
->mask
& NFS_ACL
)
2442 acl
= &result
->acl_access
;
2444 if (result
->mask
& NFS_ACLCNT
)
2445 aclcnt
= &result
->acl_access_count
;
2446 error
= nfsacl_decode(xdr
->buf
, hdrlen
, aclcnt
, acl
);
2447 if (unlikely(error
<= 0))
2451 if (result
->mask
& NFS_DFACL
)
2452 acl
= &result
->acl_default
;
2454 if (result
->mask
& NFS_DFACLCNT
)
2455 aclcnt
= &result
->acl_default_count
;
2456 error
= nfsacl_decode(xdr
->buf
, hdrlen
+ error
, aclcnt
, acl
);
2457 if (unlikely(error
<= 0))
2464 static int nfs3_xdr_dec_getacl3res(struct rpc_rqst
*req
, __be32
*p
,
2465 struct nfs3_getaclres
*result
)
2467 struct xdr_stream xdr
;
2468 enum nfs_stat status
;
2471 xdr_init_decode(&xdr
, &req
->rq_rcv_buf
, p
);
2472 error
= decode_nfsstat3(&xdr
, &status
);
2473 if (unlikely(error
))
2475 if (status
!= NFS3_OK
)
2477 error
= decode_getacl3resok(&xdr
, result
);
2481 return nfs_stat_to_errno(status
);
2484 static int nfs3_xdr_dec_setacl3res(struct rpc_rqst
*req
, __be32
*p
,
2485 struct nfs_fattr
*result
)
2487 struct xdr_stream xdr
;
2488 enum nfs_stat status
;
2491 xdr_init_decode(&xdr
, &req
->rq_rcv_buf
, p
);
2492 error
= decode_nfsstat3(&xdr
, &status
);
2493 if (unlikely(error
))
2495 if (status
!= NFS3_OK
)
2497 error
= decode_post_op_attr(&xdr
, result
);
2501 return nfs_stat_to_errno(status
);
2504 #endif /* CONFIG_NFS_V3_ACL */
2506 #define PROC(proc, argtype, restype, timer) \
2507 [NFS3PROC_##proc] = { \
2508 .p_proc = NFS3PROC_##proc, \
2509 .p_encode = (kxdrproc_t)nfs3_xdr_enc_##argtype##3args, \
2510 .p_decode = (kxdrproc_t)nfs3_xdr_dec_##restype##3res, \
2511 .p_arglen = NFS3_##argtype##args_sz, \
2512 .p_replen = NFS3_##restype##res_sz, \
2514 .p_statidx = NFS3PROC_##proc, \
2518 struct rpc_procinfo nfs3_procedures
[] = {
2519 PROC(GETATTR
, getattr
, getattr
, 1),
2520 PROC(SETATTR
, setattr
, setattr
, 0),
2521 PROC(LOOKUP
, lookup
, lookup
, 2),
2522 PROC(ACCESS
, access
, access
, 1),
2523 PROC(READLINK
, readlink
, readlink
, 3),
2524 PROC(READ
, read
, read
, 3),
2525 PROC(WRITE
, write
, write
, 4),
2526 PROC(CREATE
, create
, create
, 0),
2527 PROC(MKDIR
, mkdir
, create
, 0),
2528 PROC(SYMLINK
, symlink
, create
, 0),
2529 PROC(MKNOD
, mknod
, create
, 0),
2530 PROC(REMOVE
, remove
, remove
, 0),
2531 PROC(RMDIR
, lookup
, setattr
, 0),
2532 PROC(RENAME
, rename
, rename
, 0),
2533 PROC(LINK
, link
, link
, 0),
2534 PROC(READDIR
, readdir
, readdir
, 3),
2535 PROC(READDIRPLUS
, readdirplus
, readdir
, 3),
2536 PROC(FSSTAT
, getattr
, fsstat
, 0),
2537 PROC(FSINFO
, getattr
, fsinfo
, 0),
2538 PROC(PATHCONF
, getattr
, pathconf
, 0),
2539 PROC(COMMIT
, commit
, commit
, 5),
2542 struct rpc_version nfs_version3
= {
2544 .nrprocs
= ARRAY_SIZE(nfs3_procedures
),
2545 .procs
= nfs3_procedures
2548 #ifdef CONFIG_NFS_V3_ACL
2549 static struct rpc_procinfo nfs3_acl_procedures
[] = {
2550 [ACLPROC3_GETACL
] = {
2551 .p_proc
= ACLPROC3_GETACL
,
2552 .p_encode
= (kxdrproc_t
)nfs3_xdr_enc_getacl3args
,
2553 .p_decode
= (kxdrproc_t
)nfs3_xdr_dec_getacl3res
,
2554 .p_arglen
= ACL3_getaclargs_sz
,
2555 .p_replen
= ACL3_getaclres_sz
,
2559 [ACLPROC3_SETACL
] = {
2560 .p_proc
= ACLPROC3_SETACL
,
2561 .p_encode
= (kxdrproc_t
)nfs3_xdr_enc_setacl3args
,
2562 .p_decode
= (kxdrproc_t
)nfs3_xdr_dec_setacl3res
,
2563 .p_arglen
= ACL3_setaclargs_sz
,
2564 .p_replen
= ACL3_setaclres_sz
,
2570 struct rpc_version nfsacl_version3
= {
2572 .nrprocs
= sizeof(nfs3_acl_procedures
)/
2573 sizeof(nfs3_acl_procedures
[0]),
2574 .procs
= nfs3_acl_procedures
,
2576 #endif /* CONFIG_NFS_V3_ACL */