From: Nicholas Bellinger Date: Sat, 5 Mar 2016 06:30:52 +0000 (-0800) Subject: target: Avoid DataIN transfers for non-GOOD SAM status X-Git-Tag: next-20160307~17^2~1 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=2654cf300fc2bc27fa9ff7bb7c092b97e76acc9a;p=karo-tx-linux.git target: Avoid DataIN transfers for non-GOOD SAM status 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 Cc: Hannes Reinecke Cc: Sagi Grimberg Cc: Andy Grover Cc: Mike Christie Signed-off-by: Nicholas Bellinger --- diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index f5ad9e063b65..784dd22d33a3 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)