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: 57d174ff6797 ("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:
Dariusz Stojaczyk 2017-07-17 12:00:08 +02:00 committed by Daniel Verkamp
parent ebaa8ff7f9
commit 32f86a5f34

View File

@ -1560,7 +1560,7 @@ spdk_bdev_close(struct spdk_bdev_desc *desc)
TAILQ_REMOVE(&bdev->open_descs, desc, link);
free(desc);
if (bdev->status == SPDK_BDEV_STATUS_REMOVING) {
if (bdev->status == SPDK_BDEV_STATUS_REMOVING && TAILQ_EMPTY(&bdev->open_descs)) {
do_unregister = true;
}
pthread_mutex_unlock(&bdev->mutex);