Commit 29190c77 authored by Nicholas Bellinger's avatar Nicholas Bellinger Committed by Sasha Levin

target: Fix TAS handling for multi-session se_node_acls

commit ebde1ca5 upstream.

This patch fixes a bug in TMR task aborted status (TAS)
handling when multiple sessions are connected to the
same target WWPN endpoint and se_node_acl descriptor,
resulting in TASK_ABORTED status to not be generated
for aborted se_cmds on the remote port.

This is due to core_tmr_handle_tas_abort() incorrectly
comparing se_node_acl instead of se_session, for which
the multi-session case is expected to be sharing the
same se_node_acl.

Instead, go ahead and update core_tmr_handle_tas_abort()
to compare tmr_sess + cmd->se_sess in order to determine
if the LUN_RESET was received on a different I_T nexus,
and TASK_ABORTED status response needs to be generated.
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Cc: Quinn Tran <quinn.tran@qlogic.com>
Cc: Himanshu Madhani <himanshu.madhani@qlogic.com>
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Andy Grover <agrover@redhat.com>
Cc: Mike Christie <mchristi@redhat.com>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: default avatarSasha Levin <sasha.levin@oracle.com>
parent 3286a2fe
...@@ -79,7 +79,7 @@ void core_tmr_release_req(struct se_tmr_req *tmr) ...@@ -79,7 +79,7 @@ void core_tmr_release_req(struct se_tmr_req *tmr)
} }
static void core_tmr_handle_tas_abort( static void core_tmr_handle_tas_abort(
struct se_node_acl *tmr_nacl, struct se_session *tmr_sess,
struct se_cmd *cmd, struct se_cmd *cmd,
int tas) int tas)
{ {
...@@ -87,7 +87,7 @@ static void core_tmr_handle_tas_abort( ...@@ -87,7 +87,7 @@ static void core_tmr_handle_tas_abort(
/* /*
* TASK ABORTED status (TAS) bit support * TASK ABORTED status (TAS) bit support
*/ */
if ((tmr_nacl && (tmr_nacl != cmd->se_sess->se_node_acl)) && tas) { if (tmr_sess && tmr_sess != cmd->se_sess && tas) {
remove = false; remove = false;
transport_send_task_abort(cmd); transport_send_task_abort(cmd);
} }
...@@ -277,7 +277,7 @@ static void core_tmr_drain_tmr_list( ...@@ -277,7 +277,7 @@ static void core_tmr_drain_tmr_list(
static void core_tmr_drain_state_list( static void core_tmr_drain_state_list(
struct se_device *dev, struct se_device *dev,
struct se_cmd *prout_cmd, struct se_cmd *prout_cmd,
struct se_node_acl *tmr_nacl, struct se_session *tmr_sess,
int tas, int tas,
struct list_head *preempt_and_abort_list) struct list_head *preempt_and_abort_list)
{ {
...@@ -368,7 +368,7 @@ static void core_tmr_drain_state_list( ...@@ -368,7 +368,7 @@ static void core_tmr_drain_state_list(
cancel_work_sync(&cmd->work); cancel_work_sync(&cmd->work);
transport_wait_for_tasks(cmd); transport_wait_for_tasks(cmd);
core_tmr_handle_tas_abort(tmr_nacl, cmd, tas); core_tmr_handle_tas_abort(tmr_sess, cmd, tas);
target_put_sess_cmd(cmd); target_put_sess_cmd(cmd);
} }
} }
...@@ -381,6 +381,7 @@ int core_tmr_lun_reset( ...@@ -381,6 +381,7 @@ int core_tmr_lun_reset(
{ {
struct se_node_acl *tmr_nacl = NULL; struct se_node_acl *tmr_nacl = NULL;
struct se_portal_group *tmr_tpg = NULL; struct se_portal_group *tmr_tpg = NULL;
struct se_session *tmr_sess = NULL;
int tas; int tas;
/* /*
* TASK_ABORTED status bit, this is configurable via ConfigFS * TASK_ABORTED status bit, this is configurable via ConfigFS
...@@ -399,8 +400,9 @@ int core_tmr_lun_reset( ...@@ -399,8 +400,9 @@ int core_tmr_lun_reset(
* or struct se_device passthrough.. * or struct se_device passthrough..
*/ */
if (tmr && tmr->task_cmd && tmr->task_cmd->se_sess) { if (tmr && tmr->task_cmd && tmr->task_cmd->se_sess) {
tmr_nacl = tmr->task_cmd->se_sess->se_node_acl; tmr_sess = tmr->task_cmd->se_sess;
tmr_tpg = tmr->task_cmd->se_sess->se_tpg; tmr_nacl = tmr_sess->se_node_acl;
tmr_tpg = tmr_sess->se_tpg;
if (tmr_nacl && tmr_tpg) { if (tmr_nacl && tmr_tpg) {
pr_debug("LUN_RESET: TMR caller fabric: %s" pr_debug("LUN_RESET: TMR caller fabric: %s"
" initiator port %s\n", " initiator port %s\n",
...@@ -413,7 +415,7 @@ int core_tmr_lun_reset( ...@@ -413,7 +415,7 @@ int core_tmr_lun_reset(
dev->transport->name, tas); dev->transport->name, tas);
core_tmr_drain_tmr_list(dev, tmr, preempt_and_abort_list); core_tmr_drain_tmr_list(dev, tmr, preempt_and_abort_list);
core_tmr_drain_state_list(dev, prout_cmd, tmr_nacl, tas, core_tmr_drain_state_list(dev, prout_cmd, tmr_sess, tas,
preempt_and_abort_list); preempt_and_abort_list);
/* /*
......
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