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

Commit a50da144 authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Nicholas Bellinger
Browse files

target: support zero allocation length in SBC commands



READ CAPACITY must be subject to the same treatment as INQUIRY,
REQUEST SENSE, and MODE SENSE, but there are no pre-existing bugs
to fix here.  Just use an on-stack buffer, and copy to it after
checking the return value of transport_kmap_data_sg.

Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent 7a3f369c
Loading
Loading
Loading
Loading
+15 −8
Original line number Original line Diff line number Diff line
@@ -40,8 +40,9 @@
static int sbc_emulate_readcapacity(struct se_cmd *cmd)
static int sbc_emulate_readcapacity(struct se_cmd *cmd)
{
{
	struct se_device *dev = cmd->se_dev;
	struct se_device *dev = cmd->se_dev;
	unsigned char *buf;
	unsigned long long blocks_long = dev->transport->get_blocks(dev);
	unsigned long long blocks_long = dev->transport->get_blocks(dev);
	unsigned char *rbuf;
	unsigned char buf[8];
	u32 blocks;
	u32 blocks;


	if (blocks_long >= 0x00000000ffffffff)
	if (blocks_long >= 0x00000000ffffffff)
@@ -49,8 +50,6 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd)
	else
	else
		blocks = (u32)blocks_long;
		blocks = (u32)blocks_long;


	buf = transport_kmap_data_sg(cmd);

	buf[0] = (blocks >> 24) & 0xff;
	buf[0] = (blocks >> 24) & 0xff;
	buf[1] = (blocks >> 16) & 0xff;
	buf[1] = (blocks >> 16) & 0xff;
	buf[2] = (blocks >> 8) & 0xff;
	buf[2] = (blocks >> 8) & 0xff;
@@ -60,7 +59,11 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd)
	buf[6] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff;
	buf[6] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff;
	buf[7] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff;
	buf[7] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff;


	rbuf = transport_kmap_data_sg(cmd);
	if (rbuf) {
		memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
		transport_kunmap_data_sg(cmd);
		transport_kunmap_data_sg(cmd);
	}


	target_complete_cmd(cmd, GOOD);
	target_complete_cmd(cmd, GOOD);
	return 0;
	return 0;
@@ -69,11 +72,11 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd)
static int sbc_emulate_readcapacity_16(struct se_cmd *cmd)
static int sbc_emulate_readcapacity_16(struct se_cmd *cmd)
{
{
	struct se_device *dev = cmd->se_dev;
	struct se_device *dev = cmd->se_dev;
	unsigned char *buf;
	unsigned char *rbuf;
	unsigned char buf[32];
	unsigned long long blocks = dev->transport->get_blocks(dev);
	unsigned long long blocks = dev->transport->get_blocks(dev);


	buf = transport_kmap_data_sg(cmd);
	memset(buf, 0, sizeof(buf));

	buf[0] = (blocks >> 56) & 0xff;
	buf[0] = (blocks >> 56) & 0xff;
	buf[1] = (blocks >> 48) & 0xff;
	buf[1] = (blocks >> 48) & 0xff;
	buf[2] = (blocks >> 40) & 0xff;
	buf[2] = (blocks >> 40) & 0xff;
@@ -93,7 +96,11 @@ static int sbc_emulate_readcapacity_16(struct se_cmd *cmd)
	if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws)
	if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws)
		buf[14] = 0x80;
		buf[14] = 0x80;


	rbuf = transport_kmap_data_sg(cmd);
	if (rbuf) {
		memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
		transport_kunmap_data_sg(cmd);
		transport_kunmap_data_sg(cmd);
	}


	target_complete_cmd(cmd, GOOD);
	target_complete_cmd(cmd, GOOD);
	return 0;
	return 0;