From ade146b966e42b4ec6de7b377f026340d87edf31 Mon Sep 17 00:00:00 2001 From: Ben Walker Date: Mon, 16 Apr 2018 14:45:53 -0700 Subject: [PATCH] bdev: Wait for io device to unregister in bdev_part Change-Id: I6627fd4253094548816c50bd97e13b22dc245df1 Signed-off-by: Ben Walker Reviewed-on: https://review.gerrithub.io/407838 Reviewed-by: Jim Harris Reviewed-by: Daniel Verkamp Tested-by: SPDK Automated Test System --- include/spdk_internal/bdev.h | 2 +- lib/bdev/error/vbdev_error.c | 3 +-- lib/bdev/gpt/vbdev_gpt.c | 3 +-- lib/bdev/part.c | 23 ++++++++++++++++++----- lib/bdev/split/vbdev_split.c | 3 +-- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/include/spdk_internal/bdev.h b/include/spdk_internal/bdev.h index 48e0ccd84..d978a56bd 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 108c1967c..2226785ec 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 c8b8d89ae..1cae051d3 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 ff837effe..e1c54266b 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 b9ef5dc21..542bd6c97 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