From patchwork Mon Feb 9 18:38:29 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 438031 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 6A33414014D for ; Tue, 10 Feb 2015 05:42:06 +1100 (AEDT) Received: from localhost ([::1]:34507 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YKtHY-0001e0-DT for incoming@patchwork.ozlabs.org; Mon, 09 Feb 2015 13:42:04 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56615) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YKtEX-00046x-Id for qemu-devel@nongnu.org; Mon, 09 Feb 2015 13:39:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YKtEV-0005SI-1X for qemu-devel@nongnu.org; Mon, 09 Feb 2015 13:38:57 -0500 Received: from mx1.redhat.com ([209.132.183.28]:45557) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YKtEU-0005Rv-OH for qemu-devel@nongnu.org; Mon, 09 Feb 2015 13:38:54 -0500 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t19IcsKZ026494 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Mon, 9 Feb 2015 13:38:54 -0500 Received: from localhost ([10.18.17.71]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t19Icr37029438 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Mon, 9 Feb 2015 13:38:53 -0500 From: Max Reitz To: qemu-devel@nongnu.org Date: Mon, 9 Feb 2015 13:38:29 -0500 Message-Id: <1423507124-29809-8-git-send-email-mreitz@redhat.com> In-Reply-To: <1423507124-29809-1-git-send-email-mreitz@redhat.com> References: <1423507124-29809-1-git-send-email-mreitz@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Kevin Wolf , Paolo Bonzini , Stefan Hajnoczi , Max Reitz Subject: [Qemu-devel] [PATCH v2 07/22] block: Add bdrv_close_all() handlers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- 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); }