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

Commit ebde1ca5 authored by Nicholas Bellinger's avatar Nicholas Bellinger
Browse files

target: Fix TAS handling for multi-session se_node_acls



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>
Cc: stable@vger.kernel.org # 3.10+
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent a6d9bb1c
Loading
Loading
Loading
Loading
+9 −7
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ void core_tmr_release_req(struct se_tmr_req *tmr)
}

static void core_tmr_handle_tas_abort(
	struct se_node_acl *tmr_nacl,
	struct se_session *tmr_sess,
	struct se_cmd *cmd,
	int tas)
{
@@ -84,7 +84,7 @@ static void core_tmr_handle_tas_abort(
	/*
	 * 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;
		transport_send_task_abort(cmd);
	}
@@ -273,7 +273,7 @@ static void core_tmr_drain_tmr_list(
static void core_tmr_drain_state_list(
	struct se_device *dev,
	struct se_cmd *prout_cmd,
	struct se_node_acl *tmr_nacl,
	struct se_session *tmr_sess,
	int tas,
	struct list_head *preempt_and_abort_list)
{
@@ -364,7 +364,7 @@ static void core_tmr_drain_state_list(
		cancel_work_sync(&cmd->work);
		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);
	}
}
@@ -377,6 +377,7 @@ int core_tmr_lun_reset(
{
	struct se_node_acl *tmr_nacl = NULL;
	struct se_portal_group *tmr_tpg = NULL;
	struct se_session *tmr_sess = NULL;
	int tas;
        /*
	 * TASK_ABORTED status bit, this is configurable via ConfigFS
@@ -395,8 +396,9 @@ int core_tmr_lun_reset(
	 * or struct se_device passthrough..
	 */
	if (tmr && tmr->task_cmd && tmr->task_cmd->se_sess) {
		tmr_nacl = tmr->task_cmd->se_sess->se_node_acl;
		tmr_tpg = tmr->task_cmd->se_sess->se_tpg;
		tmr_sess = tmr->task_cmd->se_sess;
		tmr_nacl = tmr_sess->se_node_acl;
		tmr_tpg = tmr_sess->se_tpg;
		if (tmr_nacl && tmr_tpg) {
			pr_debug("LUN_RESET: TMR caller fabric: %s"
				" initiator port %s\n",
@@ -409,7 +411,7 @@ int core_tmr_lun_reset(
		dev->transport->name, tas);

	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);

	/*