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: v4.9.8~2438^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4347ab5a086efcba449e7a6f0a14d1474060006b;p=platform%2Fkernel%2Flinux-rpi3.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 Reviewed-by: 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 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)