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: 3453d5708b
("NFSv4.1: Avoid false retries when RPC calls are interrupted")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
Родитель
634d811c61
Коммит
5c441544f0
|
@ -521,9 +521,7 @@ static int nfs4_do_handle_exception(struct nfs_server *server,
|
|||
case -NFS4ERR_DEADSESSION:
|
||||
case -NFS4ERR_SEQ_FALSE_RETRY:
|
||||
case -NFS4ERR_SEQ_MISORDERED:
|
||||
dprintk("%s ERROR: %d Reset session\n", __func__,
|
||||
errorcode);
|
||||
nfs4_schedule_session_recovery(clp->cl_session, errorcode);
|
||||
/* Handled in nfs41_sequence_process() */
|
||||
goto wait_on_recovery;
|
||||
#endif /* defined(CONFIG_NFS_V4_1) */
|
||||
case -NFS4ERR_FILE_OPEN:
|
||||
|
@ -782,6 +780,7 @@ static int nfs41_sequence_process(struct rpc_task *task,
|
|||
struct nfs4_session *session;
|
||||
struct nfs4_slot *slot = res->sr_slot;
|
||||
struct nfs_client *clp;
|
||||
int status;
|
||||
int ret = 1;
|
||||
|
||||
if (slot == NULL)
|
||||
|
@ -793,8 +792,13 @@ static int nfs41_sequence_process(struct rpc_task *task,
|
|||
session = slot->table->session;
|
||||
|
||||
trace_nfs4_sequence_done(session, res);
|
||||
|
||||
status = res->sr_status;
|
||||
if (task->tk_status == -NFS4ERR_DEADSESSION)
|
||||
status = -NFS4ERR_DEADSESSION;
|
||||
|
||||
/* Check the SEQUENCE operation status */
|
||||
switch (res->sr_status) {
|
||||
switch (status) {
|
||||
case 0:
|
||||
/* Mark this sequence number as having been acked */
|
||||
nfs4_slot_sequence_acked(slot, slot->seq_nr);
|
||||
|
@ -866,6 +870,10 @@ static int nfs41_sequence_process(struct rpc_task *task,
|
|||
*/
|
||||
slot->seq_nr = slot->seq_nr_highest_sent;
|
||||
goto out_retry;
|
||||
case -NFS4ERR_BADSESSION:
|
||||
case -NFS4ERR_DEADSESSION:
|
||||
case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
|
||||
goto session_recover;
|
||||
default:
|
||||
/* Just update the slot sequence no. */
|
||||
slot->seq_done = 1;
|
||||
|
@ -876,8 +884,10 @@ out:
|
|||
out_noaction:
|
||||
return ret;
|
||||
session_recover:
|
||||
nfs4_schedule_session_recovery(session, res->sr_status);
|
||||
goto retry_nowait;
|
||||
nfs4_schedule_session_recovery(session, status);
|
||||
dprintk("%s ERROR: %d Reset session\n", __func__, status);
|
||||
nfs41_sequence_free_slot(res);
|
||||
goto out;
|
||||
retry_new_seq:
|
||||
++slot->seq_nr;
|
||||
retry_nowait:
|
||||
|
@ -2188,7 +2198,6 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct
|
|||
case -NFS4ERR_BAD_HIGH_SLOT:
|
||||
case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
|
||||
case -NFS4ERR_DEADSESSION:
|
||||
nfs4_schedule_session_recovery(server->nfs_client->cl_session, err);
|
||||
return -EAGAIN;
|
||||
case -NFS4ERR_STALE_CLIENTID:
|
||||
case -NFS4ERR_STALE_STATEID:
|
||||
|
@ -7824,6 +7833,15 @@ nfs41_same_server_scope(struct nfs41_server_scope *a,
|
|||
static void
|
||||
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 = {
|
||||
|
@ -8871,8 +8889,6 @@ static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nf
|
|||
case -NFS4ERR_BADSESSION:
|
||||
case -NFS4ERR_DEADSESSION:
|
||||
case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
|
||||
nfs4_schedule_session_recovery(clp->cl_session,
|
||||
task->tk_status);
|
||||
break;
|
||||
default:
|
||||
nfs4_schedule_lease_recovery(clp);
|
||||
|
|
Загрузка…
Ссылка в новой задаче