diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2012-09-07 11:30:40 -0400 |
|---|---|---|
| committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-09-17 20:13:38 -0400 |
| commit | a50da144d048f9dbebed2b1441ed779d6bbbcd03 (patch) | |
| tree | 25290267964578f79c10590a6511d10b85e7de96 /drivers | |
| parent | 7a3f369ce31694017996524a1cdb08208a839077 (diff) | |
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>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/target/target_core_sbc.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index a9dd9469e3bd..868f8aa04f13 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
| @@ -40,8 +40,9 @@ | |||
| 40 | static int sbc_emulate_readcapacity(struct se_cmd *cmd) | 40 | static int sbc_emulate_readcapacity(struct se_cmd *cmd) |
| 41 | { | 41 | { |
| 42 | struct se_device *dev = cmd->se_dev; | 42 | struct se_device *dev = cmd->se_dev; |
| 43 | unsigned char *buf; | ||
| 44 | unsigned long long blocks_long = dev->transport->get_blocks(dev); | 43 | unsigned long long blocks_long = dev->transport->get_blocks(dev); |
| 44 | unsigned char *rbuf; | ||
| 45 | unsigned char buf[8]; | ||
| 45 | u32 blocks; | 46 | u32 blocks; |
| 46 | 47 | ||
| 47 | if (blocks_long >= 0x00000000ffffffff) | 48 | if (blocks_long >= 0x00000000ffffffff) |
| @@ -49,8 +50,6 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd) | |||
| 49 | else | 50 | else |
| 50 | blocks = (u32)blocks_long; | 51 | blocks = (u32)blocks_long; |
| 51 | 52 | ||
| 52 | buf = transport_kmap_data_sg(cmd); | ||
| 53 | |||
| 54 | buf[0] = (blocks >> 24) & 0xff; | 53 | buf[0] = (blocks >> 24) & 0xff; |
| 55 | buf[1] = (blocks >> 16) & 0xff; | 54 | buf[1] = (blocks >> 16) & 0xff; |
| 56 | buf[2] = (blocks >> 8) & 0xff; | 55 | buf[2] = (blocks >> 8) & 0xff; |
| @@ -60,7 +59,11 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd) | |||
| 60 | buf[6] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff; | 59 | buf[6] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff; |
| 61 | buf[7] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff; | 60 | buf[7] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff; |
| 62 | 61 | ||
| 63 | transport_kunmap_data_sg(cmd); | 62 | rbuf = transport_kmap_data_sg(cmd); |
| 63 | if (rbuf) { | ||
| 64 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); | ||
| 65 | transport_kunmap_data_sg(cmd); | ||
| 66 | } | ||
| 64 | 67 | ||
| 65 | target_complete_cmd(cmd, GOOD); | 68 | target_complete_cmd(cmd, GOOD); |
| 66 | return 0; | 69 | return 0; |
| @@ -69,11 +72,11 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd) | |||
| 69 | static int sbc_emulate_readcapacity_16(struct se_cmd *cmd) | 72 | static int sbc_emulate_readcapacity_16(struct se_cmd *cmd) |
| 70 | { | 73 | { |
| 71 | struct se_device *dev = cmd->se_dev; | 74 | struct se_device *dev = cmd->se_dev; |
| 72 | unsigned char *buf; | 75 | unsigned char *rbuf; |
| 76 | unsigned char buf[32]; | ||
| 73 | unsigned long long blocks = dev->transport->get_blocks(dev); | 77 | unsigned long long blocks = dev->transport->get_blocks(dev); |
| 74 | 78 | ||
| 75 | buf = transport_kmap_data_sg(cmd); | 79 | memset(buf, 0, sizeof(buf)); |
| 76 | |||
| 77 | buf[0] = (blocks >> 56) & 0xff; | 80 | buf[0] = (blocks >> 56) & 0xff; |
| 78 | buf[1] = (blocks >> 48) & 0xff; | 81 | buf[1] = (blocks >> 48) & 0xff; |
| 79 | buf[2] = (blocks >> 40) & 0xff; | 82 | buf[2] = (blocks >> 40) & 0xff; |
| @@ -93,7 +96,11 @@ static int sbc_emulate_readcapacity_16(struct se_cmd *cmd) | |||
| 93 | if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws) | 96 | if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws) |
| 94 | buf[14] = 0x80; | 97 | buf[14] = 0x80; |
| 95 | 98 | ||
| 96 | transport_kunmap_data_sg(cmd); | 99 | rbuf = transport_kmap_data_sg(cmd); |
| 100 | if (rbuf) { | ||
| 101 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); | ||
| 102 | transport_kunmap_data_sg(cmd); | ||
| 103 | } | ||
| 97 | 104 | ||
| 98 | target_complete_cmd(cmd, GOOD); | 105 | target_complete_cmd(cmd, GOOD); |
| 99 | return 0; | 106 | return 0; |
