tcm: make pi data verification configurable

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:
dee408c868
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
Dmitry Monakhov 2017-03-31 19:53:36 +04:00 committed by Nicholas Bellinger
parent f11b55d135
commit 056e8924a0
4 changed files with 48 additions and 10 deletions

View File

@ -533,6 +533,7 @@ DEF_CONFIGFS_ATTRIB_SHOW(emulate_3pc);
DEF_CONFIGFS_ATTRIB_SHOW(pi_prot_type); DEF_CONFIGFS_ATTRIB_SHOW(pi_prot_type);
DEF_CONFIGFS_ATTRIB_SHOW(hw_pi_prot_type); DEF_CONFIGFS_ATTRIB_SHOW(hw_pi_prot_type);
DEF_CONFIGFS_ATTRIB_SHOW(pi_prot_format); 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(enforce_pr_isids);
DEF_CONFIGFS_ATTRIB_SHOW(is_nonrot); DEF_CONFIGFS_ATTRIB_SHOW(is_nonrot);
DEF_CONFIGFS_ATTRIB_SHOW(emulate_rest_reord); 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); ret = dev->transport->init_prot(dev);
if (ret) { if (ret) {
da->pi_prot_type = old_prot; da->pi_prot_type = old_prot;
da->pi_prot_verify = (bool) da->pi_prot_type;
return ret; return ret;
} }
@ -830,6 +832,7 @@ static ssize_t pi_prot_type_store(struct config_item *item,
dev->transport->free_prot(dev); 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); pr_debug("dev[%p]: SE Device Protection Type: %d\n", dev, flag);
return count; return count;
} }
@ -872,6 +875,35 @@ static ssize_t pi_prot_format_store(struct config_item *item,
return count; 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, static ssize_t force_pr_aptpl_store(struct config_item *item,
const char *page, size_t count) const char *page, size_t count)
{ {
@ -1067,6 +1099,7 @@ CONFIGFS_ATTR(, emulate_3pc);
CONFIGFS_ATTR(, pi_prot_type); CONFIGFS_ATTR(, pi_prot_type);
CONFIGFS_ATTR_RO(, hw_pi_prot_type); CONFIGFS_ATTR_RO(, hw_pi_prot_type);
CONFIGFS_ATTR(, pi_prot_format); CONFIGFS_ATTR(, pi_prot_format);
CONFIGFS_ATTR(, pi_prot_verify);
CONFIGFS_ATTR(, enforce_pr_isids); CONFIGFS_ATTR(, enforce_pr_isids);
CONFIGFS_ATTR(, is_nonrot); CONFIGFS_ATTR(, is_nonrot);
CONFIGFS_ATTR(, emulate_rest_reord); CONFIGFS_ATTR(, emulate_rest_reord);
@ -1104,6 +1137,7 @@ struct configfs_attribute *sbc_attrib_attrs[] = {
&attr_pi_prot_type, &attr_pi_prot_type,
&attr_hw_pi_prot_type, &attr_hw_pi_prot_type,
&attr_pi_prot_format, &attr_pi_prot_format,
&attr_pi_prot_verify,
&attr_enforce_pr_isids, &attr_enforce_pr_isids,
&attr_is_nonrot, &attr_is_nonrot,
&attr_emulate_rest_reord, &attr_emulate_rest_reord,

View 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, ret = fd_do_rw(cmd, file, dev->dev_attrib.block_size,
sgl, sgl_nents, cmd->data_length, 0); 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 >> u32 sectors = cmd->data_length >>
ilog2(dev->dev_attrib.block_size); 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; return rc;
} }
} else { } 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 >> u32 sectors = cmd->data_length >>
ilog2(dev->dev_attrib.block_size); ilog2(dev->dev_attrib.block_size);

View 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_offset, prot_page;
u32 prot_npages __maybe_unused; u32 prot_npages __maybe_unused;
u64 tmp; 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; tmp = cmd->t_task_lba * se_dev->prot_length;
prot_offset = do_div(tmp, PAGE_SIZE); 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_sg = &prot_table->sg_table[prot_page -
prot_table->page_start_offset]; prot_table->page_start_offset];
if (is_read) if (se_dev->dev_attrib.pi_prot_verify) {
rc = sbc_dif_verify(cmd, cmd->t_task_lba, sectors, 0, if (is_read)
prot_sg, prot_offset); rc = sbc_dif_verify(cmd, cmd->t_task_lba, sectors, 0,
else prot_sg, prot_offset);
rc = sbc_dif_verify(cmd, cmd->t_task_lba, sectors, 0, else
cmd->t_prot_sg, 0); rc = sbc_dif_verify(cmd, cmd->t_task_lba, sectors, 0,
cmd->t_prot_sg, 0);
}
if (!rc) if (!rc)
sbc_dif_copy_prot(cmd, sectors, is_read, prot_sg, prot_offset); sbc_dif_copy_prot(cmd, sectors, is_read, prot_sg, prot_offset);

View File

@ -664,6 +664,7 @@ struct se_dev_attrib {
int pi_prot_format; int pi_prot_format;
enum target_prot_type pi_prot_type; enum target_prot_type pi_prot_type;
enum target_prot_type hw_pi_prot_type; enum target_prot_type hw_pi_prot_type;
int pi_prot_verify;
int enforce_pr_isids; int enforce_pr_isids;
int force_pr_aptpl; int force_pr_aptpl;
int is_nonrot; int is_nonrot;