Commit f118de60 authored by wuzhouhui's avatar wuzhouhui Committed by Ben Walker
Browse files

bdev: fix race condition between spdk_bdev_close and _remove_notify



When new bdev was created, the struct spdk_bdev_module::examine_disk()
may open and close bdev. On the other hand, if something goes wrong,
the creation procedure may unregister new created bdev, so race
condition appeared between _remove_notify() and spdk_bdev_close().

Add the new field "closed" and "remove_notified" in struct spdk_bdev_desc,
so _remove_notify() and spdk_bdev_close() knows how to deal with this
situation.

Change-Id: Ibfe915a4d76096796b039a13a4f49f26669eba2c
Signed-off-by: default avatarwuzhouhui <wuzhouhui@kingsoft.com>
Reviewed-on: https://review.gerrithub.io/423369


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 898739fb
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -263,6 +263,7 @@ struct spdk_bdev_desc {
	spdk_bdev_remove_cb_t		remove_cb;
	void				*remove_ctx;
	bool				remove_scheduled;
	bool				closed;
	bool				write;
	TAILQ_ENTRY(spdk_bdev_desc)	link;
};
@@ -3174,8 +3175,14 @@ _remove_notify(void *arg)
{
	struct spdk_bdev_desc *desc = arg;

	desc->remove_scheduled = false;

	if (desc->closed) {
		free(desc);
	} else {
		desc->remove_cb(desc->remove_ctx);
	}
}

void
spdk_bdev_unregister(struct spdk_bdev *bdev, spdk_bdev_unregister_cb cb_fn, void *cb_arg)
@@ -3289,7 +3296,12 @@ spdk_bdev_close(struct spdk_bdev_desc *desc)
	pthread_mutex_lock(&bdev->internal.mutex);

	TAILQ_REMOVE(&bdev->internal.open_descs, desc, link);

	desc->closed = true;

	if (!desc->remove_scheduled) {
		free(desc);
	}

	/* If no more descriptors, kill QoS channel */
	if (bdev->internal.qos && TAILQ_EMPTY(&bdev->internal.open_descs)) {