lib/scsi: allocate only requested amount of data
Remove 4k allocation size in spdk_scsi_task_alloc_data(). From now on all commands must obay allocation length. Change-Id: Ica9384c62d431483ae1d0bd2e6fdee18b570861f Signed-off-by: Pawel Wodkowski <pawelx.wodkowski@intel.com>
This commit is contained in:
parent
4fdc493c8e
commit
8b449060eb
@ -183,9 +183,10 @@ spdk_scsi_lun_task_mgmt_execute(struct spdk_scsi_task *task)
|
||||
static void
|
||||
complete_task_with_no_lun(struct spdk_scsi_task *task)
|
||||
{
|
||||
uint8_t buffer[36];
|
||||
uint8_t *data;
|
||||
uint32_t allocation_len;
|
||||
int data_len;
|
||||
uint32_t data_len;
|
||||
|
||||
if (task->cdb[0] == SPDK_SPC_INQUIRY) {
|
||||
/*
|
||||
@ -194,14 +195,22 @@ complete_task_with_no_lun(struct spdk_scsi_task *task)
|
||||
* PERIPHERAL DEVICE TYPE = 0x1F.
|
||||
*/
|
||||
allocation_len = from_be16(&task->cdb[3]);
|
||||
data = spdk_scsi_task_alloc_data(task, allocation_len);
|
||||
data_len = 36;
|
||||
memset(data, 0, data_len);
|
||||
/* PERIPHERAL QUALIFIER(7-5) PERIPHERAL DEVICE TYPE(4-0) */
|
||||
data[0] = 0x03 << 5 | 0x1f;
|
||||
/* ADDITIONAL LENGTH */
|
||||
data[4] = data_len - 5;
|
||||
task->data_transferred = (uint64_t)data_len;
|
||||
data_len = sizeof(buffer);
|
||||
if (allocation_len > data_len)
|
||||
allocation_len = data_len;
|
||||
|
||||
if (allocation_len) {
|
||||
memset(buffer, 0, data_len);
|
||||
/* PERIPHERAL QUALIFIER(7-5) PERIPHERAL DEVICE TYPE(4-0) */
|
||||
buffer[0] = 0x03 << 5 | 0x1f;
|
||||
/* ADDITIONAL LENGTH */
|
||||
buffer[4] = data_len - 5;
|
||||
|
||||
data = spdk_scsi_task_alloc_data(task, allocation_len);
|
||||
memcpy(data, buffer, allocation_len);
|
||||
}
|
||||
|
||||
task->data_transferred = data_len;
|
||||
task->status = SPDK_SCSI_STATUS_GOOD;
|
||||
} else {
|
||||
/* LOGICAL UNIT NOT SUPPORTED */
|
||||
|
@ -1635,7 +1635,12 @@ spdk_bdev_scsi_process_primary(struct spdk_bdev *bdev,
|
||||
switch (cdb[0]) {
|
||||
case SPDK_SPC_INQUIRY:
|
||||
alloc_len = from_be16(&cdb[3]);
|
||||
data = spdk_scsi_task_alloc_data(task, alloc_len);
|
||||
if (alloc_len) {
|
||||
data = spdk_scsi_task_alloc_data(task, alloc_len);
|
||||
} else {
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
data_len = spdk_bdev_scsi_inquiry(bdev, task, cdb,
|
||||
data, alloc_len);
|
||||
if (data_len < 0) {
|
||||
|
@ -120,15 +120,6 @@ spdk_scsi_task_free_data(struct spdk_scsi_task *task)
|
||||
void *
|
||||
spdk_scsi_task_alloc_data(struct spdk_scsi_task *task, uint32_t alloc_len)
|
||||
{
|
||||
/*
|
||||
* SPDK iSCSI target depends on allocating at least 4096 bytes, even if
|
||||
* the command requested less. The individual command code (for
|
||||
* example, INQUIRY) will fill out up to 4096 bytes of data, ignoring
|
||||
* the allocation length specified in the command. After the individual
|
||||
* command functions are done, spdk_scsi_lun_execute_tasks() takes
|
||||
* care of only sending back the amount of data specified in the
|
||||
* allocation length.
|
||||
*/
|
||||
assert(task->alloc_len == 0);
|
||||
|
||||
/* Only one buffer is managable */
|
||||
@ -136,10 +127,6 @@ spdk_scsi_task_alloc_data(struct spdk_scsi_task *task, uint32_t alloc_len)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (alloc_len < 4096) {
|
||||
alloc_len = 4096;
|
||||
}
|
||||
|
||||
/* This is workaround for buffers shorter than 4kb */
|
||||
if (task->iov.iov_base == NULL) {
|
||||
task->iov.iov_base = spdk_zmalloc(alloc_len, 0, NULL);
|
||||
|
@ -104,10 +104,6 @@ spdk_scsi_task_set_data(struct spdk_scsi_task *task, void *data, uint32_t len)
|
||||
void *
|
||||
spdk_scsi_task_alloc_data(struct spdk_scsi_task *task, uint32_t alloc_len)
|
||||
{
|
||||
if (alloc_len < 4096) {
|
||||
alloc_len = 4096;
|
||||
}
|
||||
|
||||
if (task->iov.iov_base != NULL) {
|
||||
if (task->alloc_len != 0 && alloc_len > task->alloc_len) {
|
||||
spdk_put_task(task);
|
||||
@ -458,7 +454,6 @@ inquiry_standard_test(void)
|
||||
struct spdk_scsi_lun lun;
|
||||
struct spdk_scsi_dev dev;
|
||||
char cdb[6];
|
||||
/* expects a 4K internal data buffer */
|
||||
char *data;
|
||||
struct spdk_scsi_cdb_inquiry_data *inq_data;
|
||||
int rc;
|
||||
|
Loading…
Reference in New Issue
Block a user