bdev/virtio/scsi: don't ever allow unregistering the same bdev twice

Consider the following scenario:
 * user deletes a Virtio-SCSI bdev (spdk_bdev_unregister)
 * user deletes entire Virtio-SCSI controller (virtio_scsi_dev_remove)

If there were any descriptors open with asynchronous
remove callback specified, the first bdev unregister
won't delete the bdev and won't notify the Virtio-SCSI
controller in any way. Subsequent Virtio-SCSI controller
deletion might result in unregistering the same bdev
again. This patch makes Virtio-SCSI controller open a
dummy descriptor on each of its bdevs, so that it's
notified of any started bdev_unregister

Change-Id: I9a8c841d08393ef1940c4cebc9dfcb58e9b0ac4a
Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/394169
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: <shuhei.matsumoto.xt@hitachi.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 2018-01-10 07:43:11 +01:00 committed by Jim Harris
parent 6a9fe9addc
commit 5eb213cec7

View File

@ -154,6 +154,12 @@ struct virtio_scsi_disk {
struct spdk_bdev bdev;
struct virtio_scsi_dev *svdev;
struct virtio_scsi_scan_info info;
/** Descriptor opened just to be notified of external bdev hotremove. */
struct spdk_bdev_desc *notify_desc;
/** Disk marked for removal. */
bool removed;
TAILQ_ENTRY(virtio_scsi_disk) link;
};
@ -1204,6 +1210,15 @@ process_scan_inquiry(struct virtio_scsi_scan_base *base)
}
}
static void
bdev_virtio_disc_notify_remove(void *remove_ctx)
{
struct virtio_scsi_disk *disk = remove_ctx;
disk->removed = true;
spdk_bdev_close(disk->notify_desc);
}
/* To be called only from the thread performing target scan */
static int
virtio_scsi_dev_add_tgt(struct virtio_scsi_dev *svdev, struct virtio_scsi_scan_info *info)
@ -1252,6 +1267,11 @@ virtio_scsi_dev_add_tgt(struct virtio_scsi_dev *svdev, struct virtio_scsi_scan_i
return rc;
}
rc = spdk_bdev_open(bdev, false, bdev_virtio_disc_notify_remove, disk, &disk->notify_desc);
if (rc) {
assert(false);
}
TAILQ_INSERT_TAIL(&svdev->luns, disk, link);
return 0;
}
@ -1717,7 +1737,9 @@ virtio_scsi_dev_remove(struct virtio_scsi_dev *svdev)
}
TAILQ_FOREACH_SAFE(disk, &svdev->luns, link, disk_tmp) {
spdk_bdev_unregister(&disk->bdev, NULL, NULL);
if (!disk->removed) {
spdk_bdev_unregister(&disk->bdev, NULL, NULL);
}
do_remove = false;
}