Commit 8b449060 authored by Pawel Wodkowski's avatar Pawel Wodkowski Committed by Jim Harris
Browse files

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: default avatarPawel Wodkowski <pawelx.wodkowski@intel.com>
parent 4fdc493c
Loading
Loading
Loading
Loading
+18 −9
Original line number Diff line number Diff line
@@ -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);
		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) */
		data[0] = 0x03 << 5 | 0x1f;
			buffer[0] = 0x03 << 5 | 0x1f;
			/* ADDITIONAL LENGTH */
		data[4] = data_len - 5;
		task->data_transferred = (uint64_t)data_len;
			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 */
+6 −1
Original line number Diff line number Diff line
@@ -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]);
		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) {
+0 −13
Original line number Diff line number Diff line
@@ -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);
+0 −5
Original line number Diff line number Diff line
@@ -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;