Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6eaa6149 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

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: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
Cc: stable@kernel.org
parent ae1007d3
Loading
Loading
Loading
Loading
+11 −5
Original line number Original line Diff line number Diff line
@@ -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: