diff options
author | Trond Myklebust <trondmy@gmail.com> | 2020-02-13 20:51:07 +0100 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2020-02-13 22:23:02 +0100 |
commit | 5d63944f8206a80636ae8cb4b9107d3b49f43d37 (patch) | |
tree | 2ce4358837e2bc7fe3bbf34faae0146bb034db6e /fs | |
parent | NFSv4: Ensure the delegation is pinned in nfs_do_return_delegation() (diff) | |
download | linux-5d63944f8206a80636ae8cb4b9107d3b49f43d37.tar.xz linux-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')
-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 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; } |