NFSv4: Fix nfs_server_return_all_delegations
If the state manager thread is already running, we may end up racing with it in nfs_client_return_marked_delegations. Better to just allow the state manager thread to do the job. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
b757144fd7
commit
5c31e2368f
|
@ -502,6 +502,18 @@ static void nfs_mark_return_delegation(struct nfs_server *server,
|
||||||
set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
|
set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool nfs_server_mark_return_all_delegations(struct nfs_server *server)
|
||||||
|
{
|
||||||
|
struct nfs_delegation *delegation;
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
|
||||||
|
nfs_mark_return_delegation(server, delegation);
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nfs_super_return_all_delegations - return delegations for one superblock
|
* nfs_super_return_all_delegations - return delegations for one superblock
|
||||||
* @sb: sb to process
|
* @sb: sb to process
|
||||||
|
@ -510,21 +522,19 @@ static void nfs_mark_return_delegation(struct nfs_server *server,
|
||||||
void nfs_server_return_all_delegations(struct nfs_server *server)
|
void nfs_server_return_all_delegations(struct nfs_server *server)
|
||||||
{
|
{
|
||||||
struct nfs_client *clp = server->nfs_client;
|
struct nfs_client *clp = server->nfs_client;
|
||||||
struct nfs_delegation *delegation;
|
bool need_wait;
|
||||||
|
|
||||||
if (clp == NULL)
|
if (clp == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
|
need_wait = nfs_server_mark_return_all_delegations(server);
|
||||||
spin_lock(&delegation->lock);
|
|
||||||
set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
|
|
||||||
spin_unlock(&delegation->lock);
|
|
||||||
}
|
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
if (nfs_client_return_marked_delegations(clp) != 0)
|
if (need_wait) {
|
||||||
nfs4_schedule_state_manager(clp);
|
nfs4_schedule_state_manager(clp);
|
||||||
|
nfs4_wait_clnt_recover(clp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nfs_mark_return_all_delegation_types(struct nfs_server *server,
|
static void nfs_mark_return_all_delegation_types(struct nfs_server *server,
|
||||||
|
|
Loading…
Reference in New Issue