From e7dc23696b9d88f51abc70c01b321941bf861cef Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Mon, 18 Feb 2019 13:32:48 +0900 Subject: [PATCH] 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 Reviewed-on: https://review.gerrithub.io/c/444780 Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Darek Stojaczyk --- lib/scsi/scsi_bdev.c | 183 +++++++++++++++---------------------------- 1 file changed, 65 insertions(+), 118 deletions(-) diff --git a/lib/scsi/scsi_bdev.c b/lib/scsi/scsi_bdev.c index 6dc7341e5..2d3680385 100644 --- a/lib/scsi/scsi_bdev.c +++ b/lib/scsi/scsi_bdev.c @@ -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 {