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: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/c/444780
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
This commit is contained in:
Shuhei Matsumoto 2019-02-18 13:32:48 +09:00 committed by Jim Harris
parent 07e9a00b60
commit e7dc23696b

View File

@ -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 {