@@ -110,20 +110,16 @@ void override_max_devs(BlockInterfaceType type, int max_devs)
/*
* We automatically delete the drive when a device using it gets
* unplugged. Questionable feature, but we can't just drop it.
- * Device models call blockdev_mark_auto_del() to schedule the
- * automatic deletion, and generic qdev code calls blockdev_auto_del()
- * when deletion is actually safe.
+ * Device models call blockdev_del_drive() to schedule the
+ * automatic deletion, and generic block layer code uses the
+ * refcount to do the deletion when it is actually safe.
*/
-void blockdev_mark_auto_del(BlockBackend *blk)
+void blockdev_del_drive(BlockBackend *blk)
{
DriveInfo *dinfo = blk_legacy_dinfo(blk);
BlockDriverState *bs = blk_bs(blk);
AioContext *aio_context;
- if (!dinfo) {
- return;
- }
-
if (bs) {
aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
@@ -135,14 +131,7 @@ void blockdev_mark_auto_del(BlockBackend *blk)
aio_context_release(aio_context);
}
- dinfo->auto_del = 1;
-}
-
-void blockdev_auto_del(BlockBackend *blk)
-{
- DriveInfo *dinfo = blk_legacy_dinfo(blk);
-
- if (dinfo && dinfo->auto_del) {
+ if (dinfo) {
blk_unref(blk);
}
}
@@ -960,7 +960,9 @@ static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
s->dataplane = NULL;
qemu_del_vm_change_state_handler(s->change);
unregister_savevm(dev, "virtio-blk", s);
- blockdev_mark_auto_del(s->blk);
+ blk_detach_dev(s->blk, dev);
+ blockdev_del_drive(s->blk);
+ s->blk = NULL;
virtio_cleanup(vdev);
}
@@ -1054,6 +1054,7 @@ static void blk_disconnect(struct XenDevice *xendev)
if (blkdev->blk) {
blk_detach_dev(blkdev->blk, blkdev);
+ blockdev_del_drive(blkdev->blk);
blk_unref(blkdev->blk);
blkdev->blk = NULL;
}
@@ -102,7 +102,7 @@ static void release_drive(Object *obj, const char *name, void *opaque)
if (*ptr) {
blk_detach_dev(*ptr, dev);
- blockdev_auto_del(*ptr);
+ blockdev_del_drive(*ptr);
}
}
@@ -181,6 +181,9 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev)
if (ds) {
blk_detach_dev(blk, ds);
}
+ if (pci_ide->bus[di->bus].ifs[di->unit].blk) {
+ blockdev_del_drive(blk);
+ }
pci_ide->bus[di->bus].ifs[di->unit].blk = NULL;
if (!(i % 2)) {
idedev = pci_ide->bus[di->bus].master;
@@ -213,7 +213,9 @@ static void scsi_qdev_unrealize(DeviceState *qdev, Error **errp)
}
scsi_device_purge_requests(dev, SENSE_CODE(NO_SENSE));
- blockdev_mark_auto_del(dev->conf.blk);
+ blk_detach_dev(dev->conf.blk, qdev);
+ blockdev_del_drive(dev->conf.blk);
+ dev->conf.blk = NULL;
}
/* handle legacy '-drive if=scsi,...' cmd line args */
@@ -642,7 +642,8 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
* blockdev, or else scsi_bus_legacy_add_drive() dies when it
* attaches again.
*
- * The hack is probably a bad idea.
+ * The hack is probably a bad idea. Anyway, this is why this does not
+ * call blockdev_del_drive.
*/
blk_detach_dev(blk, &s->dev.qdev);
s->conf.blk = NULL;
@@ -14,8 +14,7 @@
#include "qapi/error.h"
#include "qemu/queue.h"
-void blockdev_mark_auto_del(BlockBackend *blk);
-void blockdev_auto_del(BlockBackend *blk);
+void blockdev_del_drive(BlockBackend *blk);
typedef enum {
IF_DEFAULT = -1, /* for use with drive_add() only */
@@ -34,7 +33,6 @@ struct DriveInfo {
BlockInterfaceType type;
int bus;
int unit;
- int auto_del; /* see blockdev_mark_auto_del() */
bool is_default; /* Added by default_drive() ? */
int media_cd;
int cyls, heads, secs, trans;
Instead of delaying blk_detach_dev and blockdev_auto_del until the object is finalized and properties are released, do that as soon as possible. This patch replaces blockdev_mark_auto_del calls with blk_detach_dev and blockdev_del_drive (the latter is a combination of the former blockdev_mark_auto_del and blockdev_auto_del). We cannot make blk_detach_dev do both tasks because of the USB mass storage hack. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- blockdev.c | 21 +++++---------------- hw/block/virtio-blk.c | 4 +++- hw/block/xen_disk.c | 1 + hw/core/qdev-properties-system.c | 2 +- hw/ide/piix.c | 3 +++ hw/scsi/scsi-bus.c | 4 +++- hw/usb/dev-storage.c | 3 ++- include/sysemu/blockdev.h | 4 +--- 8 files changed, 19 insertions(+), 23 deletions(-)