summaryrefslogtreecommitdiff
path: root/drivers/target
diff options
context:
space:
mode:
authorMike Christie <michael.christie@oracle.com>2021-09-30 05:04:18 +0300
committerMartin K. Petersen <martin.petersen@oracle.com>2021-10-19 05:38:35 +0300
commit945a160794a90442329fdd6ff30f02a5c5b39481 (patch)
treecb8e855c574e6cc026c810ddf94d403e6b2abb41 /drivers/target
parent25d542a8537455a3335448a3fa53cf3704883389 (diff)
downloadlinux-945a160794a90442329fdd6ff30f02a5c5b39481.tar.xz
scsi: target: Fix ordered CMD_T_SENT handling
We can race where target_handle_task_attr() has put the cmd on the delayed_cmd_list. Then target_restart_delayed_cmds() has removed it and set CMD_T_SENT, but then target_execute_cmd() now clears that bit. This patch moves the clearing to before we've put the cmd on the list. Link: https://lore.kernel.org/r/20210930020422.92578-2-michael.christie@oracle.com Reviewed-by: Lee Duncan <lduncan@suse.com> Signed-off-by: Mike Christie <michael.christie@oracle.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/target_core_transport.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 4a0055ab9151..64e0477c7644 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -2200,6 +2200,10 @@ static bool target_handle_task_attr(struct se_cmd *cmd)
if (atomic_read(&dev->dev_ordered_sync) == 0)
return false;
+ spin_lock_irq(&cmd->t_state_lock);
+ cmd->transport_state &= ~CMD_T_SENT;
+ spin_unlock_irq(&cmd->t_state_lock);
+
spin_lock(&dev->delayed_cmd_lock);
list_add_tail(&cmd->se_delayed_node, &dev->delayed_cmd_list);
spin_unlock(&dev->delayed_cmd_lock);
@@ -2228,12 +2232,8 @@ void target_execute_cmd(struct se_cmd *cmd)
if (target_write_prot_action(cmd))
return;
- if (target_handle_task_attr(cmd)) {
- spin_lock_irq(&cmd->t_state_lock);
- cmd->transport_state &= ~CMD_T_SENT;
- spin_unlock_irq(&cmd->t_state_lock);
+ if (target_handle_task_attr(cmd))
return;
- }
__target_execute_cmd(cmd, true);
}