[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 1/2] block: detach devices from DriveInfo at unreali
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PATCH 1/2] block: detach devices from DriveInfo at unrealize time |
Date: |
Fri, 8 Jan 2016 18:37:44 +0100 |
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 <address@hidden>
---
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(-)
diff --git a/blockdev.c b/blockdev.c
index 917ae06..a8309fb 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -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);
}
}
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 848f3fe..6e51246 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -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);
}
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 02eda6e..a6a0b7c 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -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;
}
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 921e799..cf147f4 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -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);
}
}
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 5a26c86..2b2d043 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -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;
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index fd1171e..a805fad 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -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 */
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index 597d8fd..f191011 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -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;
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index b06a060..ae7ad67 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -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;
--
2.5.0