From 18ed0c7f6b3458641b0e52ea27be106dad44bd5e Mon Sep 17 00:00:00 2001 From: Wojciech Malikowski Date: Wed, 31 Jul 2019 10:51:50 -0400 Subject: [PATCH] lib/bdev: spdk_bdev_get_write_unit_size() interface Added write_unit_size field to bdev structure. It describes required number of logical blocks for write operation. For legacy bdevs this value will be equal to logical block size. For bdevs working on top of Open Channel/Zoned Namespace SSDs or RAID 5 volumes write size unit could be greater than logical block size and upper layer should perform write operations with size of multiple of write unit size. Change-Id: I55eb6687912a7d0d1157874b2778e7d6c2d44e37 Signed-off-by: Wojciech Malikowski Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/463802 Tested-by: SPDK CI Jenkins Reviewed-by: Paul Luse Reviewed-by: Maciej Szwed Reviewed-by: Ben Walker Reviewed-by: Shuhei Matsumoto Community-CI: Broadcom SPDK FC-NVMe CI --- CHANGELOG.md | 5 +++++ include/spdk/bdev.h | 15 +++++++++++++++ include/spdk/bdev_module.h | 3 +++ lib/bdev/bdev.c | 11 +++++++++++ 4 files changed, 34 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4b471462..9f85733e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## v19.10: (Upcoming Release) +### bdev + +Added `spdk_bdev_get_write_unit_size()` function for retrieving required number +of logical blocks for write operation. + ### nvmf The `spdk_nvmf_tgt_create` function now accepts an object of type `spdk_nvmf_target_opts` diff --git a/include/spdk/bdev.h b/include/spdk/bdev.h index cd55e63d5..4bf4810b4 100644 --- a/include/spdk/bdev.h +++ b/include/spdk/bdev.h @@ -368,6 +368,21 @@ const char *spdk_bdev_get_product_name(const struct spdk_bdev *bdev); */ uint32_t spdk_bdev_get_block_size(const struct spdk_bdev *bdev); +/** + * Get the write unit size for this bdev. + * + * Write unit size is required number of logical blocks to perform write + * operation on block device. + * + * Unit of write unit size is logical block and the minimum of write unit + * size is one. Write operations must be multiple of write unit size. + * + * \param bdev Block device to query. + * + * \return The write unit size in logical blocks. + */ +uint32_t spdk_bdev_get_write_unit_size(const struct spdk_bdev *bdev); + /** * Get size of block device in logical blocks. * diff --git a/include/spdk/bdev_module.h b/include/spdk/bdev_module.h index 1af89306d..97f279cbf 100644 --- a/include/spdk/bdev_module.h +++ b/include/spdk/bdev_module.h @@ -265,6 +265,9 @@ struct spdk_bdev { /** Number of blocks */ uint64_t blockcnt; + /** Number of blocks required for write */ + uint32_t write_unit_size; + /** * Specifies an alignment requirement for data buffers associated with an spdk_bdev_io. * 0 = no alignment requirement diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index 970437249..0740d2574 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -2437,6 +2437,12 @@ spdk_bdev_get_block_size(const struct spdk_bdev *bdev) return bdev->blocklen; } +uint32_t +spdk_bdev_get_write_unit_size(const struct spdk_bdev *bdev) +{ + return bdev->write_unit_size; +} + uint64_t spdk_bdev_get_num_blocks(const struct spdk_bdev *bdev) { @@ -4073,6 +4079,11 @@ spdk_bdev_init(struct spdk_bdev *bdev) } } + /* If the user didn't specify a write unit size, set it to one. */ + if (bdev->write_unit_size == 0) { + bdev->write_unit_size = 1; + } + TAILQ_INIT(&bdev->internal.open_descs); TAILQ_INIT(&bdev->aliases);