Commit e22a7f075226c51f3f71b922e9eeb4f99fac1475
Committed by
Nicholas Bellinger
1 parent
b2eb705e00
Exists in
master
and in
20 other branches
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
include/target/target_core_base.h
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 |