mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-22 05:01:27 +00:00
Patch from Gilad H <gilad.public2@gmail.com> with improvements fixing the following scenario:
1. Commands start going to the init_cmd_list probably because SCST was suspended 2. A command is now waiting in the init_cmd_list, it was not yet completely initialized (more impotently cmd->dev == NULL) 3. A clear task set for the same lun arrives from a different initiator 4. The command is marked as aborted from other initiator and released from the init list. 5. The command gets to the PRE_XMIT_RESPONSE state, since it was aborted the scst_xmit_process_aborted_cmd is called. 6. At this stage since the command is marked as aborted by other initiator the scst checks for the device TAS flag (cmd->dev->tas) however cmd->dev is NULL and we crash on Null pointer de-referencing. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1466 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -445,6 +445,12 @@ enum scst_exec_context {
|
||||
/* Set if the cmd is dead and can be destroyed at any time */
|
||||
#define SCST_CMD_CAN_BE_DESTROYED 3
|
||||
|
||||
/*
|
||||
* Set if the cmd's device has TAS flag set. Used only when aborted by
|
||||
* other initiator.
|
||||
*/
|
||||
#define SCST_CMD_DEVICE_TAS 4
|
||||
|
||||
/*************************************************************
|
||||
** Tgt_dev's async. flags (tgt_dev_flags)
|
||||
*************************************************************/
|
||||
|
||||
@@ -5736,7 +5736,8 @@ void scst_xmit_process_aborted_cmd(struct scst_cmd *cmd)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (cmd->dev->tas) {
|
||||
/* For not yet inited commands cmd->dev can be NULL here */
|
||||
if (test_bit(SCST_CMD_DEVICE_TAS, &cmd->cmd_flags)) {
|
||||
TRACE_MGMT_DBG("Flag ABORTED OTHER set for cmd %p "
|
||||
"(tag %llu), returning TASK ABORTED ", cmd,
|
||||
(long long unsigned int)cmd->tag);
|
||||
|
||||
@@ -4063,9 +4063,25 @@ void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd,
|
||||
spin_lock_irqsave(&other_ini_lock, flags);
|
||||
|
||||
if (other_ini) {
|
||||
struct scst_device *dev = NULL;
|
||||
|
||||
/* Might be necessary if command aborted several times */
|
||||
if (!test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))
|
||||
set_bit(SCST_CMD_ABORTED_OTHER, &cmd->cmd_flags);
|
||||
|
||||
/* Necessary for scst_xmit_process_aborted_cmd */
|
||||
if (cmd->dev != NULL)
|
||||
dev = cmd->dev;
|
||||
else if ((mcmd != NULL) && (mcmd->mcmd_tgt_dev != NULL))
|
||||
dev = mcmd->mcmd_tgt_dev->dev;
|
||||
|
||||
if (dev != NULL) {
|
||||
if (dev->tas)
|
||||
set_bit(SCST_CMD_DEVICE_TAS, &cmd->cmd_flags);
|
||||
} else
|
||||
PRINT_WARNING("Abort cmd %p from other initiator, but "
|
||||
"neither cmd, nor mcmd %p have tgt_dev set, so "
|
||||
"TAS information can be lost", cmd, mcmd);
|
||||
} else {
|
||||
/* Might be necessary if command aborted several times */
|
||||
clear_bit(SCST_CMD_ABORTED_OTHER, &cmd->cmd_flags);
|
||||
|
||||
Reference in New Issue
Block a user