diff --git a/include/spdk/bdev_module.h b/include/spdk/bdev_module.h index 925e106e8..ac7739625 100644 --- a/include/spdk/bdev_module.h +++ b/include/spdk/bdev_module.h @@ -361,6 +361,11 @@ struct spdk_bdev { */ uint64_t zone_size; + /** + * Maximum zone append data transfer size (in blocks). + */ + uint32_t max_zone_append_size; + /** * Maximum number of open zones. */ diff --git a/include/spdk/bdev_zone.h b/include/spdk/bdev_zone.h index 684b6372d..cbfef5bba 100644 --- a/include/spdk/bdev_zone.h +++ b/include/spdk/bdev_zone.h @@ -84,6 +84,16 @@ struct spdk_bdev_zone_info { */ uint64_t spdk_bdev_get_zone_size(const struct spdk_bdev *bdev); +/** + * Get device maximum zone append data transfer size in logical blocks. + * + * If this value is 0, there is no limit. + * + * \param bdev Block device to query. + * \return Maximum zone append data transfer size for this zoned device in logical blocks. + */ +uint32_t spdk_bdev_get_max_zone_append_size(const struct spdk_bdev *bdev); + /** * Get device maximum number of open zones. * diff --git a/lib/bdev/bdev_zone.c b/lib/bdev/bdev_zone.c index 6cec0014e..fa41f979c 100644 --- a/lib/bdev/bdev_zone.c +++ b/lib/bdev/bdev_zone.c @@ -44,6 +44,12 @@ spdk_bdev_get_zone_size(const struct spdk_bdev *bdev) return bdev->zone_size; } +uint32_t +spdk_bdev_get_max_zone_append_size(const struct spdk_bdev *bdev) +{ + return bdev->max_zone_append_size; +} + uint32_t spdk_bdev_get_max_open_zones(const struct spdk_bdev *bdev) { diff --git a/lib/bdev/spdk_bdev.map b/lib/bdev/spdk_bdev.map index 9b4907e9b..7f3e648bc 100644 --- a/lib/bdev/spdk_bdev.map +++ b/lib/bdev/spdk_bdev.map @@ -143,6 +143,7 @@ # Public functions in bdev_zone.h spdk_bdev_get_zone_size; + spdk_bdev_get_max_zone_append_size; spdk_bdev_get_max_open_zones; spdk_bdev_get_max_active_zones; spdk_bdev_get_optimal_open_zones; diff --git a/module/bdev/nvme/bdev_ocssd.c b/module/bdev/nvme/bdev_ocssd.c index 38dfd96e5..395a5fbcf 100644 --- a/module/bdev/nvme/bdev_ocssd.c +++ b/module/bdev/nvme/bdev_ocssd.c @@ -1305,6 +1305,9 @@ bdev_ocssd_create_bdev(const char *ctrlr_name, const char *bdev_name, uint32_t n nvme_bdev->disk.blockcnt = geometry->num_grp * geometry->num_pu * geometry->num_chk * geometry->clba; nvme_bdev->disk.zone_size = geometry->clba; + /* Since zone appends are emulated using writes, use max io xfer size (but in blocks) */ + nvme_bdev->disk.max_zone_append_size = spdk_nvme_ns_get_max_io_xfer_size(ns) / + spdk_nvme_ns_get_extended_sector_size(ns); nvme_bdev->disk.max_open_zones = geometry->maxoc; nvme_bdev->disk.optimal_open_zones = geometry->num_grp * geometry->num_pu; nvme_bdev->disk.write_unit_size = geometry->ws_opt; diff --git a/test/unit/lib/bdev/bdev_zone.c/bdev_zone_ut.c b/test/unit/lib/bdev/bdev_zone.c/bdev_zone_ut.c index 3c293cbaf..a5c053ca6 100644 --- a/test/unit/lib/bdev/bdev_zone.c/bdev_zone_ut.c +++ b/test/unit/lib/bdev/bdev_zone.c/bdev_zone_ut.c @@ -254,6 +254,18 @@ test_get_zone_size(void) CU_ASSERT(get_zone_size == 1024 * 4096); } +static void +test_get_max_zone_append_size(void) +{ + struct spdk_bdev bdev = {}; + uint32_t get_max_zone_append_size; + + bdev.max_zone_append_size = 32; + + get_max_zone_append_size = spdk_bdev_get_max_zone_append_size(&bdev); + CU_ASSERT(get_max_zone_append_size == 32); +} + static void test_get_max_open_zones(void) { @@ -306,6 +318,7 @@ static void test_zone_get_operation(void) { test_get_zone_size(); + test_get_max_zone_append_size(); test_get_max_open_zones(); test_get_max_active_zones(); test_get_optimal_open_zones(); diff --git a/test/unit/lib/bdev/nvme/bdev_ocssd.c/bdev_ocssd_ut.c b/test/unit/lib/bdev/nvme/bdev_ocssd.c/bdev_ocssd_ut.c index b547b49e0..3f9db68e0 100644 --- a/test/unit/lib/bdev/nvme/bdev_ocssd.c/bdev_ocssd_ut.c +++ b/test/unit/lib/bdev/nvme/bdev_ocssd.c/bdev_ocssd_ut.c @@ -48,6 +48,7 @@ DEFINE_STUB_V(spdk_bdev_module_list_add, (struct spdk_bdev_module *bdev_module)) DEFINE_STUB(spdk_nvme_ctrlr_is_ocssd_ns, bool, (struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid), true); DEFINE_STUB(spdk_nvme_ns_get_extended_sector_size, uint32_t, (struct spdk_nvme_ns *ns), 4096); +DEFINE_STUB(spdk_nvme_ns_get_max_io_xfer_size, uint32_t, (struct spdk_nvme_ns *ns), 0); DEFINE_STUB(spdk_nvme_ns_is_active, bool, (struct spdk_nvme_ns *ns), true); DEFINE_STUB_V(spdk_opal_dev_destruct, (struct spdk_opal_dev *dev)); DEFINE_STUB_V(spdk_bdev_io_complete_nvme_status, (struct spdk_bdev_io *bdev_io, uint32_t cdw0,