diff --git a/include/spdk_internal/bdev.h b/include/spdk_internal/bdev.h index 60b568e58..6d4b5c692 100644 --- a/include/spdk_internal/bdev.h +++ b/include/spdk_internal/bdev.h @@ -487,6 +487,18 @@ void spdk_bdev_io_complete_scsi_status(struct spdk_bdev_io *bdev_io, enum spdk_s */ struct spdk_thread *spdk_bdev_io_get_thread(struct spdk_bdev_io *bdev_io); +/** + * Resize for a bdev. + * + * Change number of blocks for provided block device. + * It can only be called on a registered bdev. + * + * \param bdev Block device to change. + * \param size New size of bdev. + * \return 0 on success, negated errno on failure. + */ +int spdk_bdev_notify_blockcnt_change(struct spdk_bdev *bdev, uint64_t size); + void spdk_scsi_nvme_translate(const struct spdk_bdev_io *bdev_io, int *sc, int *sk, int *asc, int *ascq); diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index 178555b82..7a2404bbf 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -1124,6 +1124,27 @@ spdk_bdev_has_write_cache(const struct spdk_bdev *bdev) return bdev->write_cache; } +int +spdk_bdev_notify_blockcnt_change(struct spdk_bdev *bdev, uint64_t size) +{ + int ret; + + pthread_mutex_lock(&bdev->mutex); + + /* bdev has open descriptors */ + if (!TAILQ_EMPTY(&bdev->open_descs) && + bdev->blockcnt > size) { + ret = -EBUSY; + } else { + bdev->blockcnt = size; + ret = 0; + } + + pthread_mutex_unlock(&bdev->mutex); + + return ret; +} + /* * Convert I/O offset and length from bytes to blocks. * diff --git a/lib/bdev/lvol/vbdev_lvol.c b/lib/bdev/lvol/vbdev_lvol.c index 031e35b85..6b91d6932 100644 --- a/lib/bdev/lvol/vbdev_lvol.c +++ b/lib/bdev/lvol/vbdev_lvol.c @@ -791,7 +791,10 @@ vbdev_lvol_resize(char *name, size_t sz, rc = spdk_lvol_resize(lvol, sz, _vbdev_lvol_resize_cb, req); if (rc == 0) { - bdev->blockcnt = sz * cluster_size / bdev->blocklen; + rc = spdk_bdev_notify_blockcnt_change(bdev, sz * cluster_size / bdev->blocklen); + if (rc != 0) { + SPDK_ERRLOG("Could not change num blocks for bdev_lvol.\n"); + } } return rc; diff --git a/test/unit/lib/bdev/bdev.c/bdev_ut.c b/test/unit/lib/bdev/bdev.c/bdev_ut.c index 7e767ddf2..070df2270 100644 --- a/test/unit/lib/bdev/bdev.c/bdev_ut.c +++ b/test/unit/lib/bdev/bdev.c/bdev_ut.c @@ -286,6 +286,36 @@ bytes_to_blocks_test(void) CU_ASSERT(spdk_bdev_bytes_to_blocks(&bdev, 512, &offset_blocks, 3, &num_blocks) != 0); } +static void +num_blocks_test(void) +{ + struct spdk_bdev bdev; + struct spdk_bdev_desc *desc; + + memset(&bdev, 0, sizeof(bdev)); + bdev.name = "num_blocks"; + bdev.fn_table = &fn_table; + bdev.module = SPDK_GET_BDEV_MODULE(bdev_ut); + spdk_bdev_register(&bdev); + spdk_bdev_notify_blockcnt_change(&bdev, 50); + + /* Growing block number */ + CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 70) == 0); + /* Shrinking block number */ + CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 30) == 0); + + /* In case bdev opened */ + spdk_bdev_open(&bdev, false, NULL, NULL, &desc); + + /* Growing block number */ + CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 80) == 0); + /* Shrinking block number */ + CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 20) != 0); + + spdk_bdev_close(desc); + spdk_bdev_unregister(&bdev, NULL, NULL); +} + static void io_valid_test(void) { @@ -294,7 +324,7 @@ io_valid_test(void) memset(&bdev, 0, sizeof(bdev)); bdev.blocklen = 512; - bdev.blockcnt = 100; + spdk_bdev_notify_blockcnt_change(&bdev, 100); /* All parameters valid */ CU_ASSERT(spdk_bdev_io_valid_blocks(&bdev, 1, 2) == true); @@ -451,6 +481,7 @@ main(int argc, char **argv) if ( CU_add_test(suite, "bytes_to_blocks_test", bytes_to_blocks_test) == NULL || + CU_add_test(suite, "num_blocks_test", num_blocks_test) == NULL || CU_add_test(suite, "io_valid", io_valid_test) == NULL || CU_add_test(suite, "open_write", open_write_test) == NULL || CU_add_test(suite, "part", part_test) == NULL || diff --git a/test/unit/lib/bdev/pmem/bdev_pmem_ut.c b/test/unit/lib/bdev/pmem/bdev_pmem_ut.c index c8d0986df..1d98dab1f 100644 --- a/test/unit/lib/bdev/pmem/bdev_pmem_ut.c +++ b/test/unit/lib/bdev/pmem/bdev_pmem_ut.c @@ -280,6 +280,13 @@ spdk_bdev_module_finish_done(void) { } +int +spdk_bdev_notify_blockcnt_change(struct spdk_bdev *bdev, uint64_t size) +{ + bdev->blockcnt = size; + return 0; +} + static void ut_bdev_pmem_destruct(struct spdk_bdev *bdev) { diff --git a/test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c b/test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c index 6b1ed2713..1d657f080 100644 --- a/test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c +++ b/test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c @@ -242,6 +242,13 @@ spdk_lvol_resize(struct spdk_lvol *lvol, size_t sz, spdk_lvol_op_complete cb_fn return 0; } +int +spdk_bdev_notify_blockcnt_change(struct spdk_bdev *bdev, uint64_t size) +{ + bdev->blockcnt = size; + return 0; +} + uint64_t spdk_bs_get_cluster_size(struct spdk_blob_store *bs) { diff --git a/test/unit/lib/lvol/lvol.c/lvol_ut.c b/test/unit/lib/lvol/lvol.c/lvol_ut.c index a792901fb..15b47dae9 100644 --- a/test/unit/lib/lvol/lvol.c/lvol_ut.c +++ b/test/unit/lib/lvol/lvol.c/lvol_ut.c @@ -203,6 +203,13 @@ spdk_bs_get_page_size(struct spdk_blob_store *bs) return BS_PAGE_SIZE; } +int +spdk_bdev_notify_blockcnt_change(struct spdk_bdev *bdev, uint64_t size) +{ + bdev->blockcnt = size; + return 0; +} + static void init_dev(struct lvol_ut_bs_dev *dev) {