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: wuzhouhui <wuzhouhui@kingsoft.com> Reviewed-on: https://review.gerrithub.io/423369 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
898739fbac
commit
f118de60af
@ -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,7 +3175,13 @@ _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
|
||||
@ -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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user