summaryrefslogtreecommitdiff
path: root/fs/nfs/delegation.c
diff options
context:
space:
mode:
authorTrond Myklebust <trondmy@gmail.com>2020-02-13 14:51:07 -0500
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2020-02-13 16:23:02 -0500
commit5d63944f8206a80636ae8cb4b9107d3b49f43d37 (patch)
tree2ce4358837e2bc7fe3bbf34faae0146bb034db6e /fs/nfs/delegation.c
parent8c75593c6eee0f661ddf25dfde0e6ad2a84be7a9 (diff)
downloadlwn-5d63944f8206a80636ae8cb4b9107d3b49f43d37.tar.gz
lwn-5d63944f8206a80636ae8cb4b9107d3b49f43d37.zip
NFSv4: Ensure the delegation cred is pinned when we call delegreturn
Ensure we don't release the delegation cred during the call to nfs4_proc_delegreturn(). Fixes: ee05f456772d ("NFSv4: Fix races between open and delegreturn") Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs/nfs/delegation.c')
-rw-r--r--fs/nfs/delegation.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index c17ff826e7e9..1865322de142 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -255,13 +255,18 @@ void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync)
{
+ const struct cred *cred;
int res = 0;
- if (!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
- res = nfs4_proc_delegreturn(inode,
- delegation->cred,
+ if (!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
+ spin_lock(&delegation->lock);
+ cred = get_cred(delegation->cred);
+ spin_unlock(&delegation->lock);
+ res = nfs4_proc_delegreturn(inode, cred,
&delegation->stateid,
issync);
+ put_cred(cred);
+ }
return res;
}