aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYu Zhiguo <yuzg@cn.fujitsu.com>2009-07-06 05:24:16 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2009-07-14 12:16:47 -0400
commit9208faf297dddfa97a86d7224b6bf94f2e346dd9 (patch)
treec93d67a14b2a12b77bec058df5510530d333bfc6
parent5a421ce3c062a87db0a9e7f2a0a7ee0a5b869aab (diff)
NFSv4: ACL in operations 'open' and 'create' should be used
ACL in operations 'open' and 'create' is decoded but never be used. It should be set as the initial ACL for the object according to RFC3530. If error occurs when setting the ACL, just clear the ACL bit in the returned attr bitmap. Signed-off-by: Yu Zhiguo <yuzg@cn.fujitsu.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
-rw-r--r--fs/nfsd/nfs4proc.c47
1 files changed, 42 insertions, 5 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 7c8801769a3c..d781658e8084 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -123,6 +123,35 @@ nfsd4_check_open_attributes(struct svc_rqst *rqstp,
123 return status; 123 return status;
124} 124}
125 125
126static int
127is_create_with_attrs(struct nfsd4_open *open)
128{
129 return open->op_create == NFS4_OPEN_CREATE
130 && (open->op_createmode == NFS4_CREATE_UNCHECKED
131 || open->op_createmode == NFS4_CREATE_GUARDED
132 || open->op_createmode == NFS4_CREATE_EXCLUSIVE4_1);
133}
134
135/*
136 * if error occurs when setting the acl, just clear the acl bit
137 * in the returned attr bitmap.
138 */
139static void
140do_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
141 struct nfs4_acl *acl, u32 *bmval)
142{
143 __be32 status;
144
145 status = nfsd4_set_nfs4_acl(rqstp, fhp, acl);
146 if (status)
147 /*
148 * We should probably fail the whole open at this point,
149 * but we've already created the file, so it's too late;
150 * So this seems the least of evils:
151 */
152 bmval[0] &= ~FATTR4_WORD0_ACL;
153}
154
126static inline void 155static inline void
127fh_dup2(struct svc_fh *dst, struct svc_fh *src) 156fh_dup2(struct svc_fh *dst, struct svc_fh *src)
128{ 157{
@@ -206,6 +235,9 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
206 if (status) 235 if (status)
207 goto out; 236 goto out;
208 237
238 if (is_create_with_attrs(open) && open->op_acl != NULL)
239 do_set_nfs4_acl(rqstp, &resfh, open->op_acl, open->op_bmval);
240
209 set_change_info(&open->op_cinfo, current_fh); 241 set_change_info(&open->op_cinfo, current_fh);
210 fh_dup2(current_fh, &resfh); 242 fh_dup2(current_fh, &resfh);
211 243
@@ -536,12 +568,17 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
536 status = nfserr_badtype; 568 status = nfserr_badtype;
537 } 569 }
538 570
539 if (!status) { 571 if (status)
540 fh_unlock(&cstate->current_fh); 572 goto out;
541 set_change_info(&create->cr_cinfo, &cstate->current_fh);
542 fh_dup2(&cstate->current_fh, &resfh);
543 }
544 573
574 if (create->cr_acl != NULL)
575 do_set_nfs4_acl(rqstp, &resfh, create->cr_acl,
576 create->cr_bmval);
577
578 fh_unlock(&cstate->current_fh);
579 set_change_info(&create->cr_cinfo, &cstate->current_fh);
580 fh_dup2(&cstate->current_fh, &resfh);
581out:
545 fh_put(&resfh); 582 fh_put(&resfh);
546 return status; 583 return status;
547} 584}