aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2012-11-15 14:02:49 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2012-11-15 15:27:21 -0500
commit773cbaf7460aa58c67d4dca83c3f8bca10323bbe (patch)
tree91e6015ade8d62c34c64861f1f3810b3c15a6a25 /drivers
parentcd063bef414c51d79b9c6ea7a8ef8f9d319529bc (diff)
target: Add/check max_write_same_len device attribute + update block limits VPD
This patch adds a new max_write_same_len device attribute for use with WRITE_SAME w/ UNMAP=0 backend emulation. This can be useful for lowering the default backend value (IBLOCK uses 0xFFFF). Also, update block limits VPD emulation code in spc_emulate_evpd_b0() to report MAXIMUM WRITE SAME LENGTH, and enforce max_write_same_len during sbc_parse() -> sbc_setup_write_same() CDB sanity checking for all emulated WRITE_SAME w/ UNMAP=0 cases. (Robert: Move max_write_same_len check in sbc_setup_write_same() to check both WRITE_SAME w/ UNMAP=1 and w/ UNMAP=0 cases) Cc: Christoph Hellwig <hch@lst.de> Cc: Martin K. Petersen <martin.petersen@oracle.com> Cc: Robert Elliott <Elliott@hp.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/target/target_core_configfs.c4
-rw-r--r--drivers/target/target_core_device.c11
-rw-r--r--drivers/target/target_core_internal.h1
-rw-r--r--drivers/target/target_core_sbc.c7
-rw-r--r--drivers/target/target_core_spc.c8
5 files changed, 30 insertions, 1 deletions
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 7b473b66da7b..2b141643f06e 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -676,6 +676,9 @@ SE_DEV_ATTR(unmap_granularity, S_IRUGO | S_IWUSR);
676DEF_DEV_ATTRIB(unmap_granularity_alignment); 676DEF_DEV_ATTRIB(unmap_granularity_alignment);
677SE_DEV_ATTR(unmap_granularity_alignment, S_IRUGO | S_IWUSR); 677SE_DEV_ATTR(unmap_granularity_alignment, S_IRUGO | S_IWUSR);
678 678
679DEF_DEV_ATTRIB(max_write_same_len);
680SE_DEV_ATTR(max_write_same_len, S_IRUGO | S_IWUSR);
681
679CONFIGFS_EATTR_OPS(target_core_dev_attrib, se_dev_attrib, da_group); 682CONFIGFS_EATTR_OPS(target_core_dev_attrib, se_dev_attrib, da_group);
680 683
681static struct configfs_attribute *target_core_dev_attrib_attrs[] = { 684static struct configfs_attribute *target_core_dev_attrib_attrs[] = {
@@ -701,6 +704,7 @@ static struct configfs_attribute *target_core_dev_attrib_attrs[] = {
701 &target_core_dev_attrib_max_unmap_block_desc_count.attr, 704 &target_core_dev_attrib_max_unmap_block_desc_count.attr,
702 &target_core_dev_attrib_unmap_granularity.attr, 705 &target_core_dev_attrib_unmap_granularity.attr,
703 &target_core_dev_attrib_unmap_granularity_alignment.attr, 706 &target_core_dev_attrib_unmap_granularity_alignment.attr,
707 &target_core_dev_attrib_max_write_same_len.attr,
704 NULL, 708 NULL,
705}; 709};
706 710
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 599374e6d245..54439bc42dab 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -706,6 +706,16 @@ int se_dev_set_unmap_granularity_alignment(
706 return 0; 706 return 0;
707} 707}
708 708
709int se_dev_set_max_write_same_len(
710 struct se_device *dev,
711 u32 max_write_same_len)
712{
713 dev->dev_attrib.max_write_same_len = max_write_same_len;
714 pr_debug("dev[%p]: Set max_write_same_len: %u\n",
715 dev, dev->dev_attrib.max_write_same_len);
716 return 0;
717}
718
709int se_dev_set_emulate_dpo(struct se_device *dev, int flag) 719int se_dev_set_emulate_dpo(struct se_device *dev, int flag)
710{ 720{
711 if (flag != 0 && flag != 1) { 721 if (flag != 0 && flag != 1) {
@@ -1393,6 +1403,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
1393 dev->dev_attrib.unmap_granularity = DA_UNMAP_GRANULARITY_DEFAULT; 1403 dev->dev_attrib.unmap_granularity = DA_UNMAP_GRANULARITY_DEFAULT;
1394 dev->dev_attrib.unmap_granularity_alignment = 1404 dev->dev_attrib.unmap_granularity_alignment =
1395 DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT; 1405 DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT;
1406 dev->dev_attrib.max_write_same_len = DA_MAX_WRITE_SAME_LEN;
1396 dev->dev_attrib.fabric_max_sectors = DA_FABRIC_MAX_SECTORS; 1407 dev->dev_attrib.fabric_max_sectors = DA_FABRIC_MAX_SECTORS;
1397 dev->dev_attrib.optimal_sectors = DA_FABRIC_MAX_SECTORS; 1408 dev->dev_attrib.optimal_sectors = DA_FABRIC_MAX_SECTORS;
1398 1409
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
index bc9c52284845..93e9c1f580b0 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -24,6 +24,7 @@ int se_dev_set_max_unmap_lba_count(struct se_device *, u32);
24int se_dev_set_max_unmap_block_desc_count(struct se_device *, u32); 24int se_dev_set_max_unmap_block_desc_count(struct se_device *, u32);
25int se_dev_set_unmap_granularity(struct se_device *, u32); 25int se_dev_set_unmap_granularity(struct se_device *, u32);
26int se_dev_set_unmap_granularity_alignment(struct se_device *, u32); 26int se_dev_set_unmap_granularity_alignment(struct se_device *, u32);
27int se_dev_set_max_write_same_len(struct se_device *, u32);
27int se_dev_set_emulate_dpo(struct se_device *, int); 28int se_dev_set_emulate_dpo(struct se_device *, int);
28int se_dev_set_emulate_fua_write(struct se_device *, int); 29int se_dev_set_emulate_fua_write(struct se_device *, int);
29int se_dev_set_emulate_fua_read(struct se_device *, int); 30int se_dev_set_emulate_fua_read(struct se_device *, int);
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index a5a8f463004b..45e11d0e38c4 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -238,12 +238,19 @@ static inline unsigned long long transport_lba_64_ext(unsigned char *cdb)
238static sense_reason_t 238static sense_reason_t
239sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *ops) 239sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *ops)
240{ 240{
241 unsigned int sectors = spc_get_write_same_sectors(cmd);
242
241 if ((flags[0] & 0x04) || (flags[0] & 0x02)) { 243 if ((flags[0] & 0x04) || (flags[0] & 0x02)) {
242 pr_err("WRITE_SAME PBDATA and LBDATA" 244 pr_err("WRITE_SAME PBDATA and LBDATA"
243 " bits not supported for Block Discard" 245 " bits not supported for Block Discard"
244 " Emulation\n"); 246 " Emulation\n");
245 return TCM_UNSUPPORTED_SCSI_OPCODE; 247 return TCM_UNSUPPORTED_SCSI_OPCODE;
246 } 248 }
249 if (sectors > cmd->se_dev->dev_attrib.max_write_same_len) {
250 pr_warn("WRITE_SAME sectors: %u exceeds max_write_same_len: %u\n",
251 sectors, cmd->se_dev->dev_attrib.max_write_same_len);
252 return TCM_INVALID_CDB_FIELD;
253 }
247 /* 254 /*
248 * Special case for WRITE_SAME w/ UNMAP=1 that ends up getting 255 * Special case for WRITE_SAME w/ UNMAP=1 that ends up getting
249 * translated into block discard requests within backend code. 256 * translated into block discard requests within backend code.
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index 4b3c18305ec8..cf1b8bb310c4 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -465,7 +465,7 @@ spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
465 * Exit now if we don't support TP. 465 * Exit now if we don't support TP.
466 */ 466 */
467 if (!have_tp) 467 if (!have_tp)
468 return 0; 468 goto max_write_same;
469 469
470 /* 470 /*
471 * Set MAXIMUM UNMAP LBA COUNT 471 * Set MAXIMUM UNMAP LBA COUNT
@@ -491,6 +491,12 @@ spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
491 if (dev->dev_attrib.unmap_granularity_alignment != 0) 491 if (dev->dev_attrib.unmap_granularity_alignment != 0)
492 buf[32] |= 0x80; /* Set the UGAVALID bit */ 492 buf[32] |= 0x80; /* Set the UGAVALID bit */
493 493
494 /*
495 * MAXIMUM WRITE SAME LENGTH
496 */
497max_write_same:
498 put_unaligned_be64(dev->dev_attrib.max_write_same_len, &buf[36]);
499
494 return 0; 500 return 0;
495} 501}
496 502