diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-02-08 06:06:17 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-04-08 02:26:43 -0400 |
commit | 5132d1e655dc4befcc075ef32a261eb9733bb04c (patch) | |
tree | e3c4c4b661427e64eb901db72747d7ad66132f52 /drivers/target | |
parent | aa58b53168e12342aa0561c12bf5d6729487c63e (diff) |
target: Add internal WRITE_STRIP support
This patch adds WRITE_STRIP support in target_write_prot_action() that
invokes sbc_dif_verify_write() for checking T10-PI metadata before
submitting the I/O to a backend driver.
Upon verify failure, the specific sense code is propigated up the
failure path up to transport_generic_request_failure().
Also, update sbc_dif_verify_write() to only perform the subsequent
protection metadata copy when a valid *sg is passed.
(Use ilog2 instead of division and unlikely for pi_err - Sagi)
Reviewed-by: Martin Petersen <martin.petersen@oracle.com>
Reviewed-by: Sagi Grimberg <sagig@mellanox.com>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_sbc.c | 3 | ||||
-rw-r--r-- | drivers/target/target_core_transport.c | 16 |
2 files changed, 19 insertions, 0 deletions
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 67bc1886f004..315ff641408b 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
@@ -1342,6 +1342,9 @@ sbc_dif_verify_write(struct se_cmd *cmd, sector_t start, unsigned int sectors, | |||
1342 | kunmap_atomic(paddr); | 1342 | kunmap_atomic(paddr); |
1343 | kunmap_atomic(daddr); | 1343 | kunmap_atomic(daddr); |
1344 | } | 1344 | } |
1345 | if (!sg) | ||
1346 | return 0; | ||
1347 | |||
1345 | sbc_dif_copy_prot(cmd, sectors, false, sg, sg_off); | 1348 | sbc_dif_copy_prot(cmd, sectors, false, sg, sg_off); |
1346 | 1349 | ||
1347 | return 0; | 1350 | return 0; |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 2a0c36bf3226..0fe58bfabfc2 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -1740,6 +1740,7 @@ void __target_execute_cmd(struct se_cmd *cmd) | |||
1740 | 1740 | ||
1741 | static int target_write_prot_action(struct se_cmd *cmd) | 1741 | static int target_write_prot_action(struct se_cmd *cmd) |
1742 | { | 1742 | { |
1743 | u32 sectors; | ||
1743 | /* | 1744 | /* |
1744 | * Perform WRITE_INSERT of PI using software emulation when backend | 1745 | * Perform WRITE_INSERT of PI using software emulation when backend |
1745 | * device has PI enabled, if the transport has not already generated | 1746 | * device has PI enabled, if the transport has not already generated |
@@ -1750,6 +1751,21 @@ static int target_write_prot_action(struct se_cmd *cmd) | |||
1750 | if (!(cmd->se_sess->sup_prot_ops & TARGET_PROT_DOUT_INSERT)) | 1751 | if (!(cmd->se_sess->sup_prot_ops & TARGET_PROT_DOUT_INSERT)) |
1751 | sbc_dif_generate(cmd); | 1752 | sbc_dif_generate(cmd); |
1752 | break; | 1753 | break; |
1754 | case TARGET_PROT_DOUT_STRIP: | ||
1755 | if (cmd->se_sess->sup_prot_ops & TARGET_PROT_DOUT_STRIP) | ||
1756 | break; | ||
1757 | |||
1758 | sectors = cmd->data_length >> ilog2(cmd->se_dev->dev_attrib.block_size); | ||
1759 | cmd->pi_err = sbc_dif_verify_write(cmd, cmd->t_task_lba, | ||
1760 | sectors, 0, NULL, 0); | ||
1761 | if (unlikely(cmd->pi_err)) { | ||
1762 | spin_lock_irq(&cmd->t_state_lock); | ||
1763 | cmd->transport_state &= ~CMD_T_BUSY|CMD_T_SENT; | ||
1764 | spin_unlock_irq(&cmd->t_state_lock); | ||
1765 | transport_generic_request_failure(cmd, cmd->pi_err); | ||
1766 | return -1; | ||
1767 | } | ||
1768 | break; | ||
1753 | default: | 1769 | default: |
1754 | break; | 1770 | break; |
1755 | } | 1771 | } |