tcm: make pi data verification configurable
authorDmitry Monakhov <dmonakhov@openvz.org>
Fri, 31 Mar 2017 15:53:36 +0000 (19:53 +0400)
committerNicholas Bellinger <nab@linux-iscsi.org>
Tue, 2 May 2017 05:20:58 +0000 (22:20 -0700)
Currently ramdisk and fileio always perform PI verification
before and after backend IO. This approach is not very flexible.
Because some one may want to postpone this work to other layers in
IO stack. For example if we want to test blk_integrity_profile

testcase:
https://github.com/dmonakhov/xfstests/commit/dee408c868861d6b6871dbb3381facee7effdbe4
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
drivers/target/target_core_configfs.c
drivers/target/target_core_file.c
drivers/target/target_core_rd.c
include/target/target_core_base.h

index 70657fd564406b3c137b02c3f61824f387f554aa..a34a86652b96462fb5ba2345210654c5882d675e 100644 (file)
@@ -533,6 +533,7 @@ DEF_CONFIGFS_ATTRIB_SHOW(emulate_3pc);
 DEF_CONFIGFS_ATTRIB_SHOW(pi_prot_type);
 DEF_CONFIGFS_ATTRIB_SHOW(hw_pi_prot_type);
 DEF_CONFIGFS_ATTRIB_SHOW(pi_prot_format);
+DEF_CONFIGFS_ATTRIB_SHOW(pi_prot_verify);
 DEF_CONFIGFS_ATTRIB_SHOW(enforce_pr_isids);
 DEF_CONFIGFS_ATTRIB_SHOW(is_nonrot);
 DEF_CONFIGFS_ATTRIB_SHOW(emulate_rest_reord);
@@ -823,6 +824,7 @@ static ssize_t pi_prot_type_store(struct config_item *item,
                ret = dev->transport->init_prot(dev);
                if (ret) {
                        da->pi_prot_type = old_prot;
+                       da->pi_prot_verify = (bool) da->pi_prot_type;
                        return ret;
                }
 
@@ -830,6 +832,7 @@ static ssize_t pi_prot_type_store(struct config_item *item,
                dev->transport->free_prot(dev);
        }
 
+       da->pi_prot_verify = (bool) da->pi_prot_type;
        pr_debug("dev[%p]: SE Device Protection Type: %d\n", dev, flag);
        return count;
 }
@@ -872,6 +875,35 @@ static ssize_t pi_prot_format_store(struct config_item *item,
        return count;
 }
 
+static ssize_t pi_prot_verify_store(struct config_item *item,
+               const char *page, size_t count)
+{
+       struct se_dev_attrib *da = to_attrib(item);
+       bool flag;
+       int ret;
+
+       ret = strtobool(page, &flag);
+       if (ret < 0)
+               return ret;
+
+       if (!flag) {
+               da->pi_prot_verify = flag;
+               return count;
+       }
+       if (da->hw_pi_prot_type) {
+               pr_warn("DIF protection enabled on underlying hardware,"
+                       " ignoring\n");
+               return count;
+       }
+       if (!da->pi_prot_type) {
+               pr_warn("DIF protection not supported by backend, ignoring\n");
+               return count;
+       }
+       da->pi_prot_verify = flag;
+
+       return count;
+}
+
 static ssize_t force_pr_aptpl_store(struct config_item *item,
                const char *page, size_t count)
 {
@@ -1067,6 +1099,7 @@ CONFIGFS_ATTR(, emulate_3pc);
 CONFIGFS_ATTR(, pi_prot_type);
 CONFIGFS_ATTR_RO(, hw_pi_prot_type);
 CONFIGFS_ATTR(, pi_prot_format);
+CONFIGFS_ATTR(, pi_prot_verify);
 CONFIGFS_ATTR(, enforce_pr_isids);
 CONFIGFS_ATTR(, is_nonrot);
 CONFIGFS_ATTR(, emulate_rest_reord);
@@ -1104,6 +1137,7 @@ struct configfs_attribute *sbc_attrib_attrs[] = {
        &attr_pi_prot_type,
        &attr_hw_pi_prot_type,
        &attr_pi_prot_format,
+       &attr_pi_prot_verify,
        &attr_enforce_pr_isids,
        &attr_is_nonrot,
        &attr_emulate_rest_reord,
index dd8f32055266def613462c205e4e528f7933455c..1bf6c31e4c21459ec377db58f049ade94faef5a3 100644 (file)
@@ -554,7 +554,8 @@ fd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
                ret = fd_do_rw(cmd, file, dev->dev_attrib.block_size,
                               sgl, sgl_nents, cmd->data_length, 0);
 
-               if (ret > 0 && cmd->prot_type && dev->dev_attrib.pi_prot_type) {
+               if (ret > 0 && cmd->prot_type && dev->dev_attrib.pi_prot_type &&
+                   dev->dev_attrib.pi_prot_verify) {
                        u32 sectors = cmd->data_length >>
                                        ilog2(dev->dev_attrib.block_size);
 
@@ -564,7 +565,8 @@ fd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
                                return rc;
                }
        } else {
-               if (cmd->prot_type && dev->dev_attrib.pi_prot_type) {
+               if (cmd->prot_type && dev->dev_attrib.pi_prot_type &&
+                   dev->dev_attrib.pi_prot_verify) {
                        u32 sectors = cmd->data_length >>
                                        ilog2(dev->dev_attrib.block_size);
 
index ddc216c9f1f63dcdea780b5be5edbf34d9cc93d4..5f23f341f8d3fe708354019790854a7d496775ae 100644 (file)
@@ -410,7 +410,7 @@ static sense_reason_t rd_do_prot_rw(struct se_cmd *cmd, bool is_read)
        u32 prot_offset, prot_page;
        u32 prot_npages __maybe_unused;
        u64 tmp;
-       sense_reason_t rc = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+       sense_reason_t rc = 0;
 
        tmp = cmd->t_task_lba * se_dev->prot_length;
        prot_offset = do_div(tmp, PAGE_SIZE);
@@ -423,13 +423,14 @@ static sense_reason_t rd_do_prot_rw(struct se_cmd *cmd, bool is_read)
        prot_sg = &prot_table->sg_table[prot_page -
                                        prot_table->page_start_offset];
 
-       if (is_read)
-               rc = sbc_dif_verify(cmd, cmd->t_task_lba, sectors, 0,
-                                   prot_sg, prot_offset);
-       else
-               rc = sbc_dif_verify(cmd, cmd->t_task_lba, sectors, 0,
-                                   cmd->t_prot_sg, 0);
-
+       if (se_dev->dev_attrib.pi_prot_verify) {
+               if (is_read)
+                       rc = sbc_dif_verify(cmd, cmd->t_task_lba, sectors, 0,
+                                           prot_sg, prot_offset);
+               else
+                       rc = sbc_dif_verify(cmd, cmd->t_task_lba, sectors, 0,
+                                           cmd->t_prot_sg, 0);
+       }
        if (!rc)
                sbc_dif_copy_prot(cmd, sectors, is_read, prot_sg, prot_offset);
 
index ccfad0e9c2cdbd68f13c809c7ed6414b2c0c97c1..0c1dce2ac6f0239a90d3e86bff2afd3b0f318128 100644 (file)
@@ -664,6 +664,7 @@ struct se_dev_attrib {
        int             pi_prot_format;
        enum target_prot_type pi_prot_type;
        enum target_prot_type hw_pi_prot_type;
+       int             pi_prot_verify;
        int             enforce_pr_isids;
        int             force_pr_aptpl;
        int             is_nonrot;