bdev: don't call recursively desc->remove_cb on bdev removal
When device has more than one open descriptor, remove_cbs of particular
descriptors could be called more than once.
Consider the following scenario:
bdev X with 2 open descriptors A and B.
X is removed (hotremoved for instance)
bdev_unregister(X) is called
* bdev->status = REMOVING
* A->remove_cb is called
* some poller is started
* B->remove_cb is called
* another poller started
* poller from A->remove_cb finishes it's work and closes the desc:
* bdev_close(A)
* A is removed from bdev->open_descs list
* bdev->status is REMOVING, so bdev_unregister(X) is called again!
* B->remove cb is called again!
* another poller starts? segfault?
Fixes: 57d174ff67
("bdev: add spdk_bdev_open/close")
Change-Id: I0a898ec0aee521d0b2a1168fe7d469cc41a8ef4f
Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/369727
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
ebaa8ff7f9
commit
32f86a5f34
@ -1560,7 +1560,7 @@ spdk_bdev_close(struct spdk_bdev_desc *desc)
|
|||||||
TAILQ_REMOVE(&bdev->open_descs, desc, link);
|
TAILQ_REMOVE(&bdev->open_descs, desc, link);
|
||||||
free(desc);
|
free(desc);
|
||||||
|
|
||||||
if (bdev->status == SPDK_BDEV_STATUS_REMOVING) {
|
if (bdev->status == SPDK_BDEV_STATUS_REMOVING && TAILQ_EMPTY(&bdev->open_descs)) {
|
||||||
do_unregister = true;
|
do_unregister = true;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&bdev->mutex);
|
pthread_mutex_unlock(&bdev->mutex);
|
||||||
|
Loading…
Reference in New Issue
Block a user