diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2016-09-22 13:39:12 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2016-09-27 14:34:54 -0400 |
commit | b1a318de9bc4946ad4a20481ab3ce28c2e8cd72c (patch) | |
tree | e130b82c8bb97e7eec1adba8dc4f06aa6958d343 | |
parent | 9c27869d3f0680fa01d15616891a666d9e30fd83 (diff) |
NFSv4: Fix a race in nfs_inode_reclaim_delegation()
If we race with a delegreturn before taking the spin lock, we
currently end up dropping the delegation stateid.
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Tested-by: Oleg Drokin <green@linuxhacker.ru>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r-- | fs/nfs/delegation.c | 12 |
1 files changed, 5 insertions, 7 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 5de4cfb2ab07..094e0efe6a82 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -195,15 +195,13 @@ void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, rcu_read_unlock(); put_rpccred(oldcred); trace_nfs4_reclaim_delegation(inode, res->delegation_type); - } else { - /* We appear to have raced with a delegation return. */ - spin_unlock(&delegation->lock); - rcu_read_unlock(); - nfs_inode_set_delegation(inode, cred, res); + return; } - } else { - rcu_read_unlock(); + /* We appear to have raced with a delegation return. */ + spin_unlock(&delegation->lock); } + rcu_read_unlock(); + nfs_inode_set_delegation(inode, cred, res); } static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync) |