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: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
7a3f369ce3
commit
a50da144d0
1 changed files with 15 additions and 8 deletions
|
@ -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;
|
||||||
|
|
||||||
transport_kunmap_data_sg(cmd);
|
rbuf = transport_kmap_data_sg(cmd);
|
||||||
|
if (rbuf) {
|
||||||
|
memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
|
||||||
|
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;
|
||||||
|
|
||||||
transport_kunmap_data_sg(cmd);
|
rbuf = transport_kmap_data_sg(cmd);
|
||||||
|
if (rbuf) {
|
||||||
|
memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
|
||||||
|
transport_kunmap_data_sg(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
target_complete_cmd(cmd, GOOD);
|
target_complete_cmd(cmd, GOOD);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue