nfsd: make sure to balance get/put_write_access
Use a straight goto error label style in nfsd_setattr to make sure
we always do the put_write_access call after we got it earlier.
Note that the we have been failing to do that in the case
nfsd_break_lease() returns an error, a bug introduced into 2.6.38 with
6a76bebefe
"nfsd4: break lease on nfsd
setattr".
Signed-off-by: Christoph Hellwig <hch@lst.de>
Cc: stable@vger.kernel.org
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
parent
818e5a22e9
commit
987da47910
1 changed files with 15 additions and 14 deletions
|
@ -444,27 +444,28 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
|
||||||
|
|
||||||
iap->ia_valid |= ATTR_CTIME;
|
iap->ia_valid |= ATTR_CTIME;
|
||||||
|
|
||||||
err = nfserr_notsync;
|
if (check_guard && guardtime != inode->i_ctime.tv_sec) {
|
||||||
if (!check_guard || guardtime == inode->i_ctime.tv_sec) {
|
err = nfserr_notsync;
|
||||||
host_err = nfsd_break_lease(inode);
|
goto out_put_write_access;
|
||||||
if (host_err)
|
|
||||||
goto out_nfserr;
|
|
||||||
fh_lock(fhp);
|
|
||||||
|
|
||||||
host_err = notify_change(dentry, iap, NULL);
|
|
||||||
err = nfserrno(host_err);
|
|
||||||
fh_unlock(fhp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
host_err = nfsd_break_lease(inode);
|
||||||
|
if (host_err)
|
||||||
|
goto out_put_write_access_nfserror;
|
||||||
|
|
||||||
|
fh_lock(fhp);
|
||||||
|
host_err = notify_change(dentry, iap, NULL);
|
||||||
|
fh_unlock(fhp);
|
||||||
|
|
||||||
|
out_put_write_access_nfserror:
|
||||||
|
err = nfserrno(host_err);
|
||||||
|
out_put_write_access:
|
||||||
if (size_change)
|
if (size_change)
|
||||||
put_write_access(inode);
|
put_write_access(inode);
|
||||||
if (!err)
|
if (!err)
|
||||||
commit_metadata(fhp);
|
commit_metadata(fhp);
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
out_nfserr:
|
|
||||||
err = nfserrno(host_err);
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_NFSD_V2_ACL) || \
|
#if defined(CONFIG_NFSD_V2_ACL) || \
|
||||||
|
|
Loading…
Reference in a new issue