diff options
author | Trond Myklebust <trondmy@gmail.com> | 2020-02-13 14:51:07 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-02-19 19:54:12 +0100 |
commit | 3832448c6663dd7147184448f5b6cbe524121223 (patch) | |
tree | 1ee3385d2079696dd842d6704e9ed637dd3ad1b1 /fs | |
parent | d88079b03091dbcb85520cc791cf0c21d73f6c75 (diff) |
NFSv4: Ensure the delegation cred is pinned when we call delegreturn
commit 5d63944f8206a80636ae8cb4b9107d3b49f43d37 upstream.
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/delegation.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index fe57b2b5314a..5f02d922f217 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -222,13 +222,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; } |