From 326786a943433e4aff71e2eec4b8e894c969439f Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Fri, 12 May 2017 10:29:00 -0700 Subject: [PATCH] bdev: add getters for block size and block count Change-Id: I6fad28da43c163ea4e2c4a04ced356b67d63652f Signed-off-by: Daniel Verkamp --- include/spdk/bdev.h | 18 ++++++++++ lib/bdev/bdev.c | 12 +++++++ lib/bdev/rpc/bdev_rpc.c | 4 +-- lib/blob/bdev/blob_bdev.c | 4 +-- lib/nvmf/virtual.c | 20 ++++++----- lib/scsi/scsi_bdev.c | 48 ++++++++++++++------------ test/lib/bdev/bdevio/bdevio.c | 25 ++++++++------ test/lib/bdev/bdevperf/bdevperf.c | 8 +++-- test/lib/nvmf/virtual/virtual_ut.c | 14 ++++++++ test/lib/scsi/scsi_bdev/scsi_bdev_ut.c | 12 +++++++ 10 files changed, 118 insertions(+), 47 deletions(-) diff --git a/include/spdk/bdev.h b/include/spdk/bdev.h index ce16460a7..15c8e4e4b 100644 --- a/include/spdk/bdev.h +++ b/include/spdk/bdev.h @@ -215,6 +215,24 @@ const char *spdk_bdev_get_name(const struct spdk_bdev *bdev); */ const char *spdk_bdev_get_product_name(const struct spdk_bdev *bdev); +/** + * Get block device logical block size. + * + * \param bdev Block device to query. + * \return Size of logical block for this bdev in bytes. + */ +uint32_t spdk_bdev_get_block_size(const struct spdk_bdev *bdev); + +/** + * Get size of block device in logical blocks. + * + * \param bdev Block device to query. + * \return Size of bdev in logical blocks. + * + * Logical blocks are numbered from 0 to spdk_bdev_get_num_blocks(bdev) - 1, inclusive. + */ +uint64_t spdk_bdev_get_num_blocks(const struct spdk_bdev *bdev); + /** * Get minimum I/O buffer address alignment for a bdev. * diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index 612e9ba16..bd3d0fa93 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -545,6 +545,18 @@ spdk_bdev_get_product_name(const struct spdk_bdev *bdev) return bdev->product_name; } +uint32_t +spdk_bdev_get_block_size(const struct spdk_bdev *bdev) +{ + return bdev->blocklen; +} + +uint64_t +spdk_bdev_get_num_blocks(const struct spdk_bdev *bdev) +{ + return bdev->blockcnt; +} + size_t spdk_bdev_get_buf_align(const struct spdk_bdev *bdev) { diff --git a/lib/bdev/rpc/bdev_rpc.c b/lib/bdev/rpc/bdev_rpc.c index 53592311c..837ffeed8 100644 --- a/lib/bdev/rpc/bdev_rpc.c +++ b/lib/bdev/rpc/bdev_rpc.c @@ -66,10 +66,10 @@ spdk_rpc_get_bdevs(struct spdk_jsonrpc_server_conn *conn, spdk_json_write_string(w, spdk_bdev_get_product_name(bdev)); spdk_json_write_name(w, "block_size"); - spdk_json_write_uint32(w, bdev->blocklen); + spdk_json_write_uint32(w, spdk_bdev_get_block_size(bdev)); spdk_json_write_name(w, "num_blocks"); - spdk_json_write_uint64(w, bdev->blockcnt); + spdk_json_write_uint64(w, spdk_bdev_get_num_blocks(bdev)); spdk_json_write_name(w, "claimed"); if (bdev->status == SPDK_BDEV_STATUS_CLAIMED) { diff --git a/lib/blob/bdev/blob_bdev.c b/lib/blob/bdev/blob_bdev.c index 6b0c6d41e..46e7c9474 100644 --- a/lib/blob/bdev/blob_bdev.c +++ b/lib/blob/bdev/blob_bdev.c @@ -148,8 +148,8 @@ spdk_bdev_create_bs_dev(struct spdk_bdev *bdev) } b->bdev = bdev; - b->bs_dev.blockcnt = bdev->blockcnt; - b->bs_dev.blocklen = bdev->blocklen; + b->bs_dev.blockcnt = spdk_bdev_get_num_blocks(bdev); + b->bs_dev.blocklen = spdk_bdev_get_block_size(bdev); b->bs_dev.create_channel = bdev_blob_create_channel; b->bs_dev.destroy_channel = bdev_blob_destroy_channel; b->bs_dev.destroy = bdev_blob_destroy; diff --git a/lib/nvmf/virtual.c b/lib/nvmf/virtual.c index b90d7e235..2ffdff442 100644 --- a/lib/nvmf/virtual.c +++ b/lib/nvmf/virtual.c @@ -183,6 +183,7 @@ identify_ns(struct spdk_nvmf_subsystem *subsystem, struct spdk_nvme_ns_data *nsdata) { struct spdk_bdev *bdev; + uint64_t num_blocks; if (cmd->nsid > subsystem->dev.virt.ns_count || cmd->nsid == 0) { SPDK_ERRLOG("Identify Namespace for invalid NSID %u\n", cmd->nsid); @@ -192,12 +193,14 @@ identify_ns(struct spdk_nvmf_subsystem *subsystem, bdev = subsystem->dev.virt.ns_list[cmd->nsid - 1]; - nsdata->nsze = bdev->blockcnt; - nsdata->ncap = bdev->blockcnt; - nsdata->nuse = bdev->blockcnt; + num_blocks = spdk_bdev_get_num_blocks(bdev); + + nsdata->nsze = num_blocks; + nsdata->ncap = num_blocks; + nsdata->nuse = num_blocks; nsdata->nlbaf = 0; nsdata->flbas.format = 0; - nsdata->lbaf[0].lbads = spdk_u32log2(bdev->blocklen); + nsdata->lbaf[0].lbads = spdk_u32log2(spdk_bdev_get_block_size(bdev)); return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; } @@ -377,14 +380,15 @@ nvmf_virtual_ctrlr_rw_cmd(struct spdk_bdev *bdev, struct spdk_io_channel *ch, uint64_t io_bytes; uint64_t offset; uint64_t llen; + uint32_t block_size = spdk_bdev_get_block_size(bdev); struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; struct spdk_nvme_cpl *response = &req->rsp->nvme_cpl; struct nvme_read_cdw12 *cdw12 = (struct nvme_read_cdw12 *)&cmd->cdw12; - blockcnt = bdev->blockcnt; + blockcnt = spdk_bdev_get_num_blocks(bdev); lba_address = cmd->cdw11; lba_address = (lba_address << 32) + cmd->cdw10; - offset = lba_address * bdev->blocklen; + offset = lba_address * block_size; llen = cdw12->nlb + 1; if (lba_address >= blockcnt || llen > blockcnt || lba_address > (blockcnt - llen)) { @@ -393,7 +397,7 @@ nvmf_virtual_ctrlr_rw_cmd(struct spdk_bdev *bdev, struct spdk_io_channel *ch, return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; } - io_bytes = llen * bdev->blocklen; + io_bytes = llen * block_size; if (io_bytes > req->length) { SPDK_ERRLOG("Read/Write NLB > SGL length\n"); response->status.sc = SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID; @@ -427,7 +431,7 @@ nvmf_virtual_ctrlr_flush_cmd(struct spdk_bdev *bdev, struct spdk_io_channel *ch, uint64_t nbytes; struct spdk_nvme_cpl *response = &req->rsp->nvme_cpl; - nbytes = bdev->blockcnt * bdev->blocklen; + nbytes = spdk_bdev_get_num_blocks(bdev) * spdk_bdev_get_block_size(bdev); if (spdk_bdev_flush(bdev, ch, 0, nbytes, nvmf_virtual_ctrlr_complete_cmd, req) == NULL) { response->status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; diff --git a/lib/scsi/scsi_bdev.c b/lib/scsi/scsi_bdev.c index f064f67bd..f19bdf2b4 100644 --- a/lib/scsi/scsi_bdev.c +++ b/lib/scsi/scsi_bdev.c @@ -506,8 +506,9 @@ spdk_bdev_scsi_inquiry(struct spdk_bdev *bdev, struct spdk_scsi_task *task, } case SPDK_SPC_VPD_BLOCK_LIMITS: { - /* PAGE LENGTH */ + uint32_t block_size = spdk_bdev_get_block_size(bdev); + /* PAGE LENGTH */ memset(&data[4], 0, 60); hlen = 4; @@ -516,7 +517,7 @@ spdk_bdev_scsi_inquiry(struct spdk_bdev *bdev, struct spdk_scsi_task *task, /* support zero length in WRITE SAME */ /* MAXIMUM COMPARE AND WRITE LENGTH */ - blocks = SPDK_WORK_ATS_BLOCK_SIZE / bdev->blocklen; + blocks = SPDK_WORK_ATS_BLOCK_SIZE / block_size; if (blocks > 0xff) blocks = 0xff; @@ -524,8 +525,8 @@ spdk_bdev_scsi_inquiry(struct spdk_bdev *bdev, struct spdk_scsi_task *task, data[5] = (uint8_t)blocks; /* force align to 4KB */ - if (bdev->blocklen < 4096) { - optimal_blocks = 4096 / bdev->blocklen; + if (block_size < 4096) { + optimal_blocks = 4096 / block_size; } else { optimal_blocks = 1; } @@ -533,7 +534,7 @@ spdk_bdev_scsi_inquiry(struct spdk_bdev *bdev, struct spdk_scsi_task *task, /* OPTIMAL TRANSFER LENGTH GRANULARITY */ to_be16(&data[6], optimal_blocks); - blocks = SPDK_WORK_BLOCK_SIZE / bdev->blocklen; + blocks = SPDK_WORK_BLOCK_SIZE / block_size; /* MAXIMUM TRANSFER LENGTH */ to_be32(&data[8], blocks); @@ -1074,6 +1075,8 @@ spdk_bdev_scsi_mode_sense(struct spdk_bdev *bdev, int md, uint8_t *cdb, int dbd, int llbaa, int pc, int page, int subpage, uint8_t *data, struct spdk_scsi_task *task) { + uint64_t num_blocks = spdk_bdev_get_num_blocks(bdev); + uint32_t block_size = spdk_bdev_get_block_size(bdev); uint8_t *hdr, *bdesc, *pages; int hlen; int blen; @@ -1123,20 +1126,20 @@ spdk_bdev_scsi_mode_sense(struct spdk_bdev *bdev, int md, bdesc = &data[hlen]; if (blen == 16) { /* Number of Blocks */ - to_be64(&bdesc[0], bdev->blockcnt); + to_be64(&bdesc[0], num_blocks); /* Reserved */ memset(&bdesc[8], 0, 4); /* Block Length */ - to_be32(&bdesc[12], bdev->blocklen); + to_be32(&bdesc[12], block_size); } else if (blen == 8) { /* Number of Blocks */ - if (bdev->blockcnt > 0xffffffffULL) + if (num_blocks > 0xffffffffULL) memset(&bdesc[0], 0xff, 4); else - to_be32(&bdesc[0], bdev->blockcnt); + to_be32(&bdesc[0], num_blocks); /* Block Length */ - to_be32(&bdesc[4], bdev->blocklen); + to_be32(&bdesc[4], block_size); } return total; @@ -1297,8 +1300,8 @@ spdk_bdev_scsi_read(struct spdk_bdev *bdev, uint64_t nbytes; int rc; - maxlba = bdev->blockcnt; - blen = bdev->blocklen; + maxlba = spdk_bdev_get_num_blocks(bdev); + blen = spdk_bdev_get_block_size(bdev); rc = spdk_bdev_scsi_read_write_lba_check(task->parent, task, lba, task->transfer_len / blen, maxlba); @@ -1352,13 +1355,13 @@ spdk_bdev_scsi_write(struct spdk_bdev *bdev, return SPDK_SCSI_TASK_COMPLETE; } - maxlba = bdev->blockcnt; + maxlba = spdk_bdev_get_num_blocks(bdev); rc = spdk_bdev_scsi_read_write_lba_check(primary, task, lba, len, maxlba); if (rc < 0) { return SPDK_SCSI_TASK_COMPLETE; } - blen = bdev->blocklen; + blen = spdk_bdev_get_block_size(bdev); offset = lba * blen; nbytes = ((uint64_t)len) * blen; @@ -1418,9 +1421,9 @@ spdk_bdev_scsi_sync(struct spdk_bdev *bdev, struct spdk_scsi_task *task, return SPDK_SCSI_TASK_COMPLETE; } - maxlba = bdev->blockcnt; + maxlba = spdk_bdev_get_num_blocks(bdev); llen = len; - blen = bdev->blocklen; + blen = spdk_bdev_get_block_size(bdev); offset = lba * blen; nbytes = llen * blen; @@ -1597,14 +1600,15 @@ spdk_bdev_scsi_process_block(struct spdk_bdev *bdev, cdb[0] == SPDK_SBC_READ_16); case SPDK_SBC_READ_CAPACITY_10: { + uint64_t num_blocks = spdk_bdev_get_num_blocks(bdev); uint8_t buffer[8]; - if (bdev->blockcnt - 1 > 0xffffffffULL) { + if (num_blocks - 1 > 0xffffffffULL) { memset(buffer, 0xff, 4); } else { - to_be32(buffer, bdev->blockcnt - 1); + to_be32(buffer, num_blocks - 1); } - to_be32(&buffer[4], bdev->blocklen); + to_be32(&buffer[4], spdk_bdev_get_block_size(bdev)); len = spdk_min(task->length, sizeof(buffer)); if (spdk_scsi_task_scatter_data(task, buffer, len) < 0) @@ -1620,8 +1624,8 @@ spdk_bdev_scsi_process_block(struct spdk_bdev *bdev, case SPDK_SBC_SAI_READ_CAPACITY_16: { uint8_t buffer[32] = {0}; - to_be64(&buffer[0], bdev->blockcnt - 1); - to_be32(&buffer[8], bdev->blocklen); + to_be64(&buffer[0], spdk_bdev_get_num_blocks(bdev) - 1); + to_be32(&buffer[8], spdk_bdev_get_block_size(bdev)); /* * Set the TPE bit to 1 to indicate thin provisioning. * The position of TPE bit is the 7th bit in 14th byte @@ -1656,7 +1660,7 @@ spdk_bdev_scsi_process_block(struct spdk_bdev *bdev, } if (len == 0) { - len = bdev->blockcnt - lba; + len = spdk_bdev_get_num_blocks(bdev) - lba; } return spdk_bdev_scsi_sync(bdev, task, lba, len); diff --git a/test/lib/bdev/bdevio/bdevio.c b/test/lib/bdev/bdevio/bdevio.c index def58037f..b45aa5b25 100644 --- a/test/lib/bdev/bdevio/bdevio.c +++ b/test/lib/bdev/bdevio/bdevio.c @@ -108,6 +108,8 @@ bdevio_construct_targets(void) bdev = spdk_bdev_first(); while (bdev != NULL) { + uint64_t num_blocks = spdk_bdev_get_num_blocks(bdev); + uint32_t block_size = spdk_bdev_get_block_size(bdev); if (!spdk_bdev_claim(bdev, NULL, NULL)) { bdev = spdk_bdev_next(bdev); @@ -116,8 +118,8 @@ bdevio_construct_targets(void) printf(" %s: %" PRIu64 " blocks of %" PRIu32 " bytes (%" PRIu64 " MiB)\n", spdk_bdev_get_name(bdev), - bdev->blockcnt, bdev->blocklen, - (bdev->blockcnt * bdev->blocklen + 1024 * 1024 - 1) / (1024 * 1024)); + num_blocks, block_size, + (num_blocks * block_size + 1024 * 1024 - 1) / (1024 * 1024)); target = malloc(sizeof(struct io_target)); if (target == NULL) { @@ -299,7 +301,7 @@ blockdev_write_read(uint32_t data_length, uint32_t iov_len, int pattern, uint64_ target = g_io_targets; while (target != NULL) { - if (data_length < target->bdev->blocklen) { + if (data_length < spdk_bdev_get_block_size(target->bdev)) { target = target->next; continue; } @@ -527,27 +529,30 @@ blockdev_write_read_offset_plus_nbytes_equals_bdev_size(void) char *tx_buf = NULL; char *rx_buf = NULL; uint64_t offset; + uint32_t block_size; int rc; target = g_io_targets; while (target != NULL) { bdev = target->bdev; + block_size = spdk_bdev_get_block_size(bdev); + /* The start offset has been set to a marginal value * such that offset + nbytes == Total size of * blockdev. */ - offset = ((bdev->blockcnt - 1) * bdev->blocklen); + offset = ((spdk_bdev_get_num_blocks(bdev) - 1) * block_size); - initialize_buffer(&tx_buf, 0xA3, bdev->blocklen); - initialize_buffer(&rx_buf, 0, bdev->blocklen); + initialize_buffer(&tx_buf, 0xA3, block_size); + initialize_buffer(&rx_buf, 0, block_size); - blockdev_write(target, tx_buf, offset, bdev->blocklen, 0); + blockdev_write(target, tx_buf, offset, block_size, 0); CU_ASSERT_EQUAL(g_completion_status, SPDK_BDEV_IO_STATUS_SUCCESS); - blockdev_read(target, rx_buf, offset, bdev->blocklen, 0); + blockdev_read(target, rx_buf, offset, block_size, 0); CU_ASSERT_EQUAL(g_completion_status, SPDK_BDEV_IO_STATUS_SUCCESS); - rc = blockdev_write_read_data_match(rx_buf, tx_buf, bdev->blocklen); + rc = blockdev_write_read_data_match(rx_buf, tx_buf, block_size); /* Assert the write by comparing it with values read * from each blockdev */ CU_ASSERT_EQUAL(rc, 0); @@ -579,7 +584,7 @@ blockdev_write_read_offset_plus_nbytes_gt_bdev_size(void) /* The start offset has been set to a valid value * but offset + nbytes is greater than the Total size * of the blockdev. The test should fail. */ - offset = ((bdev->blockcnt * bdev->blocklen) - 1024); + offset = ((spdk_bdev_get_num_blocks(bdev) * spdk_bdev_get_block_size(bdev)) - 1024); initialize_buffer(&tx_buf, pattern, data_length); initialize_buffer(&rx_buf, 0, data_length); diff --git a/test/lib/bdev/bdevperf/bdevperf.c b/test/lib/bdev/bdevperf/bdevperf.c index a3864b232..87a644877 100644 --- a/test/lib/bdev/bdevperf/bdevperf.c +++ b/test/lib/bdev/bdevperf/bdevperf.c @@ -145,7 +145,7 @@ bdevperf_construct_targets(void) target->io_completed = 0; target->current_queue_depth = 0; target->offset_in_ios = 0; - target->size_in_ios = (bdev->blockcnt * bdev->blocklen) / + target->size_in_ios = (spdk_bdev_get_num_blocks(bdev) * spdk_bdev_get_block_size(bdev)) / g_io_size; align = spdk_bdev_get_buf_align(bdev); /* @@ -263,9 +263,11 @@ bdevperf_verify_write_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_s target = task->target; if (g_unmap) { + uint32_t block_size = spdk_bdev_get_block_size(target->bdev); + /* Unmap the data */ - to_be64(&task->bdesc.lba, task->offset / target->bdev->blocklen); - to_be32(&task->bdesc.block_count, g_io_size / target->bdev->blocklen); + to_be64(&task->bdesc.lba, task->offset / block_size); + to_be32(&task->bdesc.block_count, g_io_size / block_size); spdk_bdev_unmap(target->bdev, target->ch, &task->bdesc, 1, bdevperf_unmap_complete, task); diff --git a/test/lib/nvmf/virtual/virtual_ut.c b/test/lib/nvmf/virtual/virtual_ut.c index fb4f9ff2d..aacf19fe5 100644 --- a/test/lib/nvmf/virtual/virtual_ut.c +++ b/test/lib/nvmf/virtual/virtual_ut.c @@ -103,6 +103,20 @@ spdk_bdev_get_name(const struct spdk_bdev *bdev) return "test"; } +uint32_t +spdk_bdev_get_block_size(const struct spdk_bdev *bdev) +{ + abort(); + return 0; +} + +uint64_t +spdk_bdev_get_num_blocks(const struct spdk_bdev *bdev) +{ + abort(); + return 0; +} + struct spdk_io_channel * spdk_bdev_get_io_channel(struct spdk_bdev *bdev, uint32_t priority) { diff --git a/test/lib/scsi/scsi_bdev/scsi_bdev_ut.c b/test/lib/scsi/scsi_bdev/scsi_bdev_ut.c index 56440defa..2cb7260a1 100644 --- a/test/lib/scsi/scsi_bdev/scsi_bdev_ut.c +++ b/test/lib/scsi/scsi_bdev/scsi_bdev_ut.c @@ -88,6 +88,18 @@ spdk_bdev_get_name(const struct spdk_bdev *bdev) return "test"; } +uint32_t +spdk_bdev_get_block_size(const struct spdk_bdev *bdev) +{ + return 512; +} + +uint64_t +spdk_bdev_get_num_blocks(const struct spdk_bdev *bdev) +{ + return 0; +} + const char * spdk_bdev_get_product_name(const struct spdk_bdev *bdev) {