Commit e52a8b45 authored by Alexei Potashnik's avatar Alexei Potashnik Committed by Nicholas Bellinger

qla2xxx: drop cmds/tmrs arrived while session is being deleted

If a new initiator (different WWN) shows up on the same fcport, old
initiator's session is scheduled for deletion. But there is a small
window between it being marked with QLA_SESS_DELETION_IN_PROGRESS
and qlt_unret_sess getting called when new session's commands will
keep finding old session in the fcport map.

This patch drops cmds/tmrs if they find session in the progress of
being deleted.

Cc: <stable@vger.kernel.org> # v3.18+
Signed-off-by: default avatarAlexei Potashnik <alexei@purestorage.com>
Acked-by: default avatarQuinn Tran <quinn.tran@qlogic.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@qlogic.com>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent d20ed91b
...@@ -1477,6 +1477,11 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha, ...@@ -1477,6 +1477,11 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
return; return;
} }
if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, false);
return;
}
rc = __qlt_24xx_handle_abts(vha, abts, sess); rc = __qlt_24xx_handle_abts(vha, abts, sess);
if (rc != 0) { if (rc != 0) {
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf054, ql_dbg(ql_dbg_tgt_mgt, vha, 0xf054,
...@@ -3768,6 +3773,16 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha, ...@@ -3768,6 +3773,16 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
queue_work(qla_tgt_wq, &op->work); queue_work(qla_tgt_wq, &op->work);
return 0; return 0;
} }
/* Another WWN used to have our s_id. Our PLOGI scheduled its
* session deletion, but it's still in sess_del_work wq */
if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
ql_dbg(ql_dbg_io, vha, 0x3061,
"New command while old session %p is being deleted\n",
sess);
return -EFAULT;
}
/* /*
* Do kref_get() before returning + dropping qla_hw_data->hardware_lock. * Do kref_get() before returning + dropping qla_hw_data->hardware_lock.
*/ */
...@@ -3931,6 +3946,9 @@ static int qlt_handle_task_mgmt(struct scsi_qla_host *vha, void *iocb) ...@@ -3931,6 +3946,9 @@ static int qlt_handle_task_mgmt(struct scsi_qla_host *vha, void *iocb)
sizeof(struct atio_from_isp)); sizeof(struct atio_from_isp));
} }
if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS)
return -EFAULT;
return qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0); return qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0);
} }
...@@ -5603,6 +5621,11 @@ static void qlt_abort_work(struct qla_tgt *tgt, ...@@ -5603,6 +5621,11 @@ static void qlt_abort_work(struct qla_tgt *tgt,
if (!sess) if (!sess)
goto out_term; goto out_term;
} else { } else {
if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
sess = NULL;
goto out_term;
}
kref_get(&sess->se_sess->sess_kref); kref_get(&sess->se_sess->sess_kref);
} }
...@@ -5657,6 +5680,11 @@ static void qlt_tmr_work(struct qla_tgt *tgt, ...@@ -5657,6 +5680,11 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
if (!sess) if (!sess)
goto out_term; goto out_term;
} else { } else {
if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
sess = NULL;
goto out_term;
}
kref_get(&sess->se_sess->sess_kref); kref_get(&sess->se_sess->sess_kref);
} }
......
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