提交 6eaa6149 编写于 作者: T Trond Myklebust

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: NTrond Myklebust <Trond.Myklebust@netapp.com>
Cc: stable@kernel.org
上级 ae1007d3
...@@ -1138,16 +1138,14 @@ static void nfs4_reclaim_complete(struct nfs_client *clp, ...@@ -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) ...@@ -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) ...@@ -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:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册