scsi: target: Fix ordered CMD_T_SENT handling
authorMike Christie <michael.christie@oracle.com>
Thu, 30 Sep 2021 02:04:18 +0000 (21:04 -0500)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 19 Oct 2021 02:38:35 +0000 (22:38 -0400)
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>
drivers/target/target_core_transport.c

index 4a0055a..64e0477 100644 (file)
@@ -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);
 }