qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v2 07/22] block: Add bdrv_close_all() handlers


From: Max Reitz
Subject: [Qemu-devel] [PATCH v2 07/22] block: Add bdrv_close_all() handlers
Date: Mon, 9 Feb 2015 13:38:29 -0500

Every time a reference to a BlockBackend is taken, a notifier for
bdrv_close_all() has to be deposited so the reference holder can
relinquish its reference when bdrv_close_all() is called. That notifier
should be revoked on a bdrv_unref() call.

Add a Notifier * parameter to all the functions changing the reference
count of a BlockBackend: blk_new(), blk_new_with_bs(), blk_new_open(),
blk_ref() and blk_unref().

By dropping the manual reference handling in hw/block/xen_disk.c, the
blk_unref() in hw/ide/piix.c can be dropped as well.

Signed-off-by: Max Reitz <address@hidden>
---
 block/block-backend.c          | 69 ++++++++++++++++++++++++++++++++++++------
 blockdev.c                     | 62 ++++++++++++++++++++++++++++++++++---
 device-hotplug.c               |  2 +-
 hw/block/xen_disk.c            | 16 +++++++---
 hw/ide/piix.c                  |  1 -
 include/sysemu/block-backend.h | 13 +++++---
 include/sysemu/blockdev.h      |  3 ++
 nbd.c                          | 26 ++++++++++++++--
 qemu-img.c                     | 39 ++++++++++++------------
 qemu-io.c                      |  6 ++--
 qemu-nbd.c                     |  6 ++--
 11 files changed, 189 insertions(+), 54 deletions(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index 6d02184..98f4af9 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -76,7 +76,8 @@ static QTAILQ_HEAD(, BlockBackend) blk_backends =
  * Store an error through @errp on failure, unless it's null.
  * Return the new BlockBackend on success, null on failure.
  */
-BlockBackend *blk_new(const char *name, Error **errp)
+BlockBackend *blk_new(const char *name, Notifier *close_all_notifier,
+                      Error **errp)
 {
     BlockBackend *blk;
 
@@ -100,6 +101,9 @@ BlockBackend *blk_new(const char *name, Error **errp)
     blk->name = g_strdup(name);
     blk->refcnt = 1;
     notifier_list_init(&blk->remove_bs_notifiers);
+    if (close_all_notifier) {
+        bdrv_add_close_all_notifier(close_all_notifier);
+    }
     QTAILQ_INSERT_TAIL(&blk_backends, blk, link);
     return blk;
 }
@@ -108,12 +112,13 @@ BlockBackend *blk_new(const char *name, Error **errp)
  * Create a new BlockBackend with a new BlockDriverState attached.
  * Otherwise just like blk_new(), which see.
  */
-BlockBackend *blk_new_with_bs(const char *name, Error **errp)
+BlockBackend *blk_new_with_bs(const char *name, Notifier *close_all_notifier,
+                              Error **errp)
 {
     BlockBackend *blk;
     BlockDriverState *bs;
 
-    blk = blk_new(name, errp);
+    blk = blk_new(name, close_all_notifier, errp);
     if (!blk) {
         return NULL;
     }
@@ -138,12 +143,12 @@ BlockBackend *blk_new_with_bs(const char *name, Error 
**errp)
  */
 BlockBackend *blk_new_open(const char *name, const char *filename,
                            const char *reference, QDict *options, int flags,
-                           Error **errp)
+                           Notifier *close_all_notifier, Error **errp)
 {
     BlockBackend *blk;
     int ret;
 
-    blk = blk_new_with_bs(name, errp);
+    blk = blk_new_with_bs(name, close_all_notifier, errp);
     if (!blk) {
         QDECREF(options);
         return NULL;
@@ -151,7 +156,7 @@ BlockBackend *blk_new_open(const char *name, const char 
*filename,
 
     ret = bdrv_open(&blk->bs, filename, reference, options, flags, NULL, errp);
     if (ret < 0) {
-        blk_unref(blk);
+        blk_unref(blk, close_all_notifier);
         return NULL;
     }
 
@@ -191,9 +196,13 @@ static void drive_info_del(DriveInfo *dinfo)
  * Increment @blk's reference count.
  * @blk must not be null.
  */
-void blk_ref(BlockBackend *blk)
+void blk_ref(BlockBackend *blk, Notifier *close_all_notifier)
 {
     blk->refcnt++;
+
+    if (close_all_notifier) {
+        bdrv_add_close_all_notifier(close_all_notifier);
+    }
 }
 
 /*
@@ -201,8 +210,12 @@ void blk_ref(BlockBackend *blk)
  * If this drops it to zero, destroy @blk.
  * For convenience, do nothing if @blk is null.
  */
-void blk_unref(BlockBackend *blk)
+void blk_unref(BlockBackend *blk, Notifier *close_all_notifier)
 {
+    if (close_all_notifier) {
+        notifier_remove(close_all_notifier);
+    }
+
     if (blk) {
         assert(blk->refcnt > 0);
         if (!--blk->refcnt) {
@@ -352,6 +365,21 @@ void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs)
     bs->blk = blk;
 }
 
+typedef struct DevCloseAllNotifier {
+    Notifier n;
+    BlockBackend *blk;
+    QTAILQ_ENTRY(DevCloseAllNotifier) next;
+} DevCloseAllNotifier;
+
+static QTAILQ_HEAD(, DevCloseAllNotifier) close_all_notifiers =
+    QTAILQ_HEAD_INITIALIZER(close_all_notifiers);
+
+static void dev_close_all_notifier(Notifier *n, void *data)
+{
+    DevCloseAllNotifier *can = DO_UPCAST(DevCloseAllNotifier, n, n);
+    blk_detach_dev(can->blk, can->blk->dev);
+}
+
 /*
  * Attach device model @dev to @blk.
  * Return 0 on success, -EBUSY when a device model is attached already.
@@ -359,10 +387,19 @@ void blk_insert_bs(BlockBackend *blk, BlockDriverState 
*bs)
 int blk_attach_dev(BlockBackend *blk, void *dev)
 /* TODO change to DeviceState *dev when all users are qdevified */
 {
+    DevCloseAllNotifier *can;
+
     if (blk->dev) {
         return -EBUSY;
     }
-    blk_ref(blk);
+
+    can = g_new0(DevCloseAllNotifier, 1);
+    can->n.notify = dev_close_all_notifier;
+    can->blk = blk;
+
+    QTAILQ_INSERT_TAIL(&close_all_notifiers, can, next);
+
+    blk_ref(blk, &can->n);
     blk->dev = dev;
     blk_iostatus_reset(blk);
     return 0;
@@ -387,12 +424,24 @@ void blk_attach_dev_nofail(BlockBackend *blk, void *dev)
 void blk_detach_dev(BlockBackend *blk, void *dev)
 /* TODO change to DeviceState *dev when all users are qdevified */
 {
+    DevCloseAllNotifier *can;
+
     assert(blk->dev == dev);
     blk->dev = NULL;
     blk->dev_ops = NULL;
     blk->dev_opaque = NULL;
     blk->guest_block_size = 512;
-    blk_unref(blk);
+
+    QTAILQ_FOREACH(can, &close_all_notifiers, next) {
+        if (can->blk == blk) {
+            break;
+        }
+    }
+    assert(can);
+
+    blk_unref(blk, &can->n);
+    QTAILQ_REMOVE(&close_all_notifiers, can, next);
+    g_free(can);
 }
 
 /*
diff --git a/blockdev.c b/blockdev.c
index f198be6..75baf16 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -47,6 +47,15 @@
 #include "trace.h"
 #include "sysemu/arch_init.h"
 
+typedef struct BlockdevCloseAllNotifier {
+    Notifier n;
+    BlockBackend *blk;
+    QTAILQ_ENTRY(BlockdevCloseAllNotifier) next;
+} BlockdevCloseAllNotifier;
+
+static QTAILQ_HEAD(, BlockdevCloseAllNotifier) close_all_notifiers =
+    QTAILQ_HEAD_INITIALIZER(close_all_notifiers);
+
 static const char *const if_name[IF_COUNT] = {
     [IF_NONE] = "none",
     [IF_IDE] = "ide",
@@ -78,6 +87,37 @@ static int if_max_devs[IF_COUNT] = {
     [IF_SCSI] = 7,
 };
 
+static void monitor_blk_unref_with_can(BlockBackend *blk,
+                                       BlockdevCloseAllNotifier *can)
+{
+    if (can) {
+        assert(can->blk == blk);
+    } else {
+        QTAILQ_FOREACH(can, &close_all_notifiers, next) {
+            if (can->blk == blk) {
+                break;
+            }
+        }
+        assert(can);
+    }
+
+    blk_unref(blk, &can->n);
+    QTAILQ_REMOVE(&close_all_notifiers, can, next);
+    g_free(can);
+}
+
+void monitor_blk_unref(BlockBackend *blk)
+{
+    monitor_blk_unref_with_can(blk, NULL);
+}
+
+static void blockdev_close_all_notifier(Notifier *n, void *data)
+{
+    BlockdevCloseAllNotifier *can = DO_UPCAST(BlockdevCloseAllNotifier, n, n);
+
+    monitor_blk_unref_with_can(can->blk, can);
+}
+
 /**
  * Boards may call this to offer board-by-board overrides
  * of the default, global values.
@@ -140,7 +180,7 @@ void blockdev_auto_del(BlockBackend *blk)
     DriveInfo *dinfo = blk_legacy_dinfo(blk);
 
     if (dinfo && dinfo->auto_del) {
-        blk_unref(blk);
+        monitor_blk_unref(blk);
     }
 }
 
@@ -460,6 +500,7 @@ static BlockBackend *blockdev_init(const char *file, QDict 
*bs_opts,
     bool has_driver_specific_opts;
     BlockdevDetectZeroesOptions detect_zeroes =
         BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF;
+    BlockdevCloseAllNotifier *can;
 
     /* Check common options by copying from bs_opts to opts, all other options
      * stay in bs_opts for processing by bdrv_open(). */
@@ -536,14 +577,21 @@ static BlockBackend *blockdev_init(const char *file, 
QDict *bs_opts,
     }
 
     /* init */
+    can = g_new0(BlockdevCloseAllNotifier, 1);
+    can->n.notify = blockdev_close_all_notifier;
+
     if ((!file || !*file) && !has_driver_specific_opts) {
         BlockBackendRootState *blk_rs;
 
-        blk = blk_new(qemu_opts_id(opts), errp);
+        blk = blk_new(qemu_opts_id(opts), &can->n, errp);
         if (!blk) {
+            g_free(can);
             goto early_err;
         }
 
+        can->blk = blk;
+        QTAILQ_INSERT_TAIL(&close_all_notifiers, can, next);
+
         blk_rs = blk_get_root_state(blk);
         blk_rs->open_flags    = bdrv_flags;
         blk_rs->read_only     = !(bdrv_flags & BDRV_O_RDWR);
@@ -561,12 +609,16 @@ static BlockBackend *blockdev_init(const char *file, 
QDict *bs_opts,
         }
 
         blk = blk_new_open(qemu_opts_id(opts), file, NULL, bs_opts, bdrv_flags,
-                           errp);
+                           &can->n, errp);
         if (!blk) {
+            g_free(can);
             goto err_no_bs_opts;
         }
         bs = blk_bs(blk);
 
+        can->blk = blk;
+        QTAILQ_INSERT_TAIL(&close_all_notifiers, can, next);
+
         bs->detect_zeroes = detect_zeroes;
 
         /* disk I/O throttling */
@@ -2246,7 +2298,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, 
QObject **ret_data)
         blk_set_on_error(blk, BLOCKDEV_ON_ERROR_REPORT,
                          BLOCKDEV_ON_ERROR_REPORT);
     } else {
-        blk_unref(blk);
+        monitor_blk_unref(blk);
     }
 
     aio_context_release(aio_context);
@@ -3174,7 +3226,7 @@ void qmp_blockdev_add(BlockdevOptions *options, Error 
**errp)
 
     if (bs && bdrv_key_required(bs)) {
         if (blk) {
-            blk_unref(blk);
+            monitor_blk_unref(blk);
         } else {
             bdrv_unref(bs);
         }
diff --git a/device-hotplug.c b/device-hotplug.c
index 9e38cc4..aa05a71 100644
--- a/device-hotplug.c
+++ b/device-hotplug.c
@@ -77,6 +77,6 @@ void drive_hot_add(Monitor *mon, const QDict *qdict)
 
 err:
     if (dinfo) {
-        blk_unref(blk_by_legacy_dinfo(dinfo));
+        monitor_blk_unref(blk_by_legacy_dinfo(dinfo));
     }
 }
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 2f59b5b..4916ddf 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -908,8 +908,10 @@ static int blk_connect(struct XenDevice *xendev)
 
         /* setup via xenbus -> create new block driver instance */
         xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
+        /* No need to give a close_all_notifier because blk_attach_dev_nofail()
+         * and blk_detach_dev() will keep track of our reference */
         blkdev->blk = blk_new_open(blkdev->dev, blkdev->filename, NULL, 
options,
-                                   qflags, &local_err);
+                                   qflags, NULL, &local_err);
         if (!blkdev->blk) {
             xen_be_printf(&blkdev->xendev, 0, "error: %s\n",
                           error_get_pretty(local_err));
@@ -925,11 +927,16 @@ static int blk_connect(struct XenDevice *xendev)
             blkdev->blk = NULL;
             return -1;
         }
-        /* blkdev->blk is not create by us, we get a reference
-         * so we can blk_unref() unconditionally */
-        blk_ref(blkdev->blk);
     }
+
     blk_attach_dev_nofail(blkdev->blk, blkdev);
+    if (!blkdev->dinfo) {
+        /* blkdev->blk has just been created; blk_attach_dev_nofail() counts
+         * the reference blkdev->blk, so we do not have to keep track (which
+         * allows us to ignore bdrv_close_all()) */
+        blk_unref(blkdev->blk, NULL);
+    }
+
     blkdev->file_size = blk_getlength(blkdev->blk);
     if (blkdev->file_size < 0) {
         BlockDriverState *bs = blk_bs(blkdev->blk);
@@ -1032,7 +1039,6 @@ static void blk_disconnect(struct XenDevice *xendev)
 
     if (blkdev->blk) {
         blk_detach_dev(blkdev->blk, blkdev);
-        blk_unref(blkdev->blk);
         blkdev->blk = NULL;
     }
     xen_be_unbind_evtchn(&blkdev->xendev);
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index b0172fb..becf0f5 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -184,7 +184,6 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev)
                 blk_detach_dev(blk, ds);
             }
             pci_ide->bus[di->bus].ifs[di->unit].blk = NULL;
-            blk_unref(blk);
         }
     }
     qdev_reset_all(DEVICE(dev));
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index dc1e217..9840fef 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -13,6 +13,7 @@
 #ifndef BLOCK_BACKEND_H
 #define BLOCK_BACKEND_H
 
+#include "qemu/notify.h"
 #include "qemu/typedefs.h"
 #include "qapi/error.h"
 
@@ -60,13 +61,15 @@ typedef struct BlockDevOps {
     void (*resize_cb)(void *opaque);
 } BlockDevOps;
 
-BlockBackend *blk_new(const char *name, Error **errp);
-BlockBackend *blk_new_with_bs(const char *name, Error **errp);
+BlockBackend *blk_new(const char *name, Notifier *close_all_notifier,
+                      Error **errp);
+BlockBackend *blk_new_with_bs(const char *name, Notifier *close_all_notifier,
+                              Error **errp);
 BlockBackend *blk_new_open(const char *name, const char *filename,
                            const char *reference, QDict *options, int flags,
-                           Error **errp);
-void blk_ref(BlockBackend *blk);
-void blk_unref(BlockBackend *blk);
+                           Notifier *close_all_notifier, Error **errp);
+void blk_ref(BlockBackend *blk, Notifier *close_all_notifier);
+void blk_unref(BlockBackend *blk, Notifier *close_all_notifier);
 const char *blk_name(BlockBackend *blk);
 BlockBackend *blk_by_name(const char *name);
 BlockBackend *blk_next(BlockBackend *blk);
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index 2a34332..b6091e0 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -67,4 +67,7 @@ DriveInfo *add_init_drive(const char *opts);
 
 void do_commit(Monitor *mon, const QDict *qdict);
 int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
+
+void monitor_blk_unref(BlockBackend *blk);
+
 #endif
diff --git a/nbd.c b/nbd.c
index 02ee686..9c44c0f 100644
--- a/nbd.c
+++ b/nbd.c
@@ -973,6 +973,9 @@ typedef struct NBDCloseNotifier {
 static QTAILQ_HEAD(, NBDCloseNotifier) eject_notifiers =
     QTAILQ_HEAD_INITIALIZER(eject_notifiers);
 
+static QTAILQ_HEAD(, NBDCloseNotifier) close_notifiers =
+    QTAILQ_HEAD_INITIALIZER(close_notifiers);
+
 static void nbd_close_notifier(Notifier *n, void *data)
 {
     NBDCloseNotifier *cn = DO_UPCAST(NBDCloseNotifier, n, n);
@@ -983,6 +986,7 @@ NBDExport *nbd_export_new(BlockBackend *blk, off_t 
dev_offset, off_t size,
                           uint32_t nbdflags, void (*close)(NBDExport *))
 {
     NBDCloseNotifier *eject_notifier = g_new0(NBDCloseNotifier, 1);
+    NBDCloseNotifier *close_notifier = g_new0(NBDCloseNotifier, 1);
     NBDExport *exp = g_malloc0(sizeof(NBDExport));
     exp->refcount = 1;
     QTAILQ_INIT(&exp->clients);
@@ -992,7 +996,12 @@ NBDExport *nbd_export_new(BlockBackend *blk, off_t 
dev_offset, off_t size,
     exp->size = size == -1 ? blk_getlength(blk) : size;
     exp->close = close;
     exp->ctx = blk_get_aio_context(blk);
-    blk_ref(blk);
+
+    close_notifier->n.notify = nbd_close_notifier;
+    close_notifier->exp = exp;
+    QTAILQ_INSERT_TAIL(&close_notifiers, close_notifier, next);
+
+    blk_ref(blk, &close_notifier->n);
     blk_add_aio_context_notifier(blk, blk_aio_attached, blk_aio_detach, exp);
 
     eject_notifier->n.notify = nbd_close_notifier;
@@ -1045,7 +1054,7 @@ void nbd_export_set_name(NBDExport *exp, const char *name)
 
 void nbd_export_close(NBDExport *exp)
 {
-    NBDCloseNotifier *eject_notifier;
+    NBDCloseNotifier *eject_notifier, *close_notifier;
     NBDClient *client, *next;
 
     nbd_export_get(exp);
@@ -1054,6 +1063,7 @@ void nbd_export_close(NBDExport *exp)
     }
     nbd_export_set_name(exp, NULL);
     nbd_export_put(exp);
+
     if (exp->blk) {
         QTAILQ_FOREACH(eject_notifier, &eject_notifiers, next) {
             if (eject_notifier->exp == exp) {
@@ -1066,10 +1076,20 @@ void nbd_export_close(NBDExport *exp)
         QTAILQ_REMOVE(&eject_notifiers, eject_notifier, next);
         g_free(eject_notifier);
 
+        QTAILQ_FOREACH(close_notifier, &close_notifiers, next) {
+            if (close_notifier->exp == exp) {
+                break;
+            }
+        }
+        assert(close_notifier);
+
         blk_remove_aio_context_notifier(exp->blk, blk_aio_attached,
                                         blk_aio_detach, exp);
-        blk_unref(exp->blk);
+        blk_unref(exp->blk, &close_notifier->n);
         exp->blk = NULL;
+
+        QTAILQ_REMOVE(&close_notifiers, close_notifier, next);
+        g_free(close_notifier);
     }
 }
 
diff --git a/qemu-img.c b/qemu-img.c
index 77fd4e4..56a528e 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -302,7 +302,7 @@ static BlockBackend *img_open(const char *id, const char 
*filename,
         qdict_put(options, "driver", qstring_from_str(fmt));
     }
 
-    blk = blk_new_open(id, filename, NULL, options, flags, &local_err);
+    blk = blk_new_open(id, filename, NULL, options, flags, NULL, &local_err);
     if (!blk) {
         error_report("Could not open '%s': %s", filename,
                      error_get_pretty(local_err));
@@ -324,7 +324,7 @@ static BlockBackend *img_open(const char *id, const char 
*filename,
     }
     return blk;
 fail:
-    blk_unref(blk);
+    blk_unref(blk, NULL);
     return NULL;
 }
 
@@ -713,7 +713,7 @@ static int img_check(int argc, char **argv)
 
 fail:
     qapi_free_ImageCheck(check);
-    blk_unref(blk);
+    blk_unref(blk, NULL);
     return ret;
 }
 
@@ -880,7 +880,7 @@ unref_backing:
 done:
     qemu_progress_end();
 
-    blk_unref(blk);
+    blk_unref(blk, NULL);
 
     if (local_err) {
         qerror_report_err(local_err);
@@ -1292,9 +1292,9 @@ static int img_compare(int argc, char **argv)
 out:
     qemu_vfree(buf1);
     qemu_vfree(buf2);
-    blk_unref(blk2);
+    blk_unref(blk2, NULL);
 out2:
-    blk_unref(blk1);
+    blk_unref(blk1, NULL);
 out3:
     qemu_progress_end();
     return ret;
@@ -1862,11 +1862,11 @@ out:
     qemu_opts_free(create_opts);
     qemu_vfree(buf);
     qemu_opts_del(sn_opts);
-    blk_unref(out_blk);
+    blk_unref(out_blk, NULL);
     g_free(bs);
     if (blk) {
         for (bs_i = 0; bs_i < bs_n; bs_i++) {
-            blk_unref(blk[bs_i]);
+            blk_unref(blk[bs_i], NULL);
         }
         g_free(blk);
     }
@@ -2001,7 +2001,7 @@ static ImageInfoList *collect_image_info_list(const char 
*filename,
         if (err) {
             error_report("%s", error_get_pretty(err));
             error_free(err);
-            blk_unref(blk);
+            blk_unref(blk, NULL);
             goto err;
         }
 
@@ -2010,7 +2010,7 @@ static ImageInfoList *collect_image_info_list(const char 
*filename,
         *last = elem;
         last = &elem->next;
 
-        blk_unref(blk);
+        blk_unref(blk, NULL);
 
         filename = fmt = NULL;
         if (chain) {
@@ -2298,7 +2298,7 @@ static int img_map(int argc, char **argv)
     dump_map_entry(output_format, &curr, NULL);
 
 out:
-    blk_unref(blk);
+    blk_unref(blk, NULL);
     return ret < 0;
 }
 
@@ -2422,7 +2422,7 @@ static int img_snapshot(int argc, char **argv)
     }
 
     /* Cleanup */
-    blk_unref(blk);
+    blk_unref(blk, NULL);
     if (ret) {
         return 1;
     }
@@ -2546,7 +2546,7 @@ static int img_rebase(int argc, char **argv)
 
         bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
         blk_old_backing = blk_new_open("old_backing", backing_name, NULL,
-                                       options, src_flags, &local_err);
+                                       options, src_flags, NULL, &local_err);
         if (!blk_old_backing) {
             error_report("Could not open old backing file '%s': %s",
                          backing_name, error_get_pretty(local_err));
@@ -2563,7 +2563,8 @@ static int img_rebase(int argc, char **argv)
             }
 
             blk_new_backing = blk_new_open("new_backing", out_baseimg, NULL,
-                                           options, src_flags, &local_err);
+                                           options, src_flags, NULL,
+                                           &local_err);
             if (!blk_new_backing) {
                 error_report("Could not open new backing file '%s': %s",
                              out_baseimg, error_get_pretty(local_err));
@@ -2736,11 +2737,11 @@ out:
     qemu_progress_end();
     /* Cleanup */
     if (!unsafe) {
-        blk_unref(blk_old_backing);
-        blk_unref(blk_new_backing);
+        blk_unref(blk_old_backing, NULL);
+        blk_unref(blk_new_backing, NULL);
     }
 
-    blk_unref(blk);
+    blk_unref(blk, NULL);
     if (ret) {
         return 1;
     }
@@ -2863,7 +2864,7 @@ static int img_resize(int argc, char **argv)
         break;
     }
 out:
-    blk_unref(blk);
+    blk_unref(blk, NULL);
     if (ret) {
         return 1;
     }
@@ -3001,7 +3002,7 @@ static int img_amend(int argc, char **argv)
 out:
     qemu_progress_end();
 
-    blk_unref(blk);
+    blk_unref(blk, NULL);
     qemu_opts_del(opts);
     qemu_opts_free(create_opts);
     g_free(options);
diff --git a/qemu-io.c b/qemu-io.c
index 4a3e719..9c0ad37 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -37,7 +37,7 @@ static ReadLineState *readline_state;
 
 static int close_f(BlockBackend *blk, int argc, char **argv)
 {
-    blk_unref(qemuio_blk);
+    blk_unref(qemuio_blk, NULL);
     qemuio_blk = NULL;
     return 0;
 }
@@ -59,7 +59,7 @@ static int openfile(char *name, int flags, QDict *opts)
         return 1;
     }
 
-    qemuio_blk = blk_new_open("hda", name, NULL, opts, flags, &local_err);
+    qemuio_blk = blk_new_open("hda", name, NULL, opts, flags, NULL, 
&local_err);
     if (!qemuio_blk) {
         fprintf(stderr, "%s: can't open%s%s: %s\n", progname,
                 name ? " device " : "", name ?: "",
@@ -474,7 +474,7 @@ int main(int argc, char **argv)
      */
     bdrv_drain_all();
 
-    blk_unref(qemuio_blk);
+    blk_unref(qemuio_blk, NULL);
     g_free(readline_state);
     return 0;
 }
diff --git a/qemu-nbd.c b/qemu-nbd.c
index ac1e5d6..5e6e4b4 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -694,7 +694,8 @@ int main(int argc, char **argv)
     }
 
     srcpath = argv[optind];
-    blk = blk_new_open("hda", srcpath, NULL, options, flags, &local_err);
+    /* the reference will be passed on nbd_export_new() */
+    blk = blk_new_open("hda", srcpath, NULL, options, flags, NULL, &local_err);
     if (!blk) {
         errx(EXIT_FAILURE, "Failed to blk_new_open '%s': %s", argv[optind],
              error_get_pretty(local_err));
@@ -728,7 +729,9 @@ int main(int argc, char **argv)
         }
     }
 
+    /* nbd_export_new() takes the reference to blk */
     exp = nbd_export_new(blk, dev_offset, fd_size, nbdflags, 
nbd_export_closed);
+    blk_unref(blk, NULL);
 
     if (sockpath) {
         fd = unix_socket_incoming(sockpath);
@@ -773,7 +776,6 @@ int main(int argc, char **argv)
         }
     } while (state != TERMINATED);
 
-    blk_unref(blk);
     if (sockpath) {
         unlink(sockpath);
     }
-- 
2.1.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]