From: Nicholas Bellinger <nab@xxxxxxxxxxxxx> COMPARE_AND_WRITE uses cmd->t_bidi_data_sg for it's READ payload and cmd->data_direction == DMA_TO_DEVICE, but the payload is only used for internal comparision, and never actually sent over the wire. So, check for this special case in to avoid TFO->queue_data_in() within transport_complete_qf() + target_complete_ok_work() code. Cc: Christoph Hellwig <hch@xxxxxx> Cc: Hannes Reinecke <hare@xxxxxxx> Cc: Martin Petersen <martin.petersen@xxxxxxxxxx> Cc: Chris Mason <chris.mason@xxxxxxxxxxxx> Cc: James Bottomley <JBottomley@xxxxxxxxxxxxx> Cc: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx> Signed-off-by: Nicholas Bellinger <nab@xxxxxxxxxxxxx> --- drivers/target/target_core_transport.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index f7dc479..60d1336 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1832,7 +1832,8 @@ static void transport_complete_qf(struct se_cmd *cmd) ret = cmd->se_tfo->queue_data_in(cmd); break; case DMA_TO_DEVICE: - if (cmd->t_bidi_data_sg) { + if (cmd->t_bidi_data_sg && + cmd->t_task_cdb[0] != COMPARE_AND_WRITE) { ret = cmd->se_tfo->queue_data_in(cmd); if (ret < 0) break; @@ -1947,7 +1948,8 @@ static void target_complete_ok_work(struct work_struct *work) /* * Check if we need to send READ payload for BIDI-COMMAND */ - if (cmd->t_bidi_data_sg) { + if (cmd->t_bidi_data_sg && + cmd->t_task_cdb[0] != COMPARE_AND_WRITE) { spin_lock(&cmd->se_lun->lun_sep_lock); if (cmd->se_lun->lun_sep) { cmd->se_lun->lun_sep->sep_stats.tx_data_octets += -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html