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:
Seth Howell 2018-04-03 14:27:23 -07:00 committed by Jim Harris
parent ce6a7cd8b8
commit 105dcc0bd9

View File

@ -2481,12 +2481,34 @@ spdk_bdev_init(struct spdk_bdev *bdev)
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
spdk_bdev_fini(struct spdk_bdev *bdev)
{
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
@ -2651,7 +2673,6 @@ void
spdk_bdev_unregister(struct spdk_bdev *bdev, spdk_bdev_unregister_cb cb_fn, void *cb_arg)
{
struct spdk_bdev_desc *desc, *tmp;
int rc;
bool do_destruct = true;
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);
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