diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-04-02 17:55:33 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-04-07 04:48:58 -0400 |
commit | bc0058695a74c0e9aef8bf9582a096ce4924f690 (patch) | |
tree | c8ae45d655184a2eab52e8236cc6c491c3c3820d /drivers/target | |
parent | 395ccb2531021974d309f26e5fb08a8240ac5f84 (diff) |
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.c | 31 |
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( | |||
1905 | schedule_work(&cmd->se_dev->qf_work_queue); | 1905 | schedule_work(&cmd->se_dev->qf_work_queue); |
1906 | } | 1906 | } |
1907 | 1907 | ||
1908 | static bool target_check_read_strip(struct se_cmd *cmd) | ||
1909 | { | ||
1910 | sense_reason_t rc; | ||
1911 | |||
1912 | if (!(cmd->se_sess->sup_prot_ops & TARGET_PROT_DIN_STRIP)) { | ||
1913 | rc = sbc_dif_read_strip(cmd); | ||
1914 | if (rc) { | ||
1915 | cmd->pi_err = rc; | ||
1916 | return true; | ||
1917 | } | ||
1918 | } | ||
1919 | |||
1920 | return false; | ||
1921 | } | ||
1922 | |||
1908 | static void target_complete_ok_work(struct work_struct *work) | 1923 | static void target_complete_ok_work(struct work_struct *work) |
1909 | { | 1924 | { |
1910 | struct se_cmd *cmd = container_of(work, struct se_cmd, work); | 1925 | 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) | |||
1969 | cmd->data_length; | 1984 | cmd->data_length; |
1970 | } | 1985 | } |
1971 | spin_unlock(&cmd->se_lun->lun_sep_lock); | 1986 | spin_unlock(&cmd->se_lun->lun_sep_lock); |
1987 | /* | ||
1988 | * Perform READ_STRIP of PI using software emulation when | ||
1989 | * backend had PI enabled, if the transport will not be | ||
1990 | * performing hardware READ_STRIP offload. | ||
1991 | */ | ||
1992 | if (cmd->prot_op == TARGET_PROT_DIN_STRIP && | ||
1993 | target_check_read_strip(cmd)) { | ||
1994 | ret = transport_send_check_condition_and_sense(cmd, | ||
1995 | cmd->pi_err, 0); | ||
1996 | if (ret == -EAGAIN || ret == -ENOMEM) | ||
1997 | goto queue_full; | ||
1998 | |||
1999 | transport_lun_remove_cmd(cmd); | ||
2000 | transport_cmd_check_stop_to_fabric(cmd); | ||
2001 | return; | ||
2002 | } | ||
1972 | 2003 | ||
1973 | trace_target_cmd_complete(cmd); | 2004 | trace_target_cmd_complete(cmd); |
1974 | ret = cmd->se_tfo->queue_data_in(cmd); | 2005 | ret = cmd->se_tfo->queue_data_in(cmd); |