diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-07-01 18:27:53 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2014-07-08 17:14:31 -0400 |
commit | 0f3a24b43bf75adf67df188a85594a8f43b9ee93 (patch) | |
tree | b3842434d8e8344c7ac76f225611877031f1929d /fs/nfsd/vfs.c | |
parent | 1e444f5bc0c468e244ee601b7acbd87f0b6ee7e2 (diff) |
nfsd: Ensure that nfsd_create_setattr commits files to stable storage
Since nfsd_create_setattr strips the mode from the struct iattr, it
is quite possible that it will optimise away the call to nfsd_setattr
altogether.
If this is the case, then we never call commit_metadata() on the
newly created file.
Also ensure that both nfsd_setattr() and nfsd_create_setattr() fail
when the call to commit_metadata fails.
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r-- | fs/nfsd/vfs.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 730f31964597..e1b792ada45b 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -463,7 +463,7 @@ out_put_write_access: | |||
463 | if (size_change) | 463 | if (size_change) |
464 | put_write_access(inode); | 464 | put_write_access(inode); |
465 | if (!err) | 465 | if (!err) |
466 | commit_metadata(fhp); | 466 | err = commit_metadata(fhp); |
467 | out: | 467 | out: |
468 | return err; | 468 | return err; |
469 | } | 469 | } |
@@ -1121,7 +1121,8 @@ nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *resfhp, | |||
1121 | iap->ia_valid &= ~(ATTR_UID|ATTR_GID); | 1121 | iap->ia_valid &= ~(ATTR_UID|ATTR_GID); |
1122 | if (iap->ia_valid) | 1122 | if (iap->ia_valid) |
1123 | return nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); | 1123 | return nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); |
1124 | return 0; | 1124 | /* Callers expect file metadata to be committed here */ |
1125 | return commit_metadata(resfhp); | ||
1125 | } | 1126 | } |
1126 | 1127 | ||
1127 | /* HPUX client sometimes creates a file in mode 000, and sets size to 0. | 1128 | /* HPUX client sometimes creates a file in mode 000, and sets size to 0. |
@@ -1253,9 +1254,10 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1253 | err = nfsd_create_setattr(rqstp, resfhp, iap); | 1254 | err = nfsd_create_setattr(rqstp, resfhp, iap); |
1254 | 1255 | ||
1255 | /* | 1256 | /* |
1256 | * nfsd_setattr already committed the child. Transactional filesystems | 1257 | * nfsd_create_setattr already committed the child. Transactional |
1257 | * had a chance to commit changes for both parent and child | 1258 | * filesystems had a chance to commit changes for both parent and |
1258 | * simultaneously making the following commit_metadata a noop. | 1259 | * child * simultaneously making the following commit_metadata a |
1260 | * noop. | ||
1259 | */ | 1261 | */ |
1260 | err2 = nfserrno(commit_metadata(fhp)); | 1262 | err2 = nfserrno(commit_metadata(fhp)); |
1261 | if (err2) | 1263 | if (err2) |
@@ -1426,7 +1428,8 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1426 | err = nfsd_create_setattr(rqstp, resfhp, iap); | 1428 | err = nfsd_create_setattr(rqstp, resfhp, iap); |
1427 | 1429 | ||
1428 | /* | 1430 | /* |
1429 | * nfsd_setattr already committed the child (and possibly also the parent). | 1431 | * nfsd_create_setattr already committed the child |
1432 | * (and possibly also the parent). | ||
1430 | */ | 1433 | */ |
1431 | if (!err) | 1434 | if (!err) |
1432 | err = nfserrno(commit_metadata(fhp)); | 1435 | err = nfserrno(commit_metadata(fhp)); |