提交 53322fc4 编写于 作者: T Trond Myklebust 提交者: Yang Yingliang

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

mainline inclusion
from mainline-v5.5-rc1
commit 5c441544
category: bugfix
bugzilla: NA
CVE: NA

--------------------------------

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: NTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: NZhang Xiaoxu <zhangxiaoxu5@huawei.com>
Reviewed-by: NZhang Yi <yi.zhang@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 c780dc42
...@@ -504,9 +504,7 @@ static int nfs4_do_handle_exception(struct nfs_server *server, ...@@ -504,9 +504,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:
...@@ -765,6 +763,7 @@ static int nfs41_sequence_process(struct rpc_task *task, ...@@ -765,6 +763,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)
...@@ -776,8 +775,13 @@ static int nfs41_sequence_process(struct rpc_task *task, ...@@ -776,8 +775,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);
...@@ -849,6 +853,10 @@ static int nfs41_sequence_process(struct rpc_task *task, ...@@ -849,6 +853,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;
...@@ -859,8 +867,10 @@ static int nfs41_sequence_process(struct rpc_task *task, ...@@ -859,8 +867,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:
...@@ -2121,7 +2131,6 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct ...@@ -2121,7 +2131,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:
...@@ -7706,6 +7715,15 @@ nfs41_same_server_scope(struct nfs41_server_scope *a, ...@@ -7706,6 +7715,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 = {
...@@ -8756,8 +8774,6 @@ static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nf ...@@ -8756,8 +8774,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% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册