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

Commit a2c0b9e2 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFS: Ensure that we handle NFS4ERR_STALE_STATEID correctly



Even if the server is crazy, we should be able to mark the stateid as being
bad, to ensure it gets recovered.

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
Reviewed-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 03391693
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -278,6 +278,7 @@ extern void nfs4_state_set_mode_locked(struct nfs4_state *, fmode_t);
extern void nfs4_schedule_state_recovery(struct nfs_client *);
extern void nfs4_schedule_state_manager(struct nfs_client *);
extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state);
extern int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state);
extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags);
extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
+31 −13
Original line number Diff line number Diff line
@@ -249,14 +249,14 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
			if (state == NULL)
				break;
			nfs4_state_mark_reclaim_nograce(clp, state);
		case -NFS4ERR_STALE_CLIENTID:
			goto do_state_recovery;
		case -NFS4ERR_STALE_STATEID:
		case -NFS4ERR_EXPIRED:
			nfs4_schedule_state_recovery(clp);
			ret = nfs4_wait_clnt_recover(clp);
			if (ret == 0)
				exception->retry = 1;
			if (state == NULL)
				break;
			nfs4_state_mark_reclaim_reboot(clp, state);
		case -NFS4ERR_STALE_CLIENTID:
		case -NFS4ERR_EXPIRED:
			goto do_state_recovery;
#if defined(CONFIG_NFS_V4_1)
		case -NFS4ERR_BADSESSION:
		case -NFS4ERR_BADSLOT:
@@ -289,6 +289,12 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
	}
	/* We failed to handle the error */
	return nfs4_map_errors(ret);
do_state_recovery:
	nfs4_schedule_state_recovery(clp);
	ret = nfs4_wait_clnt_recover(clp);
	if (ret == 0)
		exception->retry = 1;
	return ret;
}


@@ -3420,15 +3426,14 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
			if (state == NULL)
				break;
			nfs4_state_mark_reclaim_nograce(clp, state);
		case -NFS4ERR_STALE_CLIENTID:
			goto do_state_recovery;
		case -NFS4ERR_STALE_STATEID:
			if (state == NULL)
				break;
			nfs4_state_mark_reclaim_reboot(clp, state);
		case -NFS4ERR_STALE_CLIENTID:
		case -NFS4ERR_EXPIRED:
			rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
			nfs4_schedule_state_recovery(clp);
			if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
				rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
			task->tk_status = 0;
			return -EAGAIN;
			goto do_state_recovery;
#if defined(CONFIG_NFS_V4_1)
		case -NFS4ERR_BADSESSION:
		case -NFS4ERR_BADSLOT:
@@ -3456,6 +3461,13 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
	}
	task->tk_status = nfs4_map_errors(task->tk_status);
	return 0;
do_state_recovery:
	rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
	nfs4_schedule_state_recovery(clp);
	if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
		rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
	task->tk_status = 0;
	return -EAGAIN;
}

static int
@@ -4099,6 +4111,12 @@ static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_
		   (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0)
			nfs4_state_mark_reclaim_nograce(clp, state);
		lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED;
		break;
	case -NFS4ERR_STALE_STATEID:
		if (new_lock_owner != 0 ||
		    (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0)
			nfs4_state_mark_reclaim_reboot(clp, state);
		lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED;
	};
}

+1 −1
Original line number Diff line number Diff line
@@ -901,7 +901,7 @@ void nfs4_schedule_state_recovery(struct nfs_client *clp)
	nfs4_schedule_state_manager(clp);
}

static int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state)
int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state)
{

	set_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags);