Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e22a7f07 authored by Roland Dreier's avatar Roland Dreier Committed by Nicholas Bellinger
Browse files

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: default avatarRoland Dreier <roland@purestorage.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent b2eb705e
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -535,6 +535,22 @@ target_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
	return 0;
}

/* Block Device Characteristics VPD page */
static int
target_emulate_evpd_b1(struct se_cmd *cmd, unsigned char *buf)
{
	struct se_device *dev = cmd->se_dev;

	buf[0] = dev->transport->get_device_type(dev);
	buf[3] = 0x3c;

	if (cmd->data_length >= 5 &&
	    dev->se_sub_dev->se_dev_attrib.is_nonrot)
		buf[5] = 1;

	return 0;
}

/* Thin Provisioning VPD */
static int
target_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf)
@@ -599,6 +615,7 @@ static struct {
	{ .page = 0x83, .emulate = target_emulate_evpd_83 },
	{ .page = 0x86, .emulate = target_emulate_evpd_86 },
	{ .page = 0xb0, .emulate = target_emulate_evpd_b0 },
	{ .page = 0xb1, .emulate = target_emulate_evpd_b1 },
	{ .page = 0xb2, .emulate = target_emulate_evpd_b2 },
};

+4 −0
Original line number Diff line number Diff line
@@ -698,6 +698,9 @@ SE_DEV_ATTR(emulate_tpws, S_IRUGO | S_IWUSR);
DEF_DEV_ATTRIB(enforce_pr_isids);
SE_DEV_ATTR(enforce_pr_isids, S_IRUGO | S_IWUSR);

DEF_DEV_ATTRIB(is_nonrot);
SE_DEV_ATTR(is_nonrot, S_IRUGO | S_IWUSR);

DEF_DEV_ATTRIB_RO(hw_block_size);
SE_DEV_ATTR_RO(hw_block_size);

@@ -746,6 +749,7 @@ static struct configfs_attribute *target_core_dev_attrib_attrs[] = {
	&target_core_dev_attrib_emulate_tpu.attr,
	&target_core_dev_attrib_emulate_tpws.attr,
	&target_core_dev_attrib_enforce_pr_isids.attr,
	&target_core_dev_attrib_is_nonrot.attr,
	&target_core_dev_attrib_hw_block_size.attr,
	&target_core_dev_attrib_block_size.attr,
	&target_core_dev_attrib_hw_max_sectors.attr,
+13 −0
Original line number Diff line number Diff line
@@ -853,6 +853,7 @@ void se_dev_set_default_attribs(
	dev->se_sub_dev->se_dev_attrib.emulate_reservations = DA_EMULATE_RESERVATIONS;
	dev->se_sub_dev->se_dev_attrib.emulate_alua = DA_EMULATE_ALUA;
	dev->se_sub_dev->se_dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS;
	dev->se_sub_dev->se_dev_attrib.is_nonrot = DA_IS_NONROT;
	/*
	 * The TPU=1 and TPWS=1 settings will be set in TCM/IBLOCK
	 * iblock_create_virtdevice() from struct queue_limits values
@@ -1117,6 +1118,18 @@ int se_dev_set_enforce_pr_isids(struct se_device *dev, int flag)
	return 0;
}

int se_dev_set_is_nonrot(struct se_device *dev, int flag)
{
	if ((flag != 0) && (flag != 1)) {
		printk(KERN_ERR "Illegal value %d\n", flag);
		return -EINVAL;
	}
	dev->se_sub_dev->se_dev_attrib.is_nonrot = flag;
	printk(KERN_INFO "dev[%p]: SE Device is_nonrot bit: %d\n",
	       dev, flag);
	return 0;
}

/*
 * Note, this can only be called on unexported SE Device Object.
 */
+3 −0
Original line number Diff line number Diff line
@@ -196,6 +196,9 @@ static struct se_device *iblock_create_virtdevice(
				" disabled by default\n");
	}

	if (blk_queue_nonrot(q))
		dev->se_sub_dev->se_dev_attrib.is_nonrot = 1;

	return dev;

failed:
+1 −0
Original line number Diff line number Diff line
@@ -661,6 +661,7 @@ struct se_dev_attrib {
	int		emulate_reservations;
	int		emulate_alua;
	int		enforce_pr_isids;
	int		is_nonrot;
	u32		hw_block_size;
	u32		block_size;
	u32		hw_max_sectors;
Loading