Commit e22a7f075226c51f3f71b922e9eeb4f99fac1475

Authored by Roland Dreier
Committed by Nicholas Bellinger
1 parent b2eb705e00

target: Implement Block Device Characteristics VPD page

Implement page B1h, Block Device Characteristics, so that we can report
a medium rotation rate of 1 (non-rotating / solid state) if the
is_nonrot device attribute is set; we update the iblock backend to set
this attribute if the underlying Linux block device has its nonrot
flag set.

Signed-off-by: Roland Dreier <roland@purestorage.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>

Showing 7 changed files with 41 additions and 0 deletions Side-by-side Diff

drivers/target/target_core_cdb.c
... ... @@ -535,6 +535,22 @@
535 535 return 0;
536 536 }
537 537  
  538 +/* Block Device Characteristics VPD page */
  539 +static int
  540 +target_emulate_evpd_b1(struct se_cmd *cmd, unsigned char *buf)
  541 +{
  542 + struct se_device *dev = cmd->se_dev;
  543 +
  544 + buf[0] = dev->transport->get_device_type(dev);
  545 + buf[3] = 0x3c;
  546 +
  547 + if (cmd->data_length >= 5 &&
  548 + dev->se_sub_dev->se_dev_attrib.is_nonrot)
  549 + buf[5] = 1;
  550 +
  551 + return 0;
  552 +}
  553 +
538 554 /* Thin Provisioning VPD */
539 555 static int
540 556 target_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf)
... ... @@ -599,6 +615,7 @@
599 615 { .page = 0x83, .emulate = target_emulate_evpd_83 },
600 616 { .page = 0x86, .emulate = target_emulate_evpd_86 },
601 617 { .page = 0xb0, .emulate = target_emulate_evpd_b0 },
  618 + { .page = 0xb1, .emulate = target_emulate_evpd_b1 },
602 619 { .page = 0xb2, .emulate = target_emulate_evpd_b2 },
603 620 };
604 621  
drivers/target/target_core_configfs.c
... ... @@ -698,6 +698,9 @@
698 698 DEF_DEV_ATTRIB(enforce_pr_isids);
699 699 SE_DEV_ATTR(enforce_pr_isids, S_IRUGO | S_IWUSR);
700 700  
  701 +DEF_DEV_ATTRIB(is_nonrot);
  702 +SE_DEV_ATTR(is_nonrot, S_IRUGO | S_IWUSR);
  703 +
701 704 DEF_DEV_ATTRIB_RO(hw_block_size);
702 705 SE_DEV_ATTR_RO(hw_block_size);
703 706  
... ... @@ -746,6 +749,7 @@
746 749 &target_core_dev_attrib_emulate_tpu.attr,
747 750 &target_core_dev_attrib_emulate_tpws.attr,
748 751 &target_core_dev_attrib_enforce_pr_isids.attr,
  752 + &target_core_dev_attrib_is_nonrot.attr,
749 753 &target_core_dev_attrib_hw_block_size.attr,
750 754 &target_core_dev_attrib_block_size.attr,
751 755 &target_core_dev_attrib_hw_max_sectors.attr,
drivers/target/target_core_device.c
... ... @@ -853,6 +853,7 @@
853 853 dev->se_sub_dev->se_dev_attrib.emulate_reservations = DA_EMULATE_RESERVATIONS;
854 854 dev->se_sub_dev->se_dev_attrib.emulate_alua = DA_EMULATE_ALUA;
855 855 dev->se_sub_dev->se_dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS;
  856 + dev->se_sub_dev->se_dev_attrib.is_nonrot = DA_IS_NONROT;
856 857 /*
857 858 * The TPU=1 and TPWS=1 settings will be set in TCM/IBLOCK
858 859 * iblock_create_virtdevice() from struct queue_limits values
... ... @@ -1114,6 +1115,18 @@
1114 1115 dev->se_sub_dev->se_dev_attrib.enforce_pr_isids = flag;
1115 1116 printk(KERN_INFO "dev[%p]: SE Device enforce_pr_isids bit: %s\n", dev,
1116 1117 (dev->se_sub_dev->se_dev_attrib.enforce_pr_isids) ? "Enabled" : "Disabled");
  1118 + return 0;
  1119 +}
  1120 +
  1121 +int se_dev_set_is_nonrot(struct se_device *dev, int flag)
  1122 +{
  1123 + if ((flag != 0) && (flag != 1)) {
  1124 + printk(KERN_ERR "Illegal value %d\n", flag);
  1125 + return -EINVAL;
  1126 + }
  1127 + dev->se_sub_dev->se_dev_attrib.is_nonrot = flag;
  1128 + printk(KERN_INFO "dev[%p]: SE Device is_nonrot bit: %d\n",
  1129 + dev, flag);
1117 1130 return 0;
1118 1131 }
1119 1132  
drivers/target/target_core_iblock.c
... ... @@ -196,6 +196,9 @@
196 196 " disabled by default\n");
197 197 }
198 198  
  199 + if (blk_queue_nonrot(q))
  200 + dev->se_sub_dev->se_dev_attrib.is_nonrot = 1;
  201 +
199 202 return dev;
200 203  
201 204 failed:
include/target/target_core_base.h
... ... @@ -661,6 +661,7 @@
661 661 int emulate_reservations;
662 662 int emulate_alua;
663 663 int enforce_pr_isids;
  664 + int is_nonrot;
664 665 u32 hw_block_size;
665 666 u32 block_size;
666 667 u32 hw_max_sectors;
include/target/target_core_device.h
... ... @@ -39,6 +39,7 @@
39 39 extern int se_dev_set_emulate_tpu(struct se_device *, int);
40 40 extern int se_dev_set_emulate_tpws(struct se_device *, int);
41 41 extern int se_dev_set_enforce_pr_isids(struct se_device *, int);
  42 +extern int se_dev_set_is_nonrot(struct se_device *, int);
42 43 extern int se_dev_set_queue_depth(struct se_device *, u32);
43 44 extern int se_dev_set_max_sectors(struct se_device *, u32);
44 45 extern int se_dev_set_optimal_sectors(struct se_device *, u32);
include/target/target_core_transport.h
... ... @@ -101,6 +101,8 @@
101 101 #define DA_ENFORCE_PR_ISIDS 1
102 102 #define DA_STATUS_MAX_SECTORS_MIN 16
103 103 #define DA_STATUS_MAX_SECTORS_MAX 8192
  104 +/* By default don't report non-rotating (solid state) medium */
  105 +#define DA_IS_NONROT 0
104 106  
105 107 #define SE_MODE_PAGE_BUF 512
106 108