NFSv4: Don't call nfs4_reclaim_complete() on receiving NFS4ERR_STALE_CLIENTID
If the server sends us an NFS4ERR_STALE_CLIENTID while the state management thread is busy reclaiming state, we do want to treat all state that wasn't reclaimed before the STALE_CLIENTID as if a network partition occurred (see the edge conditions described in RFC3530 and RFC5661). What we do not want to do is to send an nfs4_reclaim_complete(), since we haven't yet even started reclaiming state after the server rebooted. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Cc: stable@kernel.org
This commit is contained in:
Родитель
ae1007d37e
Коммит
6eaa61496f
|
@ -1138,16 +1138,14 @@ static void nfs4_reclaim_complete(struct nfs_client *clp,
|
||||||
(void)ops->reclaim_complete(clp);
|
(void)ops->reclaim_complete(clp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
|
static int nfs4_state_clear_reclaim_reboot(struct nfs_client *clp)
|
||||||
{
|
{
|
||||||
struct nfs4_state_owner *sp;
|
struct nfs4_state_owner *sp;
|
||||||
struct rb_node *pos;
|
struct rb_node *pos;
|
||||||
struct nfs4_state *state;
|
struct nfs4_state *state;
|
||||||
|
|
||||||
if (!test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state))
|
if (!test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state))
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
nfs4_reclaim_complete(clp, clp->cl_mvops->reboot_recovery_ops);
|
|
||||||
|
|
||||||
for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) {
|
for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) {
|
||||||
sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
|
sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
|
||||||
|
@ -1161,6 +1159,14 @@ static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
|
||||||
}
|
}
|
||||||
|
|
||||||
nfs_delegation_reap_unclaimed(clp);
|
nfs_delegation_reap_unclaimed(clp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
|
||||||
|
{
|
||||||
|
if (!nfs4_state_clear_reclaim_reboot(clp))
|
||||||
|
return;
|
||||||
|
nfs4_reclaim_complete(clp, clp->cl_mvops->reboot_recovery_ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nfs_delegation_clear_all(struct nfs_client *clp)
|
static void nfs_delegation_clear_all(struct nfs_client *clp)
|
||||||
|
@ -1187,7 +1193,7 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
|
||||||
case -NFS4ERR_STALE_CLIENTID:
|
case -NFS4ERR_STALE_CLIENTID:
|
||||||
case -NFS4ERR_LEASE_MOVED:
|
case -NFS4ERR_LEASE_MOVED:
|
||||||
set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
|
set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
|
||||||
nfs4_state_end_reclaim_reboot(clp);
|
nfs4_state_clear_reclaim_reboot(clp);
|
||||||
nfs4_state_start_reclaim_reboot(clp);
|
nfs4_state_start_reclaim_reboot(clp);
|
||||||
break;
|
break;
|
||||||
case -NFS4ERR_EXPIRED:
|
case -NFS4ERR_EXPIRED:
|
||||||
|
|
Загрузка…
Ссылка в новой задаче