Commit e7dc2369 authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Jim Harris
Browse files

scsi: Inline spdk_bdev_scsi_read/write into spdk_bdev_scsi_read_write



In this patch series, spdk_bdev_scsi_read and spdk_bdev_scsi_write
became almost identical. Hence squash them into spdk_bdev_scsi_read_write.

Change-Id: Ibbaddf74c1bf2dac37a0133eac27086af650a061
Signed-off-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/c/444780


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
parent 07e9a00b
Loading
Loading
Loading
Loading
+64 −117
Original line number Diff line number Diff line
@@ -1315,118 +1315,6 @@ spdk_bdev_scsi_queue_io(struct spdk_scsi_task *task, spdk_bdev_io_wait_cb cb_fn,
	}
}

static uint64_t
_bytes_to_blocks(uint32_t block_size, uint64_t offset_bytes, uint64_t *offset_blocks,
		 uint64_t num_bytes, uint64_t *num_blocks)
{
	uint8_t shift_cnt;

	/* Avoid expensive div operations if possible. These spdk_u32 functions are very cheap. */
	if (spdk_likely(spdk_u32_is_pow2(block_size))) {
		shift_cnt = spdk_u32log2(block_size);
		*offset_blocks = offset_bytes >> shift_cnt;
		*num_blocks = num_bytes >> shift_cnt;
		return (offset_bytes - (*offset_blocks << shift_cnt)) |
		       (num_bytes - (*num_blocks << shift_cnt));
	} else {
		*offset_blocks = offset_bytes / block_size;
		*num_blocks = num_bytes / block_size;
		return (offset_bytes % block_size) | (num_bytes % block_size);
	}
}

static int
spdk_bdev_scsi_read(struct spdk_bdev *bdev, struct spdk_bdev_desc *bdev_desc,
		    struct spdk_io_channel *bdev_ch, struct spdk_scsi_task *task,
		    uint64_t lba)
{
	uint64_t offset_blocks, num_blocks;
	int rc;

	if (_bytes_to_blocks(spdk_bdev_get_block_size(bdev), task->offset, &offset_blocks,
			     task->length, &num_blocks) != 0) {
		SPDK_ERRLOG("task's offset %" PRIu64 " or length %" PRIu32 " is not block multiple\n",
			    task->offset, task->length);
		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
					  SPDK_SCSI_SENSE_NO_SENSE,
					  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
		return SPDK_SCSI_TASK_COMPLETE;
	}

	offset_blocks += lba;

	SPDK_DEBUGLOG(SPDK_LOG_SCSI,
		      "Read: lba=%"PRIu64", len=%"PRIu64"\n",
		      offset_blocks, num_blocks);

	rc = spdk_bdev_readv_blocks(bdev_desc, bdev_ch, task->iovs, task->iovcnt,
				    offset_blocks, num_blocks,
				    spdk_bdev_scsi_task_complete_cmd, task);

	if (rc) {
		if (rc == -ENOMEM) {
			spdk_bdev_scsi_queue_io(task, spdk_bdev_scsi_process_block_resubmit, task);
			return SPDK_SCSI_TASK_PENDING;
		}
		SPDK_ERRLOG("spdk_bdev_readv_blocks() failed\n");
		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
					  SPDK_SCSI_SENSE_NO_SENSE,
					  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
		return SPDK_SCSI_TASK_COMPLETE;
	}

	task->data_transferred = task->length;
	return SPDK_SCSI_TASK_PENDING;
}

static int
spdk_bdev_scsi_write(struct spdk_bdev *bdev, struct spdk_bdev_desc *bdev_desc,
		     struct spdk_io_channel *bdev_ch, struct spdk_scsi_task *task,
		     uint64_t lba)
{
	uint64_t offset_blocks, num_blocks;
	int rc;

	if (_bytes_to_blocks(spdk_bdev_get_block_size(bdev), task->offset, &offset_blocks,
			     task->length, &num_blocks) != 0) {
		SPDK_ERRLOG("task's offset %" PRIu64 " or length %" PRIu32 " is not block multiple\n",
			    task->offset, task->length);
		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
					  SPDK_SCSI_SENSE_NO_SENSE,
					  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
		return SPDK_SCSI_TASK_COMPLETE;
	}

	offset_blocks += lba;

	SPDK_DEBUGLOG(SPDK_LOG_SCSI,
		      "Write: lba=%"PRIu64", len=%"PRIu64"\n",
		      offset_blocks, num_blocks);

	rc = spdk_bdev_writev_blocks(bdev_desc, bdev_ch, task->iovs, task->iovcnt,
				     offset_blocks, num_blocks,
				     spdk_bdev_scsi_task_complete_cmd, task);

	if (rc) {
		if (rc == -ENOMEM) {
			spdk_bdev_scsi_queue_io(task, spdk_bdev_scsi_process_block_resubmit, task);
			return SPDK_SCSI_TASK_PENDING;
		}
		SPDK_ERRLOG("spdk_bdev_writev_blocks() failed\n");
		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
					  SPDK_SCSI_SENSE_NO_SENSE,
					  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
		return SPDK_SCSI_TASK_COMPLETE;
	}

	task->data_transferred = task->length;
	return SPDK_SCSI_TASK_PENDING;
}

static int
spdk_bdev_scsi_sync(struct spdk_bdev *bdev, struct spdk_bdev_desc *bdev_desc,
		    struct spdk_io_channel *bdev_ch, struct spdk_scsi_task *task,
@@ -1470,6 +1358,26 @@ spdk_bdev_scsi_sync(struct spdk_bdev *bdev, struct spdk_bdev_desc *bdev_desc,
	return SPDK_SCSI_TASK_PENDING;
}

static uint64_t
_bytes_to_blocks(uint32_t block_size, uint64_t offset_bytes, uint64_t *offset_blocks,
		 uint64_t num_bytes, uint64_t *num_blocks)
{
	uint8_t shift_cnt;

	/* Avoid expensive div operations if possible. These spdk_u32 functions are very cheap. */
	if (spdk_likely(spdk_u32_is_pow2(block_size))) {
		shift_cnt = spdk_u32log2(block_size);
		*offset_blocks = offset_bytes >> shift_cnt;
		*num_blocks = num_bytes >> shift_cnt;
		return (offset_bytes - (*offset_blocks << shift_cnt)) |
		       (num_bytes - (*num_blocks << shift_cnt));
	} else {
		*offset_blocks = offset_bytes / block_size;
		*num_blocks = num_bytes / block_size;
		return (offset_bytes % block_size) | (num_bytes % block_size);
	}
}

static int
spdk_bdev_scsi_readwrite(struct spdk_scsi_task *task,
			 uint64_t lba, uint32_t xfer_len, bool is_read)
@@ -1478,8 +1386,9 @@ spdk_bdev_scsi_readwrite(struct spdk_scsi_task *task,
	struct spdk_bdev *bdev = lun->bdev;
	struct spdk_bdev_desc *bdev_desc = lun->bdev_desc;
	struct spdk_io_channel *bdev_ch = lun->io_channel;
	uint64_t bdev_num_blocks;
	uint64_t bdev_num_blocks, offset_blocks, num_blocks;
	uint32_t max_xfer_len, block_size;
	int rc;

	task->data_transferred = 0;

@@ -1522,9 +1431,7 @@ spdk_bdev_scsi_readwrite(struct spdk_scsi_task *task,
		return SPDK_SCSI_TASK_COMPLETE;
	}

	if (is_read) {
		return spdk_bdev_scsi_read(bdev, bdev_desc, bdev_ch, task, lba);
	} else {
	if (!is_read) {
		/* Additional check for Transfer Length */
		if (xfer_len * block_size > task->transfer_len) {
			SPDK_ERRLOG("xfer_len %" PRIu32 " * block_size %" PRIu32 " > transfer_len %u\n",
@@ -1535,9 +1442,49 @@ spdk_bdev_scsi_readwrite(struct spdk_scsi_task *task,
						  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
			return SPDK_SCSI_TASK_COMPLETE;
		}
	}

		return spdk_bdev_scsi_write(bdev, bdev_desc, bdev_ch, task, lba);
	if (_bytes_to_blocks(block_size, task->offset, &offset_blocks, task->length, &num_blocks) != 0) {
		SPDK_ERRLOG("task's offset %" PRIu64 " or length %" PRIu32 " is not block multiple\n",
			    task->offset, task->length);
		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
					  SPDK_SCSI_SENSE_NO_SENSE,
					  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
		return SPDK_SCSI_TASK_COMPLETE;
	}

	offset_blocks += lba;

	SPDK_DEBUGLOG(SPDK_LOG_SCSI,
		      "%s: lba=%"PRIu64", len=%"PRIu64"\n",
		      is_read ? "Read" : "Write", offset_blocks, num_blocks);

	if (is_read) {
		rc = spdk_bdev_readv_blocks(bdev_desc, bdev_ch, task->iovs, task->iovcnt,
					    offset_blocks, num_blocks,
					    spdk_bdev_scsi_task_complete_cmd, task);
	} else {
		rc = spdk_bdev_writev_blocks(bdev_desc, bdev_ch, task->iovs, task->iovcnt,
					     offset_blocks, num_blocks,
					     spdk_bdev_scsi_task_complete_cmd, task);
	}

	if (rc) {
		if (rc == -ENOMEM) {
			spdk_bdev_scsi_queue_io(task, spdk_bdev_scsi_process_block_resubmit, task);
			return SPDK_SCSI_TASK_PENDING;
		}
		SPDK_ERRLOG("spdk_bdev_%s_blocks() failed\n", is_read ? "readv" : "writev");
		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
					  SPDK_SCSI_SENSE_NO_SENSE,
					  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
		return SPDK_SCSI_TASK_COMPLETE;
	}

	task->data_transferred = task->length;
	return SPDK_SCSI_TASK_PENDING;
}

struct spdk_bdev_scsi_unmap_ctx {