aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorYu Zhiguo <yuzg@cn.fujitsu.com>2009-05-16 04:22:31 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2009-06-01 18:01:54 -0400
commit3c8e03166ae234d16e7871f8009638e0946d303c (patch)
tree810556f219d4a98fa1ba71b43ec9c34847b57d93 /fs
parent1dbd0d53f394cd9a86fc801dd68fdbcbcdb45718 (diff)
NFSv4: do exact check about attribute specified
Server should return NFS4ERR_ATTRNOTSUPP if an attribute specified is not supported in current environment. Operations CREATE, NVERIFY, OPEN, SETATTR and VERIFY should do this check. This bug is found when do newpynfs tests. The names of the tests that failed are following: CR12 NVF7a NVF7b NVF7c NVF7d NVF7f NVF7r NVF7s OPEN15 VF7a VF7b VF7c VF7d VF7f VF7r VF7s Add function do_check_fattr() to do exact check: 1, Check attribute specified is supported by the NFSv4 server or not. 2, Check FATTR4_WORD0_ACL & FATTR4_WORD0_FS_LOCATIONS are supported in current environment or not. 3, Check attribute specified is writable or not. step 1 and 3 are done in function nfsd4_decode_fattr() but removed to this function now. Signed-off-by: Yu Zhiguo <yuzg@cn.fujitsu.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/nfs4proc.c95
-rw-r--r--fs/nfsd/nfs4xdr.c46
2 files changed, 103 insertions, 38 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index b2883e9c6381..9272e1f806fc 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -51,6 +51,78 @@
51 51
52#define NFSDDBG_FACILITY NFSDDBG_PROC 52#define NFSDDBG_FACILITY NFSDDBG_PROC
53 53
54static u32 nfsd_attrmask[] = {
55 NFSD_WRITEABLE_ATTRS_WORD0,
56 NFSD_WRITEABLE_ATTRS_WORD1,
57 NFSD_WRITEABLE_ATTRS_WORD2
58};
59
60static u32 nfsd41_ex_attrmask[] = {
61 NFSD_SUPPATTR_EXCLCREAT_WORD0,
62 NFSD_SUPPATTR_EXCLCREAT_WORD1,
63 NFSD_SUPPATTR_EXCLCREAT_WORD2
64};
65
66static __be32
67check_attr_support(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
68 u32 *bmval, u32 *writable)
69{
70 struct dentry *dentry = cstate->current_fh.fh_dentry;
71 struct svc_export *exp = cstate->current_fh.fh_export;
72
73 /*
74 * Check about attributes are supported by the NFSv4 server or not.
75 * According to spec, unsupported attributes return ERR_ATTRNOTSUPP.
76 */
77 if ((bmval[0] & ~nfsd_suppattrs0(cstate->minorversion)) ||
78 (bmval[1] & ~nfsd_suppattrs1(cstate->minorversion)) ||
79 (bmval[2] & ~nfsd_suppattrs2(cstate->minorversion)))
80 return nfserr_attrnotsupp;
81
82 /*
83 * Check FATTR4_WORD0_ACL & FATTR4_WORD0_FS_LOCATIONS can be supported
84 * in current environment or not.
85 */
86 if (bmval[0] & FATTR4_WORD0_ACL) {
87 if (!IS_POSIXACL(dentry->d_inode))
88 return nfserr_attrnotsupp;
89 }
90 if (bmval[0] & FATTR4_WORD0_FS_LOCATIONS) {
91 if (exp->ex_fslocs.locations == NULL)
92 return nfserr_attrnotsupp;
93 }
94
95 /*
96 * According to spec, read-only attributes return ERR_INVAL.
97 */
98 if (writable) {
99 if ((bmval[0] & ~writable[0]) || (bmval[1] & ~writable[1]) ||
100 (bmval[2] & ~writable[2]))
101 return nfserr_inval;
102 }
103
104 return nfs_ok;
105}
106
107static __be32
108nfsd4_check_open_attributes(struct svc_rqst *rqstp,
109 struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
110{
111 __be32 status = nfs_ok;
112
113 if (open->op_create == NFS4_OPEN_CREATE) {
114 if (open->op_createmode == NFS4_CREATE_UNCHECKED
115 || open->op_createmode == NFS4_CREATE_GUARDED)
116 status = check_attr_support(rqstp, cstate,
117 open->op_bmval, nfsd_attrmask);
118 else if (open->op_createmode == NFS4_CREATE_EXCLUSIVE4_1)
119 status = check_attr_support(rqstp, cstate,
120 open->op_bmval, nfsd41_ex_attrmask);
121 }
122
123 return status;
124}
125
54static inline void 126static inline void
55fh_dup2(struct svc_fh *dst, struct svc_fh *src) 127fh_dup2(struct svc_fh *dst, struct svc_fh *src)
56{ 128{
@@ -225,6 +297,10 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
225 if (status) 297 if (status)
226 goto out; 298 goto out;
227 299
300 status = nfsd4_check_open_attributes(rqstp, cstate, open);
301 if (status)
302 goto out;
303
228 /* Openowner is now set, so sequence id will get bumped. Now we need 304 /* Openowner is now set, so sequence id will get bumped. Now we need
229 * these checks before we do any creates: */ 305 * these checks before we do any creates: */
230 status = nfserr_grace; 306 status = nfserr_grace;
@@ -395,6 +471,11 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
395 if (status) 471 if (status)
396 return status; 472 return status;
397 473
474 status = check_attr_support(rqstp, cstate, create->cr_bmval,
475 nfsd_attrmask);
476 if (status)
477 return status;
478
398 switch (create->cr_type) { 479 switch (create->cr_type) {
399 case NF4LNK: 480 case NF4LNK:
400 /* ugh! we have to null-terminate the linktext, or 481 /* ugh! we have to null-terminate the linktext, or
@@ -689,6 +770,12 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
689 if (status) 770 if (status)
690 return status; 771 return status;
691 status = nfs_ok; 772 status = nfs_ok;
773
774 status = check_attr_support(rqstp, cstate, setattr->sa_bmval,
775 nfsd_attrmask);
776 if (status)
777 goto out;
778
692 if (setattr->sa_acl != NULL) 779 if (setattr->sa_acl != NULL)
693 status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh, 780 status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh,
694 setattr->sa_acl); 781 setattr->sa_acl);
@@ -763,10 +850,10 @@ _nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
763 if (status) 850 if (status)
764 return status; 851 return status;
765 852
766 if ((verify->ve_bmval[0] & ~nfsd_suppattrs0(cstate->minorversion)) 853 status = check_attr_support(rqstp, cstate, verify->ve_bmval, NULL);
767 || (verify->ve_bmval[1] & ~nfsd_suppattrs1(cstate->minorversion)) 854 if (status)
768 || (verify->ve_bmval[2] & ~nfsd_suppattrs2(cstate->minorversion))) 855 return status;
769 return nfserr_attrnotsupp; 856
770 if ((verify->ve_bmval[0] & FATTR4_WORD0_RDATTR_ERROR) 857 if ((verify->ve_bmval[0] & FATTR4_WORD0_RDATTR_ERROR)
771 || (verify->ve_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1)) 858 || (verify->ve_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1))
772 return nfserr_inval; 859 return nfserr_inval;
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index ab005fc637e1..254e5b21b915 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -244,20 +244,8 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
244 DECODE_TAIL; 244 DECODE_TAIL;
245} 245}
246 246
247static u32 nfsd_attrmask[] = {
248 NFSD_WRITEABLE_ATTRS_WORD0,
249 NFSD_WRITEABLE_ATTRS_WORD1,
250 NFSD_WRITEABLE_ATTRS_WORD2
251};
252
253static u32 nfsd41_ex_attrmask[] = {
254 NFSD_SUPPATTR_EXCLCREAT_WORD0,
255 NFSD_SUPPATTR_EXCLCREAT_WORD1,
256 NFSD_SUPPATTR_EXCLCREAT_WORD2
257};
258
259static __be32 247static __be32
260nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, u32 *writable, 248nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
261 struct iattr *iattr, struct nfs4_acl **acl) 249 struct iattr *iattr, struct nfs4_acl **acl)
262{ 250{
263 int expected_len, len = 0; 251 int expected_len, len = 0;
@@ -270,18 +258,6 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, u32 *writable,
270 if ((status = nfsd4_decode_bitmap(argp, bmval))) 258 if ((status = nfsd4_decode_bitmap(argp, bmval)))
271 return status; 259 return status;
272 260
273 /*
274 * According to spec, unsupported attributes return ERR_ATTRNOTSUPP;
275 * read-only attributes return ERR_INVAL.
276 */
277 if ((bmval[0] & ~nfsd_suppattrs0(argp->minorversion)) ||
278 (bmval[1] & ~nfsd_suppattrs1(argp->minorversion)) ||
279 (bmval[2] & ~nfsd_suppattrs2(argp->minorversion)))
280 return nfserr_attrnotsupp;
281 if ((bmval[0] & ~writable[0]) || (bmval[1] & ~writable[1]) ||
282 (bmval[2] & ~writable[2]))
283 return nfserr_inval;
284
285 READ_BUF(4); 261 READ_BUF(4);
286 READ32(expected_len); 262 READ32(expected_len);
287 263
@@ -414,8 +390,11 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, u32 *writable,
414 goto xdr_error; 390 goto xdr_error;
415 } 391 }
416 } 392 }
417 BUG_ON(bmval[2]); /* no such writeable attr supported yet */ 393 if (bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0
418 if (len != expected_len) 394 || bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1
395 || bmval[2] & ~NFSD_WRITEABLE_ATTRS_WORD2)
396 READ_BUF(expected_len - len);
397 else if (len != expected_len)
419 goto xdr_error; 398 goto xdr_error;
420 399
421 DECODE_TAIL; 400 DECODE_TAIL;
@@ -508,8 +487,8 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
508 if ((status = check_filename(create->cr_name, create->cr_namelen, nfserr_inval))) 487 if ((status = check_filename(create->cr_name, create->cr_namelen, nfserr_inval)))
509 return status; 488 return status;
510 489
511 status = nfsd4_decode_fattr(argp, create->cr_bmval, nfsd_attrmask, 490 status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr,
512 &create->cr_iattr, &create->cr_acl); 491 &create->cr_acl);
513 if (status) 492 if (status)
514 goto out; 493 goto out;
515 494
@@ -672,7 +651,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
672 case NFS4_CREATE_UNCHECKED: 651 case NFS4_CREATE_UNCHECKED:
673 case NFS4_CREATE_GUARDED: 652 case NFS4_CREATE_GUARDED:
674 status = nfsd4_decode_fattr(argp, open->op_bmval, 653 status = nfsd4_decode_fattr(argp, open->op_bmval,
675 nfsd_attrmask, &open->op_iattr, &open->op_acl); 654 &open->op_iattr, &open->op_acl);
676 if (status) 655 if (status)
677 goto out; 656 goto out;
678 break; 657 break;
@@ -686,8 +665,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
686 READ_BUF(8); 665 READ_BUF(8);
687 COPYMEM(open->op_verf.data, 8); 666 COPYMEM(open->op_verf.data, 8);
688 status = nfsd4_decode_fattr(argp, open->op_bmval, 667 status = nfsd4_decode_fattr(argp, open->op_bmval,
689 nfsd41_ex_attrmask, &open->op_iattr, 668 &open->op_iattr, &open->op_acl);
690 &open->op_acl);
691 if (status) 669 if (status)
692 goto out; 670 goto out;
693 break; 671 break;
@@ -883,8 +861,8 @@ nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *seta
883 status = nfsd4_decode_stateid(argp, &setattr->sa_stateid); 861 status = nfsd4_decode_stateid(argp, &setattr->sa_stateid);
884 if (status) 862 if (status)
885 return status; 863 return status;
886 return nfsd4_decode_fattr(argp, setattr->sa_bmval, nfsd_attrmask, 864 return nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr,
887 &setattr->sa_iattr, &setattr->sa_acl); 865 &setattr->sa_acl);
888} 866}
889 867
890static __be32 868static __be32