forked from Minki/linux
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: Alexei Potashnik <alexei@purestorage.com> Acked-by: Quinn Tran <quinn.tran@qlogic.com> Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
d20ed91bb6
commit
e52a8b45b9
@ -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,
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user