diff --git a/module/bdev/raid/bdev_raid.c b/module/bdev/raid/bdev_raid.c index 0ea557fab..c61fb5f85 100644 --- a/module/bdev/raid/bdev_raid.c +++ b/module/bdev/raid/bdev_raid.c @@ -277,6 +277,14 @@ raid_bdev_io_device_unregister_cb(void *io_device) } } +void +raid_bdev_module_stop_done(struct raid_bdev *raid_bdev) +{ + if (raid_bdev->state != RAID_BDEV_STATE_CONFIGURING) { + spdk_io_device_unregister(raid_bdev, raid_bdev_io_device_unregister_cb); + } +} + /* * brief: * raid_bdev_destruct is the destruct function table pointer for raid bdev @@ -313,10 +321,12 @@ raid_bdev_destruct(void *ctxt) } if (raid_bdev->module->stop != NULL) { - raid_bdev->module->stop(raid_bdev); + if (raid_bdev->module->stop(raid_bdev) == false) { + return 1; + } } - spdk_io_device_unregister(raid_bdev, raid_bdev_io_device_unregister_cb); + raid_bdev_module_stop_done(raid_bdev); return 1; } diff --git a/module/bdev/raid/bdev_raid.h b/module/bdev/raid/bdev_raid.h index d459b4ab8..fb3a5f20b 100644 --- a/module/bdev/raid/bdev_raid.h +++ b/module/bdev/raid/bdev_raid.h @@ -262,8 +262,12 @@ struct raid_bdev_module { /* * Called when the raid is stopping, right before changing the state to * offline and unregistering the bdev. Optional. + * + * The function should return false if it is asynchronous. Then, after + * the async operation has completed and the module is fully stopped + * raid_bdev_module_stop_done() must be called. */ - void (*stop)(struct raid_bdev *raid_bdev); + bool (*stop)(struct raid_bdev *raid_bdev); /* Handler for R/W requests */ void (*submit_rw_request)(struct raid_bdev_io *raid_io); @@ -297,5 +301,6 @@ bool raid_bdev_io_complete_part(struct raid_bdev_io *raid_io, uint64_t completed void raid_bdev_queue_io_wait(struct raid_bdev_io *raid_io, struct spdk_bdev *bdev, struct spdk_io_channel *ch, spdk_bdev_io_wait_cb cb_fn); void raid_bdev_io_complete(struct raid_bdev_io *raid_io, enum spdk_bdev_io_status status); +void raid_bdev_module_stop_done(struct raid_bdev *raid_bdev); #endif /* SPDK_BDEV_RAID_INTERNAL_H */ diff --git a/module/bdev/raid/concat.c b/module/bdev/raid/concat.c index 761e05b39..c35dbb589 100644 --- a/module/bdev/raid/concat.c +++ b/module/bdev/raid/concat.c @@ -300,12 +300,14 @@ concat_start(struct raid_bdev *raid_bdev) return 0; } -static void +static bool concat_stop(struct raid_bdev *raid_bdev) { struct concat_block_range *block_range = raid_bdev->module_private; free(block_range); + + return true; } static struct raid_bdev_module g_concat_module = { diff --git a/module/bdev/raid/raid5f.c b/module/bdev/raid/raid5f.c index 9a0f94063..8b0a71941 100644 --- a/module/bdev/raid/raid5f.c +++ b/module/bdev/raid/raid5f.c @@ -671,15 +671,19 @@ raid5f_io_device_unregister_done(void *io_device) { struct raid5f_info *r5f_info = io_device; + raid_bdev_module_stop_done(r5f_info->raid_bdev); + free(r5f_info); } -static void +static bool raid5f_stop(struct raid_bdev *raid_bdev) { struct raid5f_info *r5f_info = raid_bdev->module_private; spdk_io_device_unregister(r5f_info, raid5f_io_device_unregister_done); + + return false; } static struct spdk_io_channel * diff --git a/test/unit/lib/bdev/raid/raid5f.c/raid5f_ut.c b/test/unit/lib/bdev/raid/raid5f.c/raid5f_ut.c index 262f418c4..5b9a8552d 100644 --- a/test/unit/lib/bdev/raid/raid5f.c/raid5f_ut.c +++ b/test/unit/lib/bdev/raid/raid5f.c/raid5f_ut.c @@ -13,6 +13,7 @@ DEFINE_STUB_V(raid_bdev_module_list_add, (struct raid_bdev_module *raid_module)); DEFINE_STUB(spdk_bdev_get_buf_align, size_t, (const struct spdk_bdev *bdev), 0); +DEFINE_STUB_V(raid_bdev_module_stop_done, (struct raid_bdev *raid_bdev)); struct spdk_bdev_desc { struct spdk_bdev *bdev;