mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
NFS: Fix a soft lockup in the delegation recovery code
[ Upstream commit6f9449be53] Fix a soft lockup when NFS client delegation recovery is attempted but the inode is in the process of being freed. When the igrab(inode) call fails, and we have to restart the recovery process, we need to ensure that we won't attempt to recover the same delegation again. Fixes:45870d6909("NFSv4.1: Test delegation stateids when server...") Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
cd35b9353f
commit
341e4f3e35
@@ -240,6 +240,8 @@ static struct inode *nfs_delegation_grab_inode(struct nfs_delegation *delegation
|
||||
spin_lock(&delegation->lock);
|
||||
if (delegation->inode != NULL)
|
||||
inode = igrab(delegation->inode);
|
||||
if (!inode)
|
||||
set_bit(NFS_DELEGATION_INODE_FREEING, &delegation->flags);
|
||||
spin_unlock(&delegation->lock);
|
||||
return inode;
|
||||
}
|
||||
@@ -955,10 +957,11 @@ restart:
|
||||
list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
|
||||
list_for_each_entry_rcu(delegation, &server->delegations,
|
||||
super_list) {
|
||||
if (test_bit(NFS_DELEGATION_RETURNING,
|
||||
&delegation->flags))
|
||||
continue;
|
||||
if (test_bit(NFS_DELEGATION_NEED_RECLAIM,
|
||||
if (test_bit(NFS_DELEGATION_INODE_FREEING,
|
||||
&delegation->flags) ||
|
||||
test_bit(NFS_DELEGATION_RETURNING,
|
||||
&delegation->flags) ||
|
||||
test_bit(NFS_DELEGATION_NEED_RECLAIM,
|
||||
&delegation->flags) == 0)
|
||||
continue;
|
||||
if (!nfs_sb_active(server->super))
|
||||
@@ -1064,10 +1067,11 @@ restart:
|
||||
list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
|
||||
list_for_each_entry_rcu(delegation, &server->delegations,
|
||||
super_list) {
|
||||
if (test_bit(NFS_DELEGATION_RETURNING,
|
||||
&delegation->flags))
|
||||
continue;
|
||||
if (test_bit(NFS_DELEGATION_TEST_EXPIRED,
|
||||
if (test_bit(NFS_DELEGATION_INODE_FREEING,
|
||||
&delegation->flags) ||
|
||||
test_bit(NFS_DELEGATION_RETURNING,
|
||||
&delegation->flags) ||
|
||||
test_bit(NFS_DELEGATION_TEST_EXPIRED,
|
||||
&delegation->flags) == 0)
|
||||
continue;
|
||||
if (!nfs_sb_active(server->super))
|
||||
|
||||
@@ -34,6 +34,7 @@ enum {
|
||||
NFS_DELEGATION_RETURNING,
|
||||
NFS_DELEGATION_REVOKED,
|
||||
NFS_DELEGATION_TEST_EXPIRED,
|
||||
NFS_DELEGATION_INODE_FREEING,
|
||||
};
|
||||
|
||||
int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred,
|
||||
|
||||
Reference in New Issue
Block a user