aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4proc.c')
-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}