NFSv4: Avoid unnecessary scans of filesystems for expired delegations

[ Upstream commit f163aa81a799e2d46d7f8f0b42a0e7770eaa0d06 ]

The amount of looping through the list of delegations is occasionally
leading to soft lockups.  If the state manager was asked to reap the
expired delegations, it should scan only those filesystems that hold
delegations that need to be reaped.

Fixes: 7f156ef0bf ("NFSv4: Clean up nfs_delegation_reap_expired()")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Trond Myklebust
2025-02-18 19:03:21 -05:00
committed by Greg Kroah-Hartman
parent ac8be75a7d
commit 8765bc2638
2 changed files with 8 additions and 0 deletions
+7
View File
@@ -1284,6 +1284,7 @@ static void nfs_mark_test_expired_delegation(struct nfs_server *server,
return;
clear_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
set_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags);
set_bit(NFS4SERV_DELEGATION_EXPIRED, &server->delegation_flags);
set_bit(NFS4CLNT_DELEGATION_EXPIRED, &server->nfs_client->cl_state);
}
@@ -1362,6 +1363,9 @@ static int nfs_server_reap_expired_delegations(struct nfs_server *server,
nfs4_stateid stateid;
unsigned long gen = ++server->delegation_gen;
if (!test_and_clear_bit(NFS4SERV_DELEGATION_EXPIRED,
&server->delegation_flags))
return 0;
restart:
rcu_read_lock();
list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
@@ -1391,6 +1395,9 @@ restart:
goto restart;
}
nfs_inode_mark_test_expired_delegation(server,inode);
set_bit(NFS4SERV_DELEGATION_EXPIRED, &server->delegation_flags);
set_bit(NFS4CLNT_DELEGATION_EXPIRED,
&server->nfs_client->cl_state);
iput(inode);
return -EAGAIN;
}
+1
View File
@@ -253,6 +253,7 @@ struct nfs_server {
unsigned long delegation_flags;
#define NFS4SERV_DELEGRETURN (1)
#define NFS4SERV_DELEGATION_EXPIRED (2)
unsigned long delegation_gen;
unsigned long mig_gen;
unsigned long mig_status;