summaryrefslogtreecommitdiff
path: root/hw/usb/dev-storage.c
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2016-06-21 20:46:05 +0200
committerKevin Wolf <kwolf@redhat.com>2016-07-13 13:28:00 +0200
commit8daea510951dd309a44cea8de415c685c43851cf (patch)
treeea98591f6d38d987d463f1a481f896d79b28a331 /hw/usb/dev-storage.c
parent0b8b8753e4d94901627b3e86431230f2319215c4 (diff)
downloadqemu-8daea510951dd309a44cea8de415c685c43851cf.tar.gz
block/qdev: Allow node name for drive properties
If a node name instead of a BlockBackend name is specified as the driver for a guest device, an anonymous BlockBackend is created now. The order of operations in release_drive() must be reversed in order to avoid a use-after-free bug because now blk_detach_dev() frees the last reference if an anonymous BlockBackend is used. usb-storage uses a hack where it forwards its BlockBackend as a property to another device that it internally creates. This hack must be updated so that it doesn't drop its original BB before it can be passed to the other device. This used to work because we always had the monitor reference around, but with node-names the device reference is the only one now. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com>
Diffstat (limited to 'hw/usb/dev-storage.c')
-rw-r--r--hw/usb/dev-storage.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index 4d605b8a6a..78038a2470 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -609,10 +609,12 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
* a SCSI bus that can serve only a single device, which it
* creates automatically. But first it needs to detach from its
* blockdev, or else scsi_bus_legacy_add_drive() dies when it
- * attaches again.
+ * attaches again. We also need to take another reference so that
+ * blk_detach_dev() doesn't free blk while we still need it.
*
* The hack is probably a bad idea.
*/
+ blk_ref(blk);
blk_detach_dev(blk, &s->dev.qdev);
s->conf.blk = NULL;
@@ -623,6 +625,7 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
scsi_dev = scsi_bus_legacy_add_drive(&s->bus, blk, 0, !!s->removable,
s->conf.bootindex, dev->serial,
&err);
+ blk_unref(blk);
if (!scsi_dev) {
error_propagate(errp, err);
return;