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)
89 static int nfs3_stat_to_errno(enum nfs_stat
);
92 * Map file type to S_IFMT bits
94 static const umode_t nfs_type2fmt
[] = {
101 [NF3SOCK
] = S_IFSOCK
,
106 * While encoding arguments, set up the reply buffer in advance to
107 * receive reply data directly into the page cache.
109 static void prepare_reply_buffer(struct rpc_rqst
*req
, struct page
**pages
,
110 unsigned int base
, unsigned int len
,
111 unsigned int bufsize
)
113 struct rpc_auth
*auth
= req
->rq_cred
->cr_auth
;
116 replen
= RPC_REPHDRSIZE
+ auth
->au_rslack
+ bufsize
;
117 xdr_inline_pages(&req
->rq_rcv_buf
, replen
<< 2, pages
, base
, len
);
121 * Handle decode buffer overflows out-of-line.
123 static void print_overflow_msg(const char *func
, const struct xdr_stream
*xdr
)
125 dprintk("NFS: %s prematurely hit the end of our receive buffer. "
126 "Remaining buffer length is %tu words.\n",
127 func
, xdr
->end
- xdr
->p
);
132 * Encode/decode NFSv3 basic data types
134 * Basic NFSv3 data types are defined in section 2.5 of RFC 1813:
135 * "NFS Version 3 Protocol Specification".
137 * Not all basic data types have their own encoding and decoding
138 * functions. For run-time efficiency, some data types are encoded
142 static void encode_uint32(struct xdr_stream
*xdr
, u32 value
)
144 __be32
*p
= xdr_reserve_space(xdr
, 4);
145 *p
= cpu_to_be32(value
);
148 static int decode_uint32(struct xdr_stream
*xdr
, u32
*value
)
152 p
= xdr_inline_decode(xdr
, 4);
153 if (unlikely(p
== NULL
))
155 *value
= be32_to_cpup(p
);
158 print_overflow_msg(__func__
, xdr
);
162 static int decode_uint64(struct xdr_stream
*xdr
, u64
*value
)
166 p
= xdr_inline_decode(xdr
, 8);
167 if (unlikely(p
== NULL
))
169 xdr_decode_hyper(p
, value
);
172 print_overflow_msg(__func__
, xdr
);
179 * typedef uint64 fileid3;
181 static __be32
*xdr_decode_fileid3(__be32
*p
, u64
*fileid
)
183 return xdr_decode_hyper(p
, fileid
);
186 static int decode_fileid3(struct xdr_stream
*xdr
, u64
*fileid
)
188 return decode_uint64(xdr
, fileid
);
194 * typedef string filename3<>;
196 static void encode_filename3(struct xdr_stream
*xdr
,
197 const char *name
, u32 length
)
201 BUG_ON(length
> NFS3_MAXNAMLEN
);
202 p
= xdr_reserve_space(xdr
, 4 + length
);
203 xdr_encode_opaque(p
, name
, length
);
206 static int decode_inline_filename3(struct xdr_stream
*xdr
,
207 const char **name
, u32
*length
)
212 p
= xdr_inline_decode(xdr
, 4);
213 if (unlikely(p
== NULL
))
215 count
= be32_to_cpup(p
);
216 if (count
> NFS3_MAXNAMLEN
)
217 goto out_nametoolong
;
218 p
= xdr_inline_decode(xdr
, count
);
219 if (unlikely(p
== NULL
))
221 *name
= (const char *)p
;
226 dprintk("NFS: returned filename too long: %u\n", count
);
227 return -ENAMETOOLONG
;
229 print_overflow_msg(__func__
, xdr
);
236 * typedef string nfspath3<>;
238 static void encode_nfspath3(struct xdr_stream
*xdr
, struct page
**pages
,
241 BUG_ON(length
> NFS3_MAXPATHLEN
);
242 encode_uint32(xdr
, length
);
243 xdr_write_pages(xdr
, pages
, 0, length
);
246 static int decode_nfspath3(struct xdr_stream
*xdr
)
252 p
= xdr_inline_decode(xdr
, 4);
253 if (unlikely(p
== NULL
))
255 count
= be32_to_cpup(p
);
256 if (unlikely(count
>= xdr
->buf
->page_len
|| count
> NFS3_MAXPATHLEN
))
257 goto out_nametoolong
;
258 hdrlen
= (u8
*)xdr
->p
- (u8
*)xdr
->iov
->iov_base
;
259 recvd
= xdr
->buf
->len
- hdrlen
;
260 if (unlikely(count
> recvd
))
263 xdr_read_pages(xdr
, count
);
264 xdr_terminate_string(xdr
->buf
, count
);
268 dprintk("NFS: returned pathname too long: %u\n", count
);
269 return -ENAMETOOLONG
;
271 dprintk("NFS: server cheating in pathname result: "
272 "count %u > recvd %u\n", count
, recvd
);
275 print_overflow_msg(__func__
, xdr
);
282 * typedef uint64 cookie3
284 static __be32
*xdr_encode_cookie3(__be32
*p
, u64 cookie
)
286 return xdr_encode_hyper(p
, cookie
);
289 static int decode_cookie3(struct xdr_stream
*xdr
, u64
*cookie
)
291 return decode_uint64(xdr
, cookie
);
297 * typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
299 static __be32
*xdr_encode_cookieverf3(__be32
*p
, const __be32
*verifier
)
301 memcpy(p
, verifier
, NFS3_COOKIEVERFSIZE
);
302 return p
+ XDR_QUADLEN(NFS3_COOKIEVERFSIZE
);
305 static int decode_cookieverf3(struct xdr_stream
*xdr
, __be32
*verifier
)
309 p
= xdr_inline_decode(xdr
, NFS3_COOKIEVERFSIZE
);
310 if (unlikely(p
== NULL
))
312 memcpy(verifier
, p
, NFS3_COOKIEVERFSIZE
);
315 print_overflow_msg(__func__
, xdr
);
322 * typedef opaque createverf3[NFS3_CREATEVERFSIZE];
324 static void encode_createverf3(struct xdr_stream
*xdr
, const __be32
*verifier
)
328 p
= xdr_reserve_space(xdr
, NFS3_CREATEVERFSIZE
);
329 memcpy(p
, verifier
, NFS3_CREATEVERFSIZE
);
332 static int decode_writeverf3(struct xdr_stream
*xdr
, __be32
*verifier
)
336 p
= xdr_inline_decode(xdr
, NFS3_WRITEVERFSIZE
);
337 if (unlikely(p
== NULL
))
339 memcpy(verifier
, p
, NFS3_WRITEVERFSIZE
);
342 print_overflow_msg(__func__
, xdr
);
349 * typedef uint64 size3;
351 static __be32
*xdr_decode_size3(__be32
*p
, u64
*size
)
353 return xdr_decode_hyper(p
, size
);
364 #define NFS3_OK NFS_OK
366 static int decode_nfsstat3(struct xdr_stream
*xdr
, enum nfs_stat
*status
)
370 p
= xdr_inline_decode(xdr
, 4);
371 if (unlikely(p
== NULL
))
373 *status
= be32_to_cpup(p
);
376 print_overflow_msg(__func__
, xdr
);
393 static void encode_ftype3(struct xdr_stream
*xdr
, const u32 type
)
395 BUG_ON(type
> NF3FIFO
);
396 encode_uint32(xdr
, type
);
399 static __be32
*xdr_decode_ftype3(__be32
*p
, umode_t
*mode
)
403 type
= be32_to_cpup(p
++);
406 *mode
= nfs_type2fmt
[type
];
418 static void encode_specdata3(struct xdr_stream
*xdr
, const dev_t rdev
)
422 p
= xdr_reserve_space(xdr
, 8);
423 *p
++ = cpu_to_be32(MAJOR(rdev
));
424 *p
= cpu_to_be32(MINOR(rdev
));
427 static __be32
*xdr_decode_specdata3(__be32
*p
, dev_t
*rdev
)
429 unsigned int major
, minor
;
431 major
= be32_to_cpup(p
++);
432 minor
= be32_to_cpup(p
++);
433 *rdev
= MKDEV(major
, minor
);
434 if (MAJOR(*rdev
) != major
|| MINOR(*rdev
) != minor
)
443 * opaque data<NFS3_FHSIZE>;
446 static void encode_nfs_fh3(struct xdr_stream
*xdr
, const struct nfs_fh
*fh
)
450 BUG_ON(fh
->size
> NFS3_FHSIZE
);
451 p
= xdr_reserve_space(xdr
, 4 + fh
->size
);
452 xdr_encode_opaque(p
, fh
->data
, fh
->size
);
455 static int decode_nfs_fh3(struct xdr_stream
*xdr
, struct nfs_fh
*fh
)
460 p
= xdr_inline_decode(xdr
, 4);
461 if (unlikely(p
== NULL
))
463 length
= be32_to_cpup(p
++);
464 if (unlikely(length
> NFS3_FHSIZE
))
466 p
= xdr_inline_decode(xdr
, length
);
467 if (unlikely(p
== NULL
))
470 memcpy(fh
->data
, p
, length
);
473 dprintk("NFS: file handle size (%u) too big\n", length
);
476 print_overflow_msg(__func__
, xdr
);
480 static void zero_nfs_fh3(struct nfs_fh
*fh
)
482 memset(fh
, 0, sizeof(*fh
));
493 static __be32
*xdr_encode_nfstime3(__be32
*p
, const struct timespec
*timep
)
495 *p
++ = cpu_to_be32(timep
->tv_sec
);
496 *p
++ = cpu_to_be32(timep
->tv_nsec
);
500 static __be32
*xdr_decode_nfstime3(__be32
*p
, struct timespec
*timep
)
502 timep
->tv_sec
= be32_to_cpup(p
++);
503 timep
->tv_nsec
= be32_to_cpup(p
++);
512 * SET_TO_SERVER_TIME = 1,
513 * SET_TO_CLIENT_TIME = 2
516 * union set_mode3 switch (bool set_it) {
523 * union set_uid3 switch (bool set_it) {
530 * union set_gid3 switch (bool set_it) {
537 * union set_size3 switch (bool set_it) {
544 * union set_atime switch (time_how set_it) {
545 * case SET_TO_CLIENT_TIME:
551 * union set_mtime switch (time_how set_it) {
552 * case SET_TO_CLIENT_TIME:
567 static void encode_sattr3(struct xdr_stream
*xdr
, const struct iattr
*attr
)
573 * In order to make only a single xdr_reserve_space() call,
574 * pre-compute the total number of bytes to be reserved.
575 * Six boolean values, one for each set_foo field, are always
576 * present in the encoded result, so start there.
579 if (attr
->ia_valid
& ATTR_MODE
)
581 if (attr
->ia_valid
& ATTR_UID
)
583 if (attr
->ia_valid
& ATTR_GID
)
585 if (attr
->ia_valid
& ATTR_SIZE
)
587 if (attr
->ia_valid
& ATTR_ATIME_SET
)
589 if (attr
->ia_valid
& ATTR_MTIME_SET
)
591 p
= xdr_reserve_space(xdr
, nbytes
);
593 if (attr
->ia_valid
& ATTR_MODE
) {
595 *p
++ = cpu_to_be32(attr
->ia_mode
& S_IALLUGO
);
599 if (attr
->ia_valid
& ATTR_UID
) {
601 *p
++ = cpu_to_be32(attr
->ia_uid
);
605 if (attr
->ia_valid
& ATTR_GID
) {
607 *p
++ = cpu_to_be32(attr
->ia_gid
);
611 if (attr
->ia_valid
& ATTR_SIZE
) {
613 p
= xdr_encode_hyper(p
, (u64
)attr
->ia_size
);
617 if (attr
->ia_valid
& ATTR_ATIME_SET
) {
619 p
= xdr_encode_nfstime3(p
, &attr
->ia_atime
);
620 } else if (attr
->ia_valid
& ATTR_ATIME
) {
625 if (attr
->ia_valid
& ATTR_MTIME_SET
) {
627 xdr_encode_nfstime3(p
, &attr
->ia_mtime
);
628 } else if (attr
->ia_valid
& ATTR_MTIME
) {
653 static int decode_fattr3(struct xdr_stream
*xdr
, struct nfs_fattr
*fattr
)
658 p
= xdr_inline_decode(xdr
, NFS3_fattr_sz
<< 2);
659 if (unlikely(p
== NULL
))
662 p
= xdr_decode_ftype3(p
, &fmode
);
664 fattr
->mode
= (be32_to_cpup(p
++) & ~S_IFMT
) | fmode
;
665 fattr
->nlink
= be32_to_cpup(p
++);
666 fattr
->uid
= be32_to_cpup(p
++);
667 fattr
->gid
= be32_to_cpup(p
++);
669 p
= xdr_decode_size3(p
, &fattr
->size
);
670 p
= xdr_decode_size3(p
, &fattr
->du
.nfs3
.used
);
671 p
= xdr_decode_specdata3(p
, &fattr
->rdev
);
673 p
= xdr_decode_hyper(p
, &fattr
->fsid
.major
);
674 fattr
->fsid
.minor
= 0;
676 p
= xdr_decode_fileid3(p
, &fattr
->fileid
);
677 p
= xdr_decode_nfstime3(p
, &fattr
->atime
);
678 p
= xdr_decode_nfstime3(p
, &fattr
->mtime
);
679 xdr_decode_nfstime3(p
, &fattr
->ctime
);
680 fattr
->change_attr
= nfs_timespec_to_change_attr(&fattr
->ctime
);
682 fattr
->valid
|= NFS_ATTR_FATTR_V3
;
685 print_overflow_msg(__func__
, xdr
);
692 * union post_op_attr switch (bool attributes_follow) {
699 static int decode_post_op_attr(struct xdr_stream
*xdr
, struct nfs_fattr
*fattr
)
703 p
= xdr_inline_decode(xdr
, 4);
704 if (unlikely(p
== NULL
))
707 return decode_fattr3(xdr
, fattr
);
710 print_overflow_msg(__func__
, xdr
);
722 static int decode_wcc_attr(struct xdr_stream
*xdr
, struct nfs_fattr
*fattr
)
726 p
= xdr_inline_decode(xdr
, NFS3_wcc_attr_sz
<< 2);
727 if (unlikely(p
== NULL
))
730 fattr
->valid
|= NFS_ATTR_FATTR_PRESIZE
731 | NFS_ATTR_FATTR_PRECHANGE
732 | NFS_ATTR_FATTR_PREMTIME
733 | NFS_ATTR_FATTR_PRECTIME
;
735 p
= xdr_decode_size3(p
, &fattr
->pre_size
);
736 p
= xdr_decode_nfstime3(p
, &fattr
->pre_mtime
);
737 xdr_decode_nfstime3(p
, &fattr
->pre_ctime
);
738 fattr
->pre_change_attr
= nfs_timespec_to_change_attr(&fattr
->pre_ctime
);
742 print_overflow_msg(__func__
, xdr
);
748 * union pre_op_attr switch (bool attributes_follow) {
750 * wcc_attr attributes;
758 * pre_op_attr before;
759 * post_op_attr after;
762 static int decode_pre_op_attr(struct xdr_stream
*xdr
, struct nfs_fattr
*fattr
)
766 p
= xdr_inline_decode(xdr
, 4);
767 if (unlikely(p
== NULL
))
770 return decode_wcc_attr(xdr
, fattr
);
773 print_overflow_msg(__func__
, xdr
);
777 static int decode_wcc_data(struct xdr_stream
*xdr
, struct nfs_fattr
*fattr
)
781 error
= decode_pre_op_attr(xdr
, fattr
);
784 error
= decode_post_op_attr(xdr
, fattr
);
792 * union post_op_fh3 switch (bool handle_follows) {
799 static int decode_post_op_fh3(struct xdr_stream
*xdr
, struct nfs_fh
*fh
)
801 __be32
*p
= xdr_inline_decode(xdr
, 4);
802 if (unlikely(p
== NULL
))
805 return decode_nfs_fh3(xdr
, fh
);
809 print_overflow_msg(__func__
, xdr
);
816 * struct diropargs3 {
821 static void encode_diropargs3(struct xdr_stream
*xdr
, const struct nfs_fh
*fh
,
822 const char *name
, u32 length
)
824 encode_nfs_fh3(xdr
, fh
);
825 encode_filename3(xdr
, name
, length
);
830 * NFSv3 XDR encode functions
832 * NFSv3 argument types are defined in section 3.3 of RFC 1813:
833 * "NFS Version 3 Protocol Specification".
839 * struct GETATTR3args {
843 static void nfs3_xdr_enc_getattr3args(struct rpc_rqst
*req
,
844 struct xdr_stream
*xdr
,
845 const struct nfs_fh
*fh
)
847 encode_nfs_fh3(xdr
, fh
);
853 * union sattrguard3 switch (bool check) {
855 * nfstime3 obj_ctime;
860 * struct SETATTR3args {
862 * sattr3 new_attributes;
866 static void encode_sattrguard3(struct xdr_stream
*xdr
,
867 const struct nfs3_sattrargs
*args
)
872 p
= xdr_reserve_space(xdr
, 4 + 8);
874 xdr_encode_nfstime3(p
, &args
->guardtime
);
876 p
= xdr_reserve_space(xdr
, 4);
881 static void nfs3_xdr_enc_setattr3args(struct rpc_rqst
*req
,
882 struct xdr_stream
*xdr
,
883 const struct nfs3_sattrargs
*args
)
885 encode_nfs_fh3(xdr
, args
->fh
);
886 encode_sattr3(xdr
, args
->sattr
);
887 encode_sattrguard3(xdr
, args
);
893 * struct LOOKUP3args {
897 static void nfs3_xdr_enc_lookup3args(struct rpc_rqst
*req
,
898 struct xdr_stream
*xdr
,
899 const struct nfs3_diropargs
*args
)
901 encode_diropargs3(xdr
, args
->fh
, args
->name
, args
->len
);
907 * struct ACCESS3args {
912 static void encode_access3args(struct xdr_stream
*xdr
,
913 const struct nfs3_accessargs
*args
)
915 encode_nfs_fh3(xdr
, args
->fh
);
916 encode_uint32(xdr
, args
->access
);
919 static void nfs3_xdr_enc_access3args(struct rpc_rqst
*req
,
920 struct xdr_stream
*xdr
,
921 const struct nfs3_accessargs
*args
)
923 encode_access3args(xdr
, args
);
927 * 3.3.5 READLINK3args
929 * struct READLINK3args {
933 static void nfs3_xdr_enc_readlink3args(struct rpc_rqst
*req
,
934 struct xdr_stream
*xdr
,
935 const struct nfs3_readlinkargs
*args
)
937 encode_nfs_fh3(xdr
, args
->fh
);
938 prepare_reply_buffer(req
, args
->pages
, args
->pgbase
,
939 args
->pglen
, NFS3_readlinkres_sz
);
951 static void encode_read3args(struct xdr_stream
*xdr
,
952 const struct nfs_readargs
*args
)
956 encode_nfs_fh3(xdr
, args
->fh
);
958 p
= xdr_reserve_space(xdr
, 8 + 4);
959 p
= xdr_encode_hyper(p
, args
->offset
);
960 *p
= cpu_to_be32(args
->count
);
963 static void nfs3_xdr_enc_read3args(struct rpc_rqst
*req
,
964 struct xdr_stream
*xdr
,
965 const struct nfs_readargs
*args
)
967 encode_read3args(xdr
, args
);
968 prepare_reply_buffer(req
, args
->pages
, args
->pgbase
,
969 args
->count
, NFS3_readres_sz
);
970 req
->rq_rcv_buf
.flags
|= XDRBUF_READ
;
982 * struct WRITE3args {
990 static void encode_write3args(struct xdr_stream
*xdr
,
991 const struct nfs_writeargs
*args
)
995 encode_nfs_fh3(xdr
, args
->fh
);
997 p
= xdr_reserve_space(xdr
, 8 + 4 + 4 + 4);
998 p
= xdr_encode_hyper(p
, args
->offset
);
999 *p
++ = cpu_to_be32(args
->count
);
1000 *p
++ = cpu_to_be32(args
->stable
);
1001 *p
= cpu_to_be32(args
->count
);
1002 xdr_write_pages(xdr
, args
->pages
, args
->pgbase
, args
->count
);
1005 static void nfs3_xdr_enc_write3args(struct rpc_rqst
*req
,
1006 struct xdr_stream
*xdr
,
1007 const struct nfs_writeargs
*args
)
1009 encode_write3args(xdr
, args
);
1010 xdr
->buf
->flags
|= XDRBUF_WRITE
;
1016 * enum createmode3 {
1022 * union createhow3 switch (createmode3 mode) {
1025 * sattr3 obj_attributes;
1030 * struct CREATE3args {
1035 static void encode_createhow3(struct xdr_stream
*xdr
,
1036 const struct nfs3_createargs
*args
)
1038 encode_uint32(xdr
, args
->createmode
);
1039 switch (args
->createmode
) {
1040 case NFS3_CREATE_UNCHECKED
:
1041 case NFS3_CREATE_GUARDED
:
1042 encode_sattr3(xdr
, args
->sattr
);
1044 case NFS3_CREATE_EXCLUSIVE
:
1045 encode_createverf3(xdr
, args
->verifier
);
1052 static void nfs3_xdr_enc_create3args(struct rpc_rqst
*req
,
1053 struct xdr_stream
*xdr
,
1054 const struct nfs3_createargs
*args
)
1056 encode_diropargs3(xdr
, args
->fh
, args
->name
, args
->len
);
1057 encode_createhow3(xdr
, args
);
1063 * struct MKDIR3args {
1065 * sattr3 attributes;
1068 static void nfs3_xdr_enc_mkdir3args(struct rpc_rqst
*req
,
1069 struct xdr_stream
*xdr
,
1070 const struct nfs3_mkdirargs
*args
)
1072 encode_diropargs3(xdr
, args
->fh
, args
->name
, args
->len
);
1073 encode_sattr3(xdr
, args
->sattr
);
1077 * 3.3.10 SYMLINK3args
1079 * struct symlinkdata3 {
1080 * sattr3 symlink_attributes;
1081 * nfspath3 symlink_data;
1084 * struct SYMLINK3args {
1086 * symlinkdata3 symlink;
1089 static void encode_symlinkdata3(struct xdr_stream
*xdr
,
1090 const struct nfs3_symlinkargs
*args
)
1092 encode_sattr3(xdr
, args
->sattr
);
1093 encode_nfspath3(xdr
, args
->pages
, args
->pathlen
);
1096 static void nfs3_xdr_enc_symlink3args(struct rpc_rqst
*req
,
1097 struct xdr_stream
*xdr
,
1098 const struct nfs3_symlinkargs
*args
)
1100 encode_diropargs3(xdr
, args
->fromfh
, args
->fromname
, args
->fromlen
);
1101 encode_symlinkdata3(xdr
, args
);
1107 * struct devicedata3 {
1108 * sattr3 dev_attributes;
1112 * union mknoddata3 switch (ftype3 type) {
1115 * devicedata3 device;
1118 * sattr3 pipe_attributes;
1123 * struct MKNOD3args {
1128 static void encode_devicedata3(struct xdr_stream
*xdr
,
1129 const struct nfs3_mknodargs
*args
)
1131 encode_sattr3(xdr
, args
->sattr
);
1132 encode_specdata3(xdr
, args
->rdev
);
1135 static void encode_mknoddata3(struct xdr_stream
*xdr
,
1136 const struct nfs3_mknodargs
*args
)
1138 encode_ftype3(xdr
, args
->type
);
1139 switch (args
->type
) {
1142 encode_devicedata3(xdr
, args
);
1146 encode_sattr3(xdr
, args
->sattr
);
1156 static void nfs3_xdr_enc_mknod3args(struct rpc_rqst
*req
,
1157 struct xdr_stream
*xdr
,
1158 const struct nfs3_mknodargs
*args
)
1160 encode_diropargs3(xdr
, args
->fh
, args
->name
, args
->len
);
1161 encode_mknoddata3(xdr
, args
);
1165 * 3.3.12 REMOVE3args
1167 * struct REMOVE3args {
1168 * diropargs3 object;
1171 static void nfs3_xdr_enc_remove3args(struct rpc_rqst
*req
,
1172 struct xdr_stream
*xdr
,
1173 const struct nfs_removeargs
*args
)
1175 encode_diropargs3(xdr
, args
->fh
, args
->name
.name
, args
->name
.len
);
1179 * 3.3.14 RENAME3args
1181 * struct RENAME3args {
1186 static void nfs3_xdr_enc_rename3args(struct rpc_rqst
*req
,
1187 struct xdr_stream
*xdr
,
1188 const struct nfs_renameargs
*args
)
1190 const struct qstr
*old
= args
->old_name
;
1191 const struct qstr
*new = args
->new_name
;
1193 encode_diropargs3(xdr
, args
->old_dir
, old
->name
, old
->len
);
1194 encode_diropargs3(xdr
, args
->new_dir
, new->name
, new->len
);
1200 * struct LINK3args {
1205 static void nfs3_xdr_enc_link3args(struct rpc_rqst
*req
,
1206 struct xdr_stream
*xdr
,
1207 const struct nfs3_linkargs
*args
)
1209 encode_nfs_fh3(xdr
, args
->fromfh
);
1210 encode_diropargs3(xdr
, args
->tofh
, args
->toname
, args
->tolen
);
1214 * 3.3.16 READDIR3args
1216 * struct READDIR3args {
1219 * cookieverf3 cookieverf;
1223 static void encode_readdir3args(struct xdr_stream
*xdr
,
1224 const struct nfs3_readdirargs
*args
)
1228 encode_nfs_fh3(xdr
, args
->fh
);
1230 p
= xdr_reserve_space(xdr
, 8 + NFS3_COOKIEVERFSIZE
+ 4);
1231 p
= xdr_encode_cookie3(p
, args
->cookie
);
1232 p
= xdr_encode_cookieverf3(p
, args
->verf
);
1233 *p
= cpu_to_be32(args
->count
);
1236 static void nfs3_xdr_enc_readdir3args(struct rpc_rqst
*req
,
1237 struct xdr_stream
*xdr
,
1238 const struct nfs3_readdirargs
*args
)
1240 encode_readdir3args(xdr
, args
);
1241 prepare_reply_buffer(req
, args
->pages
, 0,
1242 args
->count
, NFS3_readdirres_sz
);
1246 * 3.3.17 READDIRPLUS3args
1248 * struct READDIRPLUS3args {
1251 * cookieverf3 cookieverf;
1256 static void encode_readdirplus3args(struct xdr_stream
*xdr
,
1257 const struct nfs3_readdirargs
*args
)
1261 encode_nfs_fh3(xdr
, args
->fh
);
1263 p
= xdr_reserve_space(xdr
, 8 + NFS3_COOKIEVERFSIZE
+ 4 + 4);
1264 p
= xdr_encode_cookie3(p
, args
->cookie
);
1265 p
= xdr_encode_cookieverf3(p
, args
->verf
);
1268 * readdirplus: need dircount + buffer size.
1269 * We just make sure we make dircount big enough
1271 *p
++ = cpu_to_be32(args
->count
>> 3);
1273 *p
= cpu_to_be32(args
->count
);
1276 static void nfs3_xdr_enc_readdirplus3args(struct rpc_rqst
*req
,
1277 struct xdr_stream
*xdr
,
1278 const struct nfs3_readdirargs
*args
)
1280 encode_readdirplus3args(xdr
, args
);
1281 prepare_reply_buffer(req
, args
->pages
, 0,
1282 args
->count
, NFS3_readdirres_sz
);
1286 * 3.3.21 COMMIT3args
1288 * struct COMMIT3args {
1294 static void encode_commit3args(struct xdr_stream
*xdr
,
1295 const struct nfs_commitargs
*args
)
1299 encode_nfs_fh3(xdr
, args
->fh
);
1301 p
= xdr_reserve_space(xdr
, 8 + 4);
1302 p
= xdr_encode_hyper(p
, args
->offset
);
1303 *p
= cpu_to_be32(args
->count
);
1306 static void nfs3_xdr_enc_commit3args(struct rpc_rqst
*req
,
1307 struct xdr_stream
*xdr
,
1308 const struct nfs_commitargs
*args
)
1310 encode_commit3args(xdr
, args
);
1313 #ifdef CONFIG_NFS_V3_ACL
1315 static void nfs3_xdr_enc_getacl3args(struct rpc_rqst
*req
,
1316 struct xdr_stream
*xdr
,
1317 const struct nfs3_getaclargs
*args
)
1319 encode_nfs_fh3(xdr
, args
->fh
);
1320 encode_uint32(xdr
, args
->mask
);
1321 if (args
->mask
& (NFS_ACL
| NFS_DFACL
))
1322 prepare_reply_buffer(req
, args
->pages
, 0,
1323 NFSACL_MAXPAGES
<< PAGE_SHIFT
,
1327 static void nfs3_xdr_enc_setacl3args(struct rpc_rqst
*req
,
1328 struct xdr_stream
*xdr
,
1329 const struct nfs3_setaclargs
*args
)
1334 encode_nfs_fh3(xdr
, NFS_FH(args
->inode
));
1335 encode_uint32(xdr
, args
->mask
);
1337 base
= req
->rq_slen
;
1338 if (args
->npages
!= 0)
1339 xdr_write_pages(xdr
, args
->pages
, 0, args
->len
);
1341 xdr_reserve_space(xdr
, NFS_ACL_INLINE_BUFSIZE
);
1343 error
= nfsacl_encode(xdr
->buf
, base
, args
->inode
,
1344 (args
->mask
& NFS_ACL
) ?
1345 args
->acl_access
: NULL
, 1, 0);
1347 error
= nfsacl_encode(xdr
->buf
, base
+ error
, args
->inode
,
1348 (args
->mask
& NFS_DFACL
) ?
1349 args
->acl_default
: NULL
, 1,
1354 #endif /* CONFIG_NFS_V3_ACL */
1357 * NFSv3 XDR decode functions
1359 * NFSv3 result types are defined in section 3.3 of RFC 1813:
1360 * "NFS Version 3 Protocol Specification".
1366 * struct GETATTR3resok {
1367 * fattr3 obj_attributes;
1370 * union GETATTR3res switch (nfsstat3 status) {
1372 * GETATTR3resok resok;
1377 static int nfs3_xdr_dec_getattr3res(struct rpc_rqst
*req
,
1378 struct xdr_stream
*xdr
,
1379 struct nfs_fattr
*result
)
1381 enum nfs_stat status
;
1384 error
= decode_nfsstat3(xdr
, &status
);
1385 if (unlikely(error
))
1387 if (status
!= NFS3_OK
)
1389 error
= decode_fattr3(xdr
, result
);
1393 return nfs3_stat_to_errno(status
);
1399 * struct SETATTR3resok {
1403 * struct SETATTR3resfail {
1407 * union SETATTR3res switch (nfsstat3 status) {
1409 * SETATTR3resok resok;
1411 * SETATTR3resfail resfail;
1414 static int nfs3_xdr_dec_setattr3res(struct rpc_rqst
*req
,
1415 struct xdr_stream
*xdr
,
1416 struct nfs_fattr
*result
)
1418 enum nfs_stat status
;
1421 error
= decode_nfsstat3(xdr
, &status
);
1422 if (unlikely(error
))
1424 error
= decode_wcc_data(xdr
, result
);
1425 if (unlikely(error
))
1427 if (status
!= NFS3_OK
)
1432 return nfs3_stat_to_errno(status
);
1438 * struct LOOKUP3resok {
1440 * post_op_attr obj_attributes;
1441 * post_op_attr dir_attributes;
1444 * struct LOOKUP3resfail {
1445 * post_op_attr dir_attributes;
1448 * union LOOKUP3res switch (nfsstat3 status) {
1450 * LOOKUP3resok resok;
1452 * LOOKUP3resfail resfail;
1455 static int nfs3_xdr_dec_lookup3res(struct rpc_rqst
*req
,
1456 struct xdr_stream
*xdr
,
1457 struct nfs3_diropres
*result
)
1459 enum nfs_stat status
;
1462 error
= decode_nfsstat3(xdr
, &status
);
1463 if (unlikely(error
))
1465 if (status
!= NFS3_OK
)
1467 error
= decode_nfs_fh3(xdr
, result
->fh
);
1468 if (unlikely(error
))
1470 error
= decode_post_op_attr(xdr
, result
->fattr
);
1471 if (unlikely(error
))
1473 error
= decode_post_op_attr(xdr
, result
->dir_attr
);
1477 error
= decode_post_op_attr(xdr
, result
->dir_attr
);
1478 if (unlikely(error
))
1480 return nfs3_stat_to_errno(status
);
1486 * struct ACCESS3resok {
1487 * post_op_attr obj_attributes;
1491 * struct ACCESS3resfail {
1492 * post_op_attr obj_attributes;
1495 * union ACCESS3res switch (nfsstat3 status) {
1497 * ACCESS3resok resok;
1499 * ACCESS3resfail resfail;
1502 static int nfs3_xdr_dec_access3res(struct rpc_rqst
*req
,
1503 struct xdr_stream
*xdr
,
1504 struct nfs3_accessres
*result
)
1506 enum nfs_stat status
;
1509 error
= decode_nfsstat3(xdr
, &status
);
1510 if (unlikely(error
))
1512 error
= decode_post_op_attr(xdr
, result
->fattr
);
1513 if (unlikely(error
))
1515 if (status
!= NFS3_OK
)
1517 error
= decode_uint32(xdr
, &result
->access
);
1521 return nfs3_stat_to_errno(status
);
1525 * 3.3.5 READLINK3res
1527 * struct READLINK3resok {
1528 * post_op_attr symlink_attributes;
1532 * struct READLINK3resfail {
1533 * post_op_attr symlink_attributes;
1536 * union READLINK3res switch (nfsstat3 status) {
1538 * READLINK3resok resok;
1540 * READLINK3resfail resfail;
1543 static int nfs3_xdr_dec_readlink3res(struct rpc_rqst
*req
,
1544 struct xdr_stream
*xdr
,
1545 struct nfs_fattr
*result
)
1547 enum nfs_stat status
;
1550 error
= decode_nfsstat3(xdr
, &status
);
1551 if (unlikely(error
))
1553 error
= decode_post_op_attr(xdr
, result
);
1554 if (unlikely(error
))
1556 if (status
!= NFS3_OK
)
1558 error
= decode_nfspath3(xdr
);
1562 return nfs3_stat_to_errno(status
);
1568 * struct READ3resok {
1569 * post_op_attr file_attributes;
1575 * struct READ3resfail {
1576 * post_op_attr file_attributes;
1579 * union READ3res switch (nfsstat3 status) {
1583 * READ3resfail resfail;
1586 static int decode_read3resok(struct xdr_stream
*xdr
,
1587 struct nfs_readres
*result
)
1589 u32 eof
, count
, ocount
, recvd
;
1593 p
= xdr_inline_decode(xdr
, 4 + 4 + 4);
1594 if (unlikely(p
== NULL
))
1596 count
= be32_to_cpup(p
++);
1597 eof
= be32_to_cpup(p
++);
1598 ocount
= be32_to_cpup(p
++);
1599 if (unlikely(ocount
!= count
))
1601 hdrlen
= (u8
*)xdr
->p
- (u8
*)xdr
->iov
->iov_base
;
1602 recvd
= xdr
->buf
->len
- hdrlen
;
1603 if (unlikely(count
> recvd
))
1607 xdr_read_pages(xdr
, count
);
1609 result
->count
= count
;
1612 dprintk("NFS: READ count doesn't match length of opaque: "
1613 "count %u != ocount %u\n", count
, ocount
);
1616 dprintk("NFS: server cheating in read result: "
1617 "count %u > recvd %u\n", count
, recvd
);
1622 print_overflow_msg(__func__
, xdr
);
1626 static int nfs3_xdr_dec_read3res(struct rpc_rqst
*req
, struct xdr_stream
*xdr
,
1627 struct nfs_readres
*result
)
1629 enum nfs_stat status
;
1632 error
= decode_nfsstat3(xdr
, &status
);
1633 if (unlikely(error
))
1635 error
= decode_post_op_attr(xdr
, result
->fattr
);
1636 if (unlikely(error
))
1638 if (status
!= NFS3_OK
)
1640 error
= decode_read3resok(xdr
, result
);
1644 return nfs3_stat_to_errno(status
);
1656 * struct WRITE3resok {
1657 * wcc_data file_wcc;
1659 * stable_how committed;
1663 * struct WRITE3resfail {
1664 * wcc_data file_wcc;
1667 * union WRITE3res switch (nfsstat3 status) {
1669 * WRITE3resok resok;
1671 * WRITE3resfail resfail;
1674 static int decode_write3resok(struct xdr_stream
*xdr
,
1675 struct nfs_writeres
*result
)
1679 p
= xdr_inline_decode(xdr
, 4 + 4 + NFS3_WRITEVERFSIZE
);
1680 if (unlikely(p
== NULL
))
1682 result
->count
= be32_to_cpup(p
++);
1683 result
->verf
->committed
= be32_to_cpup(p
++);
1684 if (unlikely(result
->verf
->committed
> NFS_FILE_SYNC
))
1686 memcpy(result
->verf
->verifier
, p
, NFS3_WRITEVERFSIZE
);
1687 return result
->count
;
1689 dprintk("NFS: bad stable_how value: %u\n", result
->verf
->committed
);
1692 print_overflow_msg(__func__
, xdr
);
1696 static int nfs3_xdr_dec_write3res(struct rpc_rqst
*req
, struct xdr_stream
*xdr
,
1697 struct nfs_writeres
*result
)
1699 enum nfs_stat status
;
1702 error
= decode_nfsstat3(xdr
, &status
);
1703 if (unlikely(error
))
1705 error
= decode_wcc_data(xdr
, result
->fattr
);
1706 if (unlikely(error
))
1708 if (status
!= NFS3_OK
)
1710 error
= decode_write3resok(xdr
, result
);
1714 return nfs3_stat_to_errno(status
);
1720 * struct CREATE3resok {
1722 * post_op_attr obj_attributes;
1726 * struct CREATE3resfail {
1730 * union CREATE3res switch (nfsstat3 status) {
1732 * CREATE3resok resok;
1734 * CREATE3resfail resfail;
1737 static int decode_create3resok(struct xdr_stream
*xdr
,
1738 struct nfs3_diropres
*result
)
1742 error
= decode_post_op_fh3(xdr
, result
->fh
);
1743 if (unlikely(error
))
1745 error
= decode_post_op_attr(xdr
, result
->fattr
);
1746 if (unlikely(error
))
1748 /* The server isn't required to return a file handle.
1749 * If it didn't, force the client to perform a LOOKUP
1750 * to determine the correct file handle and attribute
1751 * values for the new object. */
1752 if (result
->fh
->size
== 0)
1753 result
->fattr
->valid
= 0;
1754 error
= decode_wcc_data(xdr
, result
->dir_attr
);
1759 static int nfs3_xdr_dec_create3res(struct rpc_rqst
*req
,
1760 struct xdr_stream
*xdr
,
1761 struct nfs3_diropres
*result
)
1763 enum nfs_stat status
;
1766 error
= decode_nfsstat3(xdr
, &status
);
1767 if (unlikely(error
))
1769 if (status
!= NFS3_OK
)
1771 error
= decode_create3resok(xdr
, result
);
1775 error
= decode_wcc_data(xdr
, result
->dir_attr
);
1776 if (unlikely(error
))
1778 return nfs3_stat_to_errno(status
);
1784 * struct REMOVE3resok {
1788 * struct REMOVE3resfail {
1792 * union REMOVE3res switch (nfsstat3 status) {
1794 * REMOVE3resok resok;
1796 * REMOVE3resfail resfail;
1799 static int nfs3_xdr_dec_remove3res(struct rpc_rqst
*req
,
1800 struct xdr_stream
*xdr
,
1801 struct nfs_removeres
*result
)
1803 enum nfs_stat status
;
1806 error
= decode_nfsstat3(xdr
, &status
);
1807 if (unlikely(error
))
1809 error
= decode_wcc_data(xdr
, result
->dir_attr
);
1810 if (unlikely(error
))
1812 if (status
!= NFS3_OK
)
1817 return nfs3_stat_to_errno(status
);
1823 * struct RENAME3resok {
1824 * wcc_data fromdir_wcc;
1825 * wcc_data todir_wcc;
1828 * struct RENAME3resfail {
1829 * wcc_data fromdir_wcc;
1830 * wcc_data todir_wcc;
1833 * union RENAME3res switch (nfsstat3 status) {
1835 * RENAME3resok resok;
1837 * RENAME3resfail resfail;
1840 static int nfs3_xdr_dec_rename3res(struct rpc_rqst
*req
,
1841 struct xdr_stream
*xdr
,
1842 struct nfs_renameres
*result
)
1844 enum nfs_stat status
;
1847 error
= decode_nfsstat3(xdr
, &status
);
1848 if (unlikely(error
))
1850 error
= decode_wcc_data(xdr
, result
->old_fattr
);
1851 if (unlikely(error
))
1853 error
= decode_wcc_data(xdr
, result
->new_fattr
);
1854 if (unlikely(error
))
1856 if (status
!= NFS3_OK
)
1861 return nfs3_stat_to_errno(status
);
1867 * struct LINK3resok {
1868 * post_op_attr file_attributes;
1869 * wcc_data linkdir_wcc;
1872 * struct LINK3resfail {
1873 * post_op_attr file_attributes;
1874 * wcc_data linkdir_wcc;
1877 * union LINK3res switch (nfsstat3 status) {
1881 * LINK3resfail resfail;
1884 static int nfs3_xdr_dec_link3res(struct rpc_rqst
*req
, struct xdr_stream
*xdr
,
1885 struct nfs3_linkres
*result
)
1887 enum nfs_stat status
;
1890 error
= decode_nfsstat3(xdr
, &status
);
1891 if (unlikely(error
))
1893 error
= decode_post_op_attr(xdr
, result
->fattr
);
1894 if (unlikely(error
))
1896 error
= decode_wcc_data(xdr
, result
->dir_attr
);
1897 if (unlikely(error
))
1899 if (status
!= NFS3_OK
)
1904 return nfs3_stat_to_errno(status
);
1908 * nfs3_decode_dirent - Decode a single NFSv3 directory entry stored in
1909 * the local page cache
1910 * @xdr: XDR stream where entry resides
1911 * @entry: buffer to fill in with entry data
1912 * @plus: boolean indicating whether this should be a readdirplus entry
1914 * Returns zero if successful, otherwise a negative errno value is
1917 * This function is not invoked during READDIR reply decoding, but
1918 * rather whenever an application invokes the getdents(2) system call
1919 * on a directory already in our cache.
1927 * fhandle3 filehandle;
1928 * post_op_attr3 attributes;
1929 * entry3 *nextentry;
1933 * struct entryplus3 {
1937 * post_op_attr name_attributes;
1938 * post_op_fh3 name_handle;
1939 * entryplus3 *nextentry;
1942 int nfs3_decode_dirent(struct xdr_stream
*xdr
, struct nfs_entry
*entry
,
1945 struct nfs_entry old
= *entry
;
1949 p
= xdr_inline_decode(xdr
, 4);
1950 if (unlikely(p
== NULL
))
1952 if (*p
== xdr_zero
) {
1953 p
= xdr_inline_decode(xdr
, 4);
1954 if (unlikely(p
== NULL
))
1962 error
= decode_fileid3(xdr
, &entry
->ino
);
1963 if (unlikely(error
))
1966 error
= decode_inline_filename3(xdr
, &entry
->name
, &entry
->len
);
1967 if (unlikely(error
))
1970 entry
->prev_cookie
= entry
->cookie
;
1971 error
= decode_cookie3(xdr
, &entry
->cookie
);
1972 if (unlikely(error
))
1975 entry
->d_type
= DT_UNKNOWN
;
1978 entry
->fattr
->valid
= 0;
1979 error
= decode_post_op_attr(xdr
, entry
->fattr
);
1980 if (unlikely(error
))
1982 if (entry
->fattr
->valid
& NFS_ATTR_FATTR_V3
)
1983 entry
->d_type
= nfs_umode_to_dtype(entry
->fattr
->mode
);
1985 /* In fact, a post_op_fh3: */
1986 p
= xdr_inline_decode(xdr
, 4);
1987 if (unlikely(p
== NULL
))
1989 if (*p
!= xdr_zero
) {
1990 error
= decode_nfs_fh3(xdr
, entry
->fh
);
1991 if (unlikely(error
)) {
1992 if (error
== -E2BIG
)
1997 zero_nfs_fh3(entry
->fh
);
2003 print_overflow_msg(__func__
, xdr
);
2006 dprintk("NFS: directory entry contains invalid file handle\n");
2012 * 3.3.16 READDIR3res
2019 * struct READDIR3resok {
2020 * post_op_attr dir_attributes;
2021 * cookieverf3 cookieverf;
2025 * struct READDIR3resfail {
2026 * post_op_attr dir_attributes;
2029 * union READDIR3res switch (nfsstat3 status) {
2031 * READDIR3resok resok;
2033 * READDIR3resfail resfail;
2036 * Read the directory contents into the page cache, but otherwise
2037 * don't touch them. The actual decoding is done by nfs3_decode_entry()
2038 * during subsequent nfs_readdir() calls.
2040 static int decode_dirlist3(struct xdr_stream
*xdr
)
2045 pglen
= xdr
->buf
->page_len
;
2046 hdrlen
= (u8
*)xdr
->p
- (u8
*)xdr
->iov
->iov_base
;
2047 recvd
= xdr
->buf
->len
- hdrlen
;
2048 if (unlikely(pglen
> recvd
))
2051 xdr_read_pages(xdr
, pglen
);
2054 dprintk("NFS: server cheating in readdir result: "
2055 "pglen %u > recvd %u\n", pglen
, recvd
);
2060 static int decode_readdir3resok(struct xdr_stream
*xdr
,
2061 struct nfs3_readdirres
*result
)
2065 error
= decode_post_op_attr(xdr
, result
->dir_attr
);
2066 if (unlikely(error
))
2068 /* XXX: do we need to check if result->verf != NULL ? */
2069 error
= decode_cookieverf3(xdr
, result
->verf
);
2070 if (unlikely(error
))
2072 error
= decode_dirlist3(xdr
);
2077 static int nfs3_xdr_dec_readdir3res(struct rpc_rqst
*req
,
2078 struct xdr_stream
*xdr
,
2079 struct nfs3_readdirres
*result
)
2081 enum nfs_stat status
;
2084 error
= decode_nfsstat3(xdr
, &status
);
2085 if (unlikely(error
))
2087 if (status
!= NFS3_OK
)
2089 error
= decode_readdir3resok(xdr
, result
);
2093 error
= decode_post_op_attr(xdr
, result
->dir_attr
);
2094 if (unlikely(error
))
2096 return nfs3_stat_to_errno(status
);
2102 * struct FSSTAT3resok {
2103 * post_op_attr obj_attributes;
2113 * struct FSSTAT3resfail {
2114 * post_op_attr obj_attributes;
2117 * union FSSTAT3res switch (nfsstat3 status) {
2119 * FSSTAT3resok resok;
2121 * FSSTAT3resfail resfail;
2124 static int decode_fsstat3resok(struct xdr_stream
*xdr
,
2125 struct nfs_fsstat
*result
)
2129 p
= xdr_inline_decode(xdr
, 8 * 6 + 4);
2130 if (unlikely(p
== NULL
))
2132 p
= xdr_decode_size3(p
, &result
->tbytes
);
2133 p
= xdr_decode_size3(p
, &result
->fbytes
);
2134 p
= xdr_decode_size3(p
, &result
->abytes
);
2135 p
= xdr_decode_size3(p
, &result
->tfiles
);
2136 p
= xdr_decode_size3(p
, &result
->ffiles
);
2137 xdr_decode_size3(p
, &result
->afiles
);
2138 /* ignore invarsec */
2141 print_overflow_msg(__func__
, xdr
);
2145 static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst
*req
,
2146 struct xdr_stream
*xdr
,
2147 struct nfs_fsstat
*result
)
2149 enum nfs_stat status
;
2152 error
= decode_nfsstat3(xdr
, &status
);
2153 if (unlikely(error
))
2155 error
= decode_post_op_attr(xdr
, result
->fattr
);
2156 if (unlikely(error
))
2158 if (status
!= NFS3_OK
)
2160 error
= decode_fsstat3resok(xdr
, result
);
2164 return nfs3_stat_to_errno(status
);
2170 * struct FSINFO3resok {
2171 * post_op_attr obj_attributes;
2179 * size3 maxfilesize;
2180 * nfstime3 time_delta;
2181 * uint32 properties;
2184 * struct FSINFO3resfail {
2185 * post_op_attr obj_attributes;
2188 * union FSINFO3res switch (nfsstat3 status) {
2190 * FSINFO3resok resok;
2192 * FSINFO3resfail resfail;
2195 static int decode_fsinfo3resok(struct xdr_stream
*xdr
,
2196 struct nfs_fsinfo
*result
)
2200 p
= xdr_inline_decode(xdr
, 4 * 7 + 8 + 8 + 4);
2201 if (unlikely(p
== NULL
))
2203 result
->rtmax
= be32_to_cpup(p
++);
2204 result
->rtpref
= be32_to_cpup(p
++);
2205 result
->rtmult
= be32_to_cpup(p
++);
2206 result
->wtmax
= be32_to_cpup(p
++);
2207 result
->wtpref
= be32_to_cpup(p
++);
2208 result
->wtmult
= be32_to_cpup(p
++);
2209 result
->dtpref
= be32_to_cpup(p
++);
2210 p
= xdr_decode_size3(p
, &result
->maxfilesize
);
2211 xdr_decode_nfstime3(p
, &result
->time_delta
);
2213 /* ignore properties */
2214 result
->lease_time
= 0;
2217 print_overflow_msg(__func__
, xdr
);
2221 static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst
*req
,
2222 struct xdr_stream
*xdr
,
2223 struct nfs_fsinfo
*result
)
2225 enum nfs_stat status
;
2228 error
= decode_nfsstat3(xdr
, &status
);
2229 if (unlikely(error
))
2231 error
= decode_post_op_attr(xdr
, result
->fattr
);
2232 if (unlikely(error
))
2234 if (status
!= NFS3_OK
)
2236 error
= decode_fsinfo3resok(xdr
, result
);
2240 return nfs3_stat_to_errno(status
);
2244 * 3.3.20 PATHCONF3res
2246 * struct PATHCONF3resok {
2247 * post_op_attr obj_attributes;
2251 * bool chown_restricted;
2252 * bool case_insensitive;
2253 * bool case_preserving;
2256 * struct PATHCONF3resfail {
2257 * post_op_attr obj_attributes;
2260 * union PATHCONF3res switch (nfsstat3 status) {
2262 * PATHCONF3resok resok;
2264 * PATHCONF3resfail resfail;
2267 static int decode_pathconf3resok(struct xdr_stream
*xdr
,
2268 struct nfs_pathconf
*result
)
2272 p
= xdr_inline_decode(xdr
, 4 * 6);
2273 if (unlikely(p
== NULL
))
2275 result
->max_link
= be32_to_cpup(p
++);
2276 result
->max_namelen
= be32_to_cpup(p
);
2277 /* ignore remaining fields */
2280 print_overflow_msg(__func__
, xdr
);
2284 static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst
*req
,
2285 struct xdr_stream
*xdr
,
2286 struct nfs_pathconf
*result
)
2288 enum nfs_stat status
;
2291 error
= decode_nfsstat3(xdr
, &status
);
2292 if (unlikely(error
))
2294 error
= decode_post_op_attr(xdr
, result
->fattr
);
2295 if (unlikely(error
))
2297 if (status
!= NFS3_OK
)
2299 error
= decode_pathconf3resok(xdr
, result
);
2303 return nfs3_stat_to_errno(status
);
2309 * struct COMMIT3resok {
2310 * wcc_data file_wcc;
2314 * struct COMMIT3resfail {
2315 * wcc_data file_wcc;
2318 * union COMMIT3res switch (nfsstat3 status) {
2320 * COMMIT3resok resok;
2322 * COMMIT3resfail resfail;
2325 static int nfs3_xdr_dec_commit3res(struct rpc_rqst
*req
,
2326 struct xdr_stream
*xdr
,
2327 struct nfs_commitres
*result
)
2329 enum nfs_stat status
;
2332 error
= decode_nfsstat3(xdr
, &status
);
2333 if (unlikely(error
))
2335 error
= decode_wcc_data(xdr
, result
->fattr
);
2336 if (unlikely(error
))
2338 if (status
!= NFS3_OK
)
2340 error
= decode_writeverf3(xdr
, result
->verf
->verifier
);
2344 return nfs3_stat_to_errno(status
);
2347 #ifdef CONFIG_NFS_V3_ACL
2349 static inline int decode_getacl3resok(struct xdr_stream
*xdr
,
2350 struct nfs3_getaclres
*result
)
2352 struct posix_acl
**acl
;
2353 unsigned int *aclcnt
;
2357 error
= decode_post_op_attr(xdr
, result
->fattr
);
2358 if (unlikely(error
))
2360 error
= decode_uint32(xdr
, &result
->mask
);
2361 if (unlikely(error
))
2364 if (result
->mask
& ~(NFS_ACL
|NFS_ACLCNT
|NFS_DFACL
|NFS_DFACLCNT
))
2367 hdrlen
= (u8
*)xdr
->p
- (u8
*)xdr
->iov
->iov_base
;
2370 if (result
->mask
& NFS_ACL
)
2371 acl
= &result
->acl_access
;
2373 if (result
->mask
& NFS_ACLCNT
)
2374 aclcnt
= &result
->acl_access_count
;
2375 error
= nfsacl_decode(xdr
->buf
, hdrlen
, aclcnt
, acl
);
2376 if (unlikely(error
<= 0))
2380 if (result
->mask
& NFS_DFACL
)
2381 acl
= &result
->acl_default
;
2383 if (result
->mask
& NFS_DFACLCNT
)
2384 aclcnt
= &result
->acl_default_count
;
2385 error
= nfsacl_decode(xdr
->buf
, hdrlen
+ error
, aclcnt
, acl
);
2386 if (unlikely(error
<= 0))
2393 static int nfs3_xdr_dec_getacl3res(struct rpc_rqst
*req
,
2394 struct xdr_stream
*xdr
,
2395 struct nfs3_getaclres
*result
)
2397 enum nfs_stat status
;
2400 error
= decode_nfsstat3(xdr
, &status
);
2401 if (unlikely(error
))
2403 if (status
!= NFS3_OK
)
2405 error
= decode_getacl3resok(xdr
, result
);
2409 return nfs3_stat_to_errno(status
);
2412 static int nfs3_xdr_dec_setacl3res(struct rpc_rqst
*req
,
2413 struct xdr_stream
*xdr
,
2414 struct nfs_fattr
*result
)
2416 enum nfs_stat status
;
2419 error
= decode_nfsstat3(xdr
, &status
);
2420 if (unlikely(error
))
2422 if (status
!= NFS3_OK
)
2424 error
= decode_post_op_attr(xdr
, result
);
2428 return nfs3_stat_to_errno(status
);
2431 #endif /* CONFIG_NFS_V3_ACL */
2435 * We need to translate between nfs status return values and
2436 * the local errno values which may not be the same.
2438 static const struct {
2443 { NFSERR_PERM
, -EPERM
},
2444 { NFSERR_NOENT
, -ENOENT
},
2445 { NFSERR_IO
, -errno_NFSERR_IO
},
2446 { NFSERR_NXIO
, -ENXIO
},
2447 /* { NFSERR_EAGAIN, -EAGAIN }, */
2448 { NFSERR_ACCES
, -EACCES
},
2449 { NFSERR_EXIST
, -EEXIST
},
2450 { NFSERR_XDEV
, -EXDEV
},
2451 { NFSERR_NODEV
, -ENODEV
},
2452 { NFSERR_NOTDIR
, -ENOTDIR
},
2453 { NFSERR_ISDIR
, -EISDIR
},
2454 { NFSERR_INVAL
, -EINVAL
},
2455 { NFSERR_FBIG
, -EFBIG
},
2456 { NFSERR_NOSPC
, -ENOSPC
},
2457 { NFSERR_ROFS
, -EROFS
},
2458 { NFSERR_MLINK
, -EMLINK
},
2459 { NFSERR_NAMETOOLONG
, -ENAMETOOLONG
},
2460 { NFSERR_NOTEMPTY
, -ENOTEMPTY
},
2461 { NFSERR_DQUOT
, -EDQUOT
},
2462 { NFSERR_STALE
, -ESTALE
},
2463 { NFSERR_REMOTE
, -EREMOTE
},
2465 { NFSERR_WFLUSH
, -EWFLUSH
},
2467 { NFSERR_BADHANDLE
, -EBADHANDLE
},
2468 { NFSERR_NOT_SYNC
, -ENOTSYNC
},
2469 { NFSERR_BAD_COOKIE
, -EBADCOOKIE
},
2470 { NFSERR_NOTSUPP
, -ENOTSUPP
},
2471 { NFSERR_TOOSMALL
, -ETOOSMALL
},
2472 { NFSERR_SERVERFAULT
, -EREMOTEIO
},
2473 { NFSERR_BADTYPE
, -EBADTYPE
},
2474 { NFSERR_JUKEBOX
, -EJUKEBOX
},
2479 * nfs3_stat_to_errno - convert an NFS status code to a local errno
2480 * @status: NFS status code to convert
2482 * Returns a local errno value, or -EIO if the NFS status code is
2483 * not recognized. This function is used jointly by NFSv2 and NFSv3.
2485 static int nfs3_stat_to_errno(enum nfs_stat status
)
2489 for (i
= 0; nfs_errtbl
[i
].stat
!= -1; i
++) {
2490 if (nfs_errtbl
[i
].stat
== (int)status
)
2491 return nfs_errtbl
[i
].errno
;
2493 dprintk("NFS: Unrecognized nfs status value: %u\n", status
);
2494 return nfs_errtbl
[i
].errno
;
2498 #define PROC(proc, argtype, restype, timer) \
2499 [NFS3PROC_##proc] = { \
2500 .p_proc = NFS3PROC_##proc, \
2501 .p_encode = (kxdreproc_t)nfs3_xdr_enc_##argtype##3args, \
2502 .p_decode = (kxdrdproc_t)nfs3_xdr_dec_##restype##3res, \
2503 .p_arglen = NFS3_##argtype##args_sz, \
2504 .p_replen = NFS3_##restype##res_sz, \
2506 .p_statidx = NFS3PROC_##proc, \
2510 struct rpc_procinfo nfs3_procedures
[] = {
2511 PROC(GETATTR
, getattr
, getattr
, 1),
2512 PROC(SETATTR
, setattr
, setattr
, 0),
2513 PROC(LOOKUP
, lookup
, lookup
, 2),
2514 PROC(ACCESS
, access
, access
, 1),
2515 PROC(READLINK
, readlink
, readlink
, 3),
2516 PROC(READ
, read
, read
, 3),
2517 PROC(WRITE
, write
, write
, 4),
2518 PROC(CREATE
, create
, create
, 0),
2519 PROC(MKDIR
, mkdir
, create
, 0),
2520 PROC(SYMLINK
, symlink
, create
, 0),
2521 PROC(MKNOD
, mknod
, create
, 0),
2522 PROC(REMOVE
, remove
, remove
, 0),
2523 PROC(RMDIR
, lookup
, setattr
, 0),
2524 PROC(RENAME
, rename
, rename
, 0),
2525 PROC(LINK
, link
, link
, 0),
2526 PROC(READDIR
, readdir
, readdir
, 3),
2527 PROC(READDIRPLUS
, readdirplus
, readdir
, 3),
2528 PROC(FSSTAT
, getattr
, fsstat
, 0),
2529 PROC(FSINFO
, getattr
, fsinfo
, 0),
2530 PROC(PATHCONF
, getattr
, pathconf
, 0),
2531 PROC(COMMIT
, commit
, commit
, 5),
2534 const struct rpc_version nfs_version3
= {
2536 .nrprocs
= ARRAY_SIZE(nfs3_procedures
),
2537 .procs
= nfs3_procedures
2540 #ifdef CONFIG_NFS_V3_ACL
2541 static struct rpc_procinfo nfs3_acl_procedures
[] = {
2542 [ACLPROC3_GETACL
] = {
2543 .p_proc
= ACLPROC3_GETACL
,
2544 .p_encode
= (kxdreproc_t
)nfs3_xdr_enc_getacl3args
,
2545 .p_decode
= (kxdrdproc_t
)nfs3_xdr_dec_getacl3res
,
2546 .p_arglen
= ACL3_getaclargs_sz
,
2547 .p_replen
= ACL3_getaclres_sz
,
2551 [ACLPROC3_SETACL
] = {
2552 .p_proc
= ACLPROC3_SETACL
,
2553 .p_encode
= (kxdreproc_t
)nfs3_xdr_enc_setacl3args
,
2554 .p_decode
= (kxdrdproc_t
)nfs3_xdr_dec_setacl3res
,
2555 .p_arglen
= ACL3_setaclargs_sz
,
2556 .p_replen
= ACL3_setaclres_sz
,
2562 const struct rpc_version nfsacl_version3
= {
2564 .nrprocs
= sizeof(nfs3_acl_procedures
)/
2565 sizeof(nfs3_acl_procedures
[0]),
2566 .procs
= nfs3_acl_procedures
,
2568 #endif /* CONFIG_NFS_V3_ACL */