Commit 987da479 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by J. Bruce Fields

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
6a76bebe "nfsd4: break lease on nfsd
setattr".
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 818e5a22
...@@ -444,27 +444,28 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, ...@@ -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;
if (check_guard && guardtime != inode->i_ctime.tv_sec) {
err = nfserr_notsync; err = nfserr_notsync;
if (!check_guard || guardtime == inode->i_ctime.tv_sec) { goto out_put_write_access;
}
host_err = nfsd_break_lease(inode); host_err = nfsd_break_lease(inode);
if (host_err) if (host_err)
goto out_nfserr; goto out_put_write_access_nfserror;
fh_lock(fhp);
fh_lock(fhp);
host_err = notify_change(dentry, iap, NULL); host_err = notify_change(dentry, iap, NULL);
err = nfserrno(host_err);
fh_unlock(fhp); 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) || \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment