diff --git a/include/spdk_internal/bdev.h b/include/spdk_internal/bdev.h index 48e0ccd840..d978a56bde 100644 --- a/include/spdk_internal/bdev.h +++ b/include/spdk_internal/bdev.h @@ -610,7 +610,7 @@ struct spdk_bdev_part_channel { typedef TAILQ_HEAD(bdev_part_tailq, spdk_bdev_part) SPDK_BDEV_PART_TAILQ; void spdk_bdev_part_base_free(struct spdk_bdev_part_base *base); -void spdk_bdev_part_free(struct spdk_bdev_part *part); +int spdk_bdev_part_free(struct spdk_bdev_part *part); void spdk_bdev_part_base_hotremove(struct spdk_bdev *base_bdev, struct bdev_part_tailq *tailq); int spdk_bdev_part_base_construct(struct spdk_bdev_part_base *base, struct spdk_bdev *bdev, spdk_bdev_remove_cb_t remove_cb, diff --git a/lib/bdev/error/vbdev_error.c b/lib/bdev/error/vbdev_error.c index 108c1967ce..2226785ec5 100644 --- a/lib/bdev/error/vbdev_error.c +++ b/lib/bdev/error/vbdev_error.c @@ -220,8 +220,7 @@ vbdev_error_destruct(void *ctx) SPDK_ERRLOG("vbdev_error_config_remove() failed\n"); } - spdk_bdev_part_free(&error_disk->part); - return rc; + return spdk_bdev_part_free(&error_disk->part); } static int diff --git a/lib/bdev/gpt/vbdev_gpt.c b/lib/bdev/gpt/vbdev_gpt.c index c8b8d89aed..1cae051d3c 100644 --- a/lib/bdev/gpt/vbdev_gpt.c +++ b/lib/bdev/gpt/vbdev_gpt.c @@ -152,8 +152,7 @@ vbdev_gpt_destruct(void *ctx) { struct gpt_disk *gpt_disk = ctx; - spdk_bdev_part_free(&gpt_disk->part); - return 0; + return spdk_bdev_part_free(&gpt_disk->part); } static void diff --git a/lib/bdev/part.c b/lib/bdev/part.c index ff837effe7..e1c54266b9 100644 --- a/lib/bdev/part.c +++ b/lib/bdev/part.c @@ -50,24 +50,37 @@ spdk_bdev_part_base_free(struct spdk_bdev_part_base *base) base->base_free_fn(base); } -void -spdk_bdev_part_free(struct spdk_bdev_part *part) +static void +spdk_bdev_part_free_cb(void *io_device) { + struct spdk_bdev_part *part = io_device; struct spdk_bdev_part_base *base; assert(part); assert(part->base); base = part->base; - spdk_io_device_unregister(part, NULL); + TAILQ_REMOVE(base->tailq, part, tailq); - free(part->bdev.name); - free(part); if (__sync_sub_and_fetch(&base->ref, 1) == 0) { spdk_bdev_module_release_bdev(base->bdev); spdk_bdev_part_base_free(base); } + + spdk_bdev_destruct_done(&part->bdev, 0); + free(part->bdev.name); + free(part); +} + +int +spdk_bdev_part_free(struct spdk_bdev_part *part) +{ + spdk_io_device_unregister(part, spdk_bdev_part_free_cb); + + /* Return 1 to indicate that this is an asynchronous operation that isn't complete + * until spdk_bdev_destruct_done is called */ + return 1; } void diff --git a/lib/bdev/split/vbdev_split.c b/lib/bdev/split/vbdev_split.c index b9ef5dc217..542bd6c976 100644 --- a/lib/bdev/split/vbdev_split.c +++ b/lib/bdev/split/vbdev_split.c @@ -100,8 +100,7 @@ vbdev_split_destruct(void *ctx) { struct spdk_bdev_part *part = ctx; - spdk_bdev_part_free(part); - return 0; + return spdk_bdev_part_free(part); } static void