summaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2014-04-02 23:55:33 +0200
committerNicholas Bellinger <nab@linux-iscsi.org>2014-04-07 10:48:58 +0200
commitbc0058695a74c0e9aef8bf9582a096ce4924f690 (patch)
treec8ae45d655184a2eab52e8236cc6c491c3c3820d /drivers/target
parenttarget/sbc: Add sbc_dif_read_strip software emulation (diff)
downloadlinux-bc0058695a74c0e9aef8bf9582a096ce4924f690.tar.xz
linux-bc0058695a74c0e9aef8bf9582a096ce4924f690.zip
target: Enable READ_STRIP emulation in target_complete_ok_work
This patch enables the use of READ_STRIP software emulation in target_complete_ok_work() code for I/O READs. This is useful when the fabric does not support READ_STRIP hardware offload, but would still like to interact with backend device that have T10 PI enabled. v2 changes: - Move TARGET_PROT_DIN_STRIP check from target_check_read_strip() into target_complete_ok_work() (Sagi) Cc: Martin K. Petersen <martin.petersen@oracle.com> Cc: Sagi Grimberg <sagig@mellanox.com> Cc: Or Gerlitz <ogerlitz@mellanox.com> Cc: Quinn Tran <quinn.tran@qlogic.com> Cc: Giridhar Malavali <giridhar.malavali@qlogic.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/target_core_transport.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index a7a4ef2d589e..d4b98690a736 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1905,6 +1905,21 @@ static void transport_handle_queue_full(
schedule_work(&cmd->se_dev->qf_work_queue);
}
+static bool target_check_read_strip(struct se_cmd *cmd)
+{
+ sense_reason_t rc;
+
+ if (!(cmd->se_sess->sup_prot_ops & TARGET_PROT_DIN_STRIP)) {
+ rc = sbc_dif_read_strip(cmd);
+ if (rc) {
+ cmd->pi_err = rc;
+ return true;
+ }
+ }
+
+ return false;
+}
+
static void target_complete_ok_work(struct work_struct *work)
{
struct se_cmd *cmd = container_of(work, struct se_cmd, work);
@@ -1969,6 +1984,22 @@ static void target_complete_ok_work(struct work_struct *work)
cmd->data_length;
}
spin_unlock(&cmd->se_lun->lun_sep_lock);
+ /*
+ * Perform READ_STRIP of PI using software emulation when
+ * backend had PI enabled, if the transport will not be
+ * performing hardware READ_STRIP offload.
+ */
+ if (cmd->prot_op == TARGET_PROT_DIN_STRIP &&
+ target_check_read_strip(cmd)) {
+ ret = transport_send_check_condition_and_sense(cmd,
+ cmd->pi_err, 0);
+ if (ret == -EAGAIN || ret == -ENOMEM)
+ goto queue_full;
+
+ transport_lun_remove_cmd(cmd);
+ transport_cmd_check_stop_to_fabric(cmd);
+ return;
+ }
trace_target_cmd_complete(cmd);
ret = cmd->se_tfo->queue_data_in(cmd);