]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/target/target_core_transport.c
target: add SAM_STAT_BUSY sense reason
[linux.git] / drivers / target / target_core_transport.c
index 473d652e48163f4e307e2b69ea7572f7a9d4c30d..74b646f165d4e4fea16c955884dcf2a119cb82c3 100644 (file)
@@ -1729,9 +1729,6 @@ void transport_generic_request_failure(struct se_cmd *cmd,
 {
        int ret = 0, post_ret = 0;
 
-       if (transport_check_aborted_status(cmd, 1))
-               return;
-
        pr_debug("-----[ Storage Engine Exception; sense_reason %d\n",
                 sense_reason);
        target_show_cmd("-----[ ", cmd);
@@ -1740,6 +1737,7 @@ void transport_generic_request_failure(struct se_cmd *cmd,
         * For SAM Task Attribute emulation for failed struct se_cmd
         */
        transport_complete_task_attr(cmd);
+
        /*
         * Handle special case for COMPARE_AND_WRITE failure, where the
         * callback is expected to drop the per device ->caw_sem.
@@ -1748,6 +1746,9 @@ void transport_generic_request_failure(struct se_cmd *cmd,
             cmd->transport_complete_callback)
                cmd->transport_complete_callback(cmd, false, &post_ret);
 
+       if (transport_check_aborted_status(cmd, 1))
+               return;
+
        switch (sense_reason) {
        case TCM_NON_EXISTENT_LUN:
        case TCM_UNSUPPORTED_SCSI_OPCODE:
@@ -1773,6 +1774,9 @@ void transport_generic_request_failure(struct se_cmd *cmd,
        case TCM_OUT_OF_RESOURCES:
                cmd->scsi_status = SAM_STAT_TASK_SET_FULL;
                goto queue_status;
+       case TCM_LUN_BUSY:
+               cmd->scsi_status = SAM_STAT_BUSY;
+               goto queue_status;
        case TCM_RESERVATION_CONFLICT:
                /*
                 * No SENSE Data payload for this case, set SCSI Status
@@ -1974,6 +1978,7 @@ void target_execute_cmd(struct se_cmd *cmd)
        }
 
        cmd->t_state = TRANSPORT_PROCESSING;
+       cmd->transport_state &= ~CMD_T_PRE_EXECUTE;
        cmd->transport_state |= CMD_T_ACTIVE | CMD_T_SENT;
        spin_unlock_irq(&cmd->t_state_lock);
 
@@ -2011,6 +2016,8 @@ static void target_restart_delayed_cmds(struct se_device *dev)
                list_del(&cmd->se_delayed_node);
                spin_unlock(&dev->delayed_cmd_lock);
 
+               cmd->transport_state |= CMD_T_SENT;
+
                __target_execute_cmd(cmd, true);
 
                if (cmd->sam_task_attr == TCM_ORDERED_TAG)
@@ -2046,6 +2053,8 @@ static void transport_complete_task_attr(struct se_cmd *cmd)
                pr_debug("Incremented dev_cur_ordered_id: %u for ORDERED\n",
                         dev->dev_cur_ordered_id);
        }
+       cmd->se_cmd_flags &= ~SCF_TASK_ATTR_SET;
+
 restart:
        target_restart_delayed_cmds(dev);
 }
@@ -2555,7 +2564,20 @@ EXPORT_SYMBOL(transport_generic_new_cmd);
 
 static void transport_write_pending_qf(struct se_cmd *cmd)
 {
+       unsigned long flags;
        int ret;
+       bool stop;
+
+       spin_lock_irqsave(&cmd->t_state_lock, flags);
+       stop = (cmd->transport_state & (CMD_T_STOP | CMD_T_ABORTED));
+       spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+
+       if (stop) {
+               pr_debug("%s:%d CMD_T_STOP|CMD_T_ABORTED for ITT: 0x%08llx\n",
+                       __func__, __LINE__, cmd->tag);
+               complete_all(&cmd->t_transport_stop_comp);
+               return;
+       }
 
        ret = cmd->se_tfo->write_pending(cmd);
        if (ret) {
@@ -2649,6 +2671,7 @@ int target_get_sess_cmd(struct se_cmd *se_cmd, bool ack_kref)
                ret = -ESHUTDOWN;
                goto out;
        }
+       se_cmd->transport_state |= CMD_T_PRE_EXECUTE;
        list_add_tail(&se_cmd->se_cmd_list, &se_sess->sess_cmd_list);
 out:
        spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);