Commit 5c441544 authored by Trond Myklebust's avatar Trond Myklebust

NFSv4.x: Handle bad/dead sessions correctly in nfs41_sequence_process()

If the server returns a bad or dead session error, the we don't want
to update the session slot number, but just immediately schedule
recovery and allow it to proceed.

We can/should then remove handling in other places

Fixes: 3453d570 ("NFSv4.1: Avoid false retries when RPC calls are interrupted")
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent 634d811c
...@@ -521,9 +521,7 @@ static int nfs4_do_handle_exception(struct nfs_server *server, ...@@ -521,9 +521,7 @@ static int nfs4_do_handle_exception(struct nfs_server *server,
case -NFS4ERR_DEADSESSION: case -NFS4ERR_DEADSESSION:
case -NFS4ERR_SEQ_FALSE_RETRY: case -NFS4ERR_SEQ_FALSE_RETRY:
case -NFS4ERR_SEQ_MISORDERED: case -NFS4ERR_SEQ_MISORDERED:
dprintk("%s ERROR: %d Reset session\n", __func__, /* Handled in nfs41_sequence_process() */
errorcode);
nfs4_schedule_session_recovery(clp->cl_session, errorcode);
goto wait_on_recovery; goto wait_on_recovery;
#endif /* defined(CONFIG_NFS_V4_1) */ #endif /* defined(CONFIG_NFS_V4_1) */
case -NFS4ERR_FILE_OPEN: case -NFS4ERR_FILE_OPEN:
...@@ -782,6 +780,7 @@ static int nfs41_sequence_process(struct rpc_task *task, ...@@ -782,6 +780,7 @@ static int nfs41_sequence_process(struct rpc_task *task,
struct nfs4_session *session; struct nfs4_session *session;
struct nfs4_slot *slot = res->sr_slot; struct nfs4_slot *slot = res->sr_slot;
struct nfs_client *clp; struct nfs_client *clp;
int status;
int ret = 1; int ret = 1;
if (slot == NULL) if (slot == NULL)
...@@ -793,8 +792,13 @@ static int nfs41_sequence_process(struct rpc_task *task, ...@@ -793,8 +792,13 @@ static int nfs41_sequence_process(struct rpc_task *task,
session = slot->table->session; session = slot->table->session;
trace_nfs4_sequence_done(session, res); trace_nfs4_sequence_done(session, res);
status = res->sr_status;
if (task->tk_status == -NFS4ERR_DEADSESSION)
status = -NFS4ERR_DEADSESSION;
/* Check the SEQUENCE operation status */ /* Check the SEQUENCE operation status */
switch (res->sr_status) { switch (status) {
case 0: case 0:
/* Mark this sequence number as having been acked */ /* Mark this sequence number as having been acked */
nfs4_slot_sequence_acked(slot, slot->seq_nr); nfs4_slot_sequence_acked(slot, slot->seq_nr);
...@@ -866,6 +870,10 @@ static int nfs41_sequence_process(struct rpc_task *task, ...@@ -866,6 +870,10 @@ static int nfs41_sequence_process(struct rpc_task *task,
*/ */
slot->seq_nr = slot->seq_nr_highest_sent; slot->seq_nr = slot->seq_nr_highest_sent;
goto out_retry; goto out_retry;
case -NFS4ERR_BADSESSION:
case -NFS4ERR_DEADSESSION:
case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
goto session_recover;
default: default:
/* Just update the slot sequence no. */ /* Just update the slot sequence no. */
slot->seq_done = 1; slot->seq_done = 1;
...@@ -876,8 +884,10 @@ static int nfs41_sequence_process(struct rpc_task *task, ...@@ -876,8 +884,10 @@ static int nfs41_sequence_process(struct rpc_task *task,
out_noaction: out_noaction:
return ret; return ret;
session_recover: session_recover:
nfs4_schedule_session_recovery(session, res->sr_status); nfs4_schedule_session_recovery(session, status);
goto retry_nowait; dprintk("%s ERROR: %d Reset session\n", __func__, status);
nfs41_sequence_free_slot(res);
goto out;
retry_new_seq: retry_new_seq:
++slot->seq_nr; ++slot->seq_nr;
retry_nowait: retry_nowait:
...@@ -2188,7 +2198,6 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct ...@@ -2188,7 +2198,6 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct
case -NFS4ERR_BAD_HIGH_SLOT: case -NFS4ERR_BAD_HIGH_SLOT:
case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
case -NFS4ERR_DEADSESSION: case -NFS4ERR_DEADSESSION:
nfs4_schedule_session_recovery(server->nfs_client->cl_session, err);
return -EAGAIN; return -EAGAIN;
case -NFS4ERR_STALE_CLIENTID: case -NFS4ERR_STALE_CLIENTID:
case -NFS4ERR_STALE_STATEID: case -NFS4ERR_STALE_STATEID:
...@@ -7824,6 +7833,15 @@ nfs41_same_server_scope(struct nfs41_server_scope *a, ...@@ -7824,6 +7833,15 @@ nfs41_same_server_scope(struct nfs41_server_scope *a,
static void static void
nfs4_bind_one_conn_to_session_done(struct rpc_task *task, void *calldata) nfs4_bind_one_conn_to_session_done(struct rpc_task *task, void *calldata)
{ {
struct nfs41_bind_conn_to_session_args *args = task->tk_msg.rpc_argp;
struct nfs_client *clp = args->client;
switch (task->tk_status) {
case -NFS4ERR_BADSESSION:
case -NFS4ERR_DEADSESSION:
nfs4_schedule_session_recovery(clp->cl_session,
task->tk_status);
}
} }
static const struct rpc_call_ops nfs4_bind_one_conn_to_session_ops = { static const struct rpc_call_ops nfs4_bind_one_conn_to_session_ops = {
...@@ -8871,8 +8889,6 @@ static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nf ...@@ -8871,8 +8889,6 @@ static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nf
case -NFS4ERR_BADSESSION: case -NFS4ERR_BADSESSION:
case -NFS4ERR_DEADSESSION: case -NFS4ERR_DEADSESSION:
case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
nfs4_schedule_session_recovery(clp->cl_session,
task->tk_status);
break; break;
default: default:
nfs4_schedule_lease_recovery(clp); nfs4_schedule_lease_recovery(clp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment