From: Nicholas Bellinger <[email protected]>

This patch modifies existing transport_complete_*() code
to avoid invoking target_core_fabric_ops->queue_data_in()
driver callbacks for I/O READs with non-GOOD SAM status.

Some initiators expect GOOD status when a DATA-IN payload
transfer is involved, so to be safe go ahead and always
invoke target_core_fabric_ops->queue_status() to generate
fabric responses instead.

Note this is a prerequisite for IBLOCK supporting retriable
status, so SAM_STAT_BUSY + SAM_STAT_TASK_SET_FULL always
generates fabric driver responses instead of initiating
DataIN payload transfer when non-GOOD status is present

Cc: Christoph Hellwig <[email protected]>
Cc: Hannes Reinecke <[email protected]>
Cc: Sagi Grimberg <[email protected]>
Cc: Andy Grover <[email protected]>
Cc: Mike Christie <[email protected]>
Signed-off-by: Nicholas Bellinger <[email protected]>
---
 drivers/target/target_core_transport.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index f5ad9e0..784dd22 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1997,6 +1997,9 @@ static void transport_complete_qf(struct se_cmd *cmd)
 
        switch (cmd->data_direction) {
        case DMA_FROM_DEVICE:
+               if (cmd->scsi_status)
+                       goto queue_status;
+
                trace_target_cmd_complete(cmd);
                ret = cmd->se_tfo->queue_data_in(cmd);
                break;
@@ -2007,6 +2010,7 @@ static void transport_complete_qf(struct se_cmd *cmd)
                }
                /* Fall through for DMA_TO_DEVICE */
        case DMA_NONE:
+queue_status:
                trace_target_cmd_complete(cmd);
                ret = cmd->se_tfo->queue_status(cmd);
                break;
@@ -2128,6 +2132,9 @@ static void target_complete_ok_work(struct work_struct 
*work)
 queue_rsp:
        switch (cmd->data_direction) {
        case DMA_FROM_DEVICE:
+               if (cmd->scsi_status)
+                       goto queue_status;
+
                atomic_long_add(cmd->data_length,
                                &cmd->se_lun->lun_stats.tx_data_octets);
                /*
@@ -2167,6 +2174,7 @@ queue_rsp:
                }
                /* Fall through for DMA_TO_DEVICE */
        case DMA_NONE:
+queue_status:
                trace_target_cmd_complete(cmd);
                ret = cmd->se_tfo->queue_status(cmd);
                if (ret == -EAGAIN || ret == -ENOMEM)
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to