When a scsi-cd is created without a backing drive (an empty CD-ROM),
scsi_cd_realize() allocates an anonymous BlockBackend for the empty
drive with blk_new() and attaches it to the device using
blk_attach_dev().

blk_new() returns the backend with refcnt == 1 (the creation reference
owned by the caller) and blk_attach_dev() takes an additional reference
for the device.  The creation reference was never released, so on
unplug blk_detach_dev() only drops the device's reference and the
BlockBackend is leaked.

Release the creation reference with blk_unref() right after
blk_attach_dev(), matching the idiom already used in set_drive_helper()
in hw/core/qdev-properties-system.c ("If we need to keep a reference,
blk_attach_dev() took it").

Signed-off-by: Mitsuru Kariya <[email protected]>
---
 hw/scsi/scsi-disk.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 5ba5b46c4f..d70af0d9b4 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2627,6 +2627,7 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
         dev->conf.blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
         ret = blk_attach_dev(dev->conf.blk, &dev->qdev);
         assert(ret == 0);
+        blk_unref(dev->conf.blk);
     }
 
     if (dev->conf.physical_block_size != 0) {
-- 
2.43.0


Reply via email to