aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2011-10-13 11:37:11 -0400
committerJ. Bruce Fields <bfields@redhat.com>2011-10-17 17:50:08 -0400
commit856121b2e83bd64bffdc8de449d24c9295e92ff3 (patch)
treed60a777368fa48120a878407dd7abdcc780d2eba
parent4cdc951b8611de4ce25e35c9fb8c0656150c9245 (diff)
nfsd4: warn on open failure after create
If we create the object and then return failure to the client, we're left with an unexpected file in the filesystem. I'm trying to eliminate such cases but not 100% sure I have so an assertion might be helpful for now. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--fs/nfsd/nfs4proc.c7
-rw-r--r--fs/nfsd/vfs.c2
-rw-r--r--fs/nfsd/vfs.h2
-rw-r--r--fs/nfsd/xdr4.h3
4 files changed, 8 insertions, 6 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 10b50d78bdc3..710b97b7a2f3 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -194,7 +194,6 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
194{ 194{
195 struct svc_fh resfh; 195 struct svc_fh resfh;
196 __be32 status; 196 __be32 status;
197 int created = 0;
198 197
199 fh_init(&resfh, NFS4_FHSIZE); 198 fh_init(&resfh, NFS4_FHSIZE);
200 open->op_truncate = 0; 199 open->op_truncate = 0;
@@ -223,7 +222,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
223 open->op_fname.len, &open->op_iattr, 222 open->op_fname.len, &open->op_iattr,
224 &resfh, open->op_createmode, 223 &resfh, open->op_createmode,
225 (u32 *)open->op_verf.data, 224 (u32 *)open->op_verf.data,
226 &open->op_truncate, &created); 225 &open->op_truncate, &open->op_created);
227 226
228 /* 227 /*
229 * Following rfc 3530 14.2.16, use the returned bitmask 228 * Following rfc 3530 14.2.16, use the returned bitmask
@@ -253,7 +252,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
253 /* set reply cache */ 252 /* set reply cache */
254 fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh, 253 fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh,
255 &resfh.fh_handle); 254 &resfh.fh_handle);
256 if (!created) 255 if (!open->op_created)
257 status = do_open_permission(rqstp, current_fh, open, 256 status = do_open_permission(rqstp, current_fh, open,
258 NFSD_MAY_NOP); 257 NFSD_MAY_NOP);
259 258
@@ -318,6 +317,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
318 /* We don't yet support WANT bits: */ 317 /* We don't yet support WANT bits: */
319 open->op_share_access &= NFS4_SHARE_ACCESS_MASK; 318 open->op_share_access &= NFS4_SHARE_ACCESS_MASK;
320 319
320 open->op_created = 0;
321 /* 321 /*
322 * RFC5661 18.51.3 322 * RFC5661 18.51.3
323 * Before RECLAIM_COMPLETE done, server should deny new lock 323 * Before RECLAIM_COMPLETE done, server should deny new lock
@@ -408,6 +408,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
408 * set, (2) sets open->op_stateid, (3) sets open->op_delegation. 408 * set, (2) sets open->op_stateid, (3) sets open->op_delegation.
409 */ 409 */
410 status = nfsd4_process_open2(rqstp, &cstate->current_fh, open); 410 status = nfsd4_process_open2(rqstp, &cstate->current_fh, open);
411 WARN_ON(status && open->op_created);
411out: 412out:
412 nfsd4_cleanup_open_state(open, status); 413 nfsd4_cleanup_open_state(open, status);
413 if (open->op_openowner) 414 if (open->op_openowner)
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 4dd91283d039..7a2e442623c8 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1370,7 +1370,7 @@ __be32
1370do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, 1370do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1371 char *fname, int flen, struct iattr *iap, 1371 char *fname, int flen, struct iattr *iap,
1372 struct svc_fh *resfhp, int createmode, u32 *verifier, 1372 struct svc_fh *resfhp, int createmode, u32 *verifier,
1373 int *truncp, int *created) 1373 bool *truncp, bool *created)
1374{ 1374{
1375 struct dentry *dentry, *dchild = NULL; 1375 struct dentry *dentry, *dchild = NULL;
1376 struct inode *dirp; 1376 struct inode *dirp;
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index 503f3bf11abd..3f54ad03bb2b 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -62,7 +62,7 @@ __be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *);
62__be32 do_nfsd_create(struct svc_rqst *, struct svc_fh *, 62__be32 do_nfsd_create(struct svc_rqst *, struct svc_fh *,
63 char *name, int len, struct iattr *attrs, 63 char *name, int len, struct iattr *attrs,
64 struct svc_fh *res, int createmode, 64 struct svc_fh *res, int createmode,
65 u32 *verifier, int *truncp, int *created); 65 u32 *verifier, bool *truncp, bool *created);
66__be32 nfsd_commit(struct svc_rqst *, struct svc_fh *, 66__be32 nfsd_commit(struct svc_rqst *, struct svc_fh *,
67 loff_t, unsigned long); 67 loff_t, unsigned long);
68#endif /* CONFIG_NFSD_V3 */ 68#endif /* CONFIG_NFSD_V3 */
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index ce8c59196b4e..e3057350eea1 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -226,7 +226,8 @@ struct nfsd4_open {
226 u32 op_recall; /* recall */ 226 u32 op_recall; /* recall */
227 struct nfsd4_change_info op_cinfo; /* response */ 227 struct nfsd4_change_info op_cinfo; /* response */
228 u32 op_rflags; /* response */ 228 u32 op_rflags; /* response */
229 int op_truncate; /* used during processing */ 229 bool op_truncate; /* used during processing */
230 bool op_created; /* used during processing */
230 struct nfs4_openowner *op_openowner; /* used during processing */ 231 struct nfs4_openowner *op_openowner; /* used during processing */
231 struct nfs4_file *op_file; /* used during processing */ 232 struct nfs4_file *op_file; /* used during processing */
232 struct nfs4_ol_stateid *op_stp; /* used during processing */ 233 struct nfs4_ol_stateid *op_stp; /* used during processing */