bdev.c: defer destroy until dev_unregister returns
by placing the destroy function in the callback of the io_device_unregister, we ensure that all channels associated with a bdev will be freed before the bdev is destroyed. This eliminates the possibility of an io_channel callback referencing a destroyed bdev. Change-Id: I0dd6f53dcfa9c9c5a3c6e98a7e2ad8687da17c3f Signed-off-by: Seth Howell <seth.howell@intel.com> Reviewed-on: https://review.gerrithub.io/406248 Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
ce6a7cd8b8
commit
105dcc0bd9
@ -2481,12 +2481,34 @@ spdk_bdev_init(struct spdk_bdev *bdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
spdk_bdev_destroy_cb(void *io_device)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
struct spdk_bdev *bdev;
|
||||||
|
spdk_bdev_unregister_cb cb_fn;
|
||||||
|
void *cb_arg;
|
||||||
|
|
||||||
|
bdev = __bdev_from_io_dev(io_device);
|
||||||
|
cb_fn = bdev->unregister_cb;
|
||||||
|
cb_arg = bdev->unregister_ctx;
|
||||||
|
|
||||||
|
rc = bdev->fn_table->destruct(bdev->ctxt);
|
||||||
|
if (rc < 0) {
|
||||||
|
SPDK_ERRLOG("destruct failed\n");
|
||||||
|
}
|
||||||
|
if (rc <= 0 && cb_fn != NULL) {
|
||||||
|
cb_fn(cb_arg, rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
spdk_bdev_fini(struct spdk_bdev *bdev)
|
spdk_bdev_fini(struct spdk_bdev *bdev)
|
||||||
{
|
{
|
||||||
pthread_mutex_destroy(&bdev->mutex);
|
pthread_mutex_destroy(&bdev->mutex);
|
||||||
|
|
||||||
spdk_io_device_unregister(__bdev_to_io_dev(bdev), NULL);
|
spdk_io_device_unregister(__bdev_to_io_dev(bdev), spdk_bdev_destroy_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2651,7 +2673,6 @@ void
|
|||||||
spdk_bdev_unregister(struct spdk_bdev *bdev, spdk_bdev_unregister_cb cb_fn, void *cb_arg)
|
spdk_bdev_unregister(struct spdk_bdev *bdev, spdk_bdev_unregister_cb cb_fn, void *cb_arg)
|
||||||
{
|
{
|
||||||
struct spdk_bdev_desc *desc, *tmp;
|
struct spdk_bdev_desc *desc, *tmp;
|
||||||
int rc;
|
|
||||||
bool do_destruct = true;
|
bool do_destruct = true;
|
||||||
|
|
||||||
SPDK_DEBUGLOG(SPDK_LOG_BDEV, "Removing bdev %s from list\n", bdev->name);
|
SPDK_DEBUGLOG(SPDK_LOG_BDEV, "Removing bdev %s from list\n", bdev->name);
|
||||||
@ -2686,14 +2707,6 @@ spdk_bdev_unregister(struct spdk_bdev *bdev, spdk_bdev_unregister_cb cb_fn, void
|
|||||||
pthread_mutex_unlock(&bdev->mutex);
|
pthread_mutex_unlock(&bdev->mutex);
|
||||||
|
|
||||||
spdk_bdev_fini(bdev);
|
spdk_bdev_fini(bdev);
|
||||||
|
|
||||||
rc = bdev->fn_table->destruct(bdev->ctxt);
|
|
||||||
if (rc < 0) {
|
|
||||||
SPDK_ERRLOG("destruct failed\n");
|
|
||||||
}
|
|
||||||
if (rc <= 0 && cb_fn != NULL) {
|
|
||||||
cb_fn(cb_arg, rc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
Loading…
Reference in New Issue
Block a user