From patchwork Tue Sep 16 18:12:09 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 390141 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 1A61F140143 for ; Wed, 17 Sep 2014 04:18:14 +1000 (EST) Received: from localhost ([::1]:39999 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XTxKO-00041f-2q for incoming@patchwork.ozlabs.org; Tue, 16 Sep 2014 14:18:12 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52773) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XTxFA-0003W7-Fe for qemu-devel@nongnu.org; Tue, 16 Sep 2014 14:12:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XTxF1-0003EI-No for qemu-devel@nongnu.org; Tue, 16 Sep 2014 14:12:48 -0400 Received: from mx1.redhat.com ([209.132.183.28]:32853) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XTxF1-0003Cv-GG for qemu-devel@nongnu.org; Tue, 16 Sep 2014 14:12:39 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8GICWWN025219 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 16 Sep 2014 14:12:32 -0400 Received: from blackfin.pond.sub.org (ovpn-116-29.ams2.redhat.com [10.36.116.29]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8GICTxG015351 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Tue, 16 Sep 2014 14:12:31 -0400 Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id F1AF730428D8; Tue, 16 Sep 2014 20:12:28 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Tue, 16 Sep 2014 20:12:09 +0200 Message-Id: <1410891148-28849-5-git-send-email-armbru@redhat.com> In-Reply-To: <1410891148-28849-1-git-send-email-armbru@redhat.com> References: <1410891148-28849-1-git-send-email-armbru@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: kwolf@redhat.com, famz@redhat.com, benoit.canet@nodalink.com, stefanha@redhat.com, mreitz@redhat.com Subject: [Qemu-devel] [PATCH v3 04/23] block: Connect BlockBackend and DriveInfo 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 Make the BlockBackend own the DriveInfo. Change blockdev_init() to return the BlockBackend instead of the DriveInfo. Signed-off-by: Markus Armbruster --- block.c | 2 -- block/block-backend.c | 38 ++++++++++++++++++++++++ blockdev.c | 73 ++++++++++++++++++++++++----------------------- include/sysemu/blockdev.h | 4 +++ 4 files changed, 79 insertions(+), 38 deletions(-) diff --git a/block.c b/block.c index 7ccf443..5f7dc45 100644 --- a/block.c +++ b/block.c @@ -29,7 +29,6 @@ #include "qemu/module.h" #include "qapi/qmp/qjson.h" #include "sysemu/sysemu.h" -#include "sysemu/blockdev.h" /* FIXME layering violation */ #include "qemu/notify.h" #include "block/coroutine.h" #include "block/qapi.h" @@ -2124,7 +2123,6 @@ static void bdrv_delete(BlockDriverState *bs) /* remove from list, if necessary */ bdrv_make_anon(bs); - drive_info_del(drive_get_by_blockdev(bs)); g_free(bs); } diff --git a/block/block-backend.c b/block/block-backend.c index a12215a..9ee57c7 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -12,11 +12,13 @@ #include "sysemu/block-backend.h" #include "block/block_int.h" +#include "sysemu/blockdev.h" struct BlockBackend { char *name; int refcnt; BlockDriverState *bs; + DriveInfo *legacy_dinfo; QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */ }; @@ -87,6 +89,7 @@ static void blk_delete(BlockBackend *blk) QTAILQ_REMOVE(&blk_backends, blk, link); } g_free(blk->name); + drive_info_del(blk->legacy_dinfo); g_free(blk); } @@ -167,6 +170,41 @@ BlockDriverState *blk_bs(BlockBackend *blk) } /* + * Return @blk's DriveInfo if any, else null. + */ +DriveInfo *blk_legacy_dinfo(BlockBackend *blk) +{ + return blk->legacy_dinfo; +} + +/* + * Set @blk's DriveInfo to @dinfo, and return it. + * @blk must not have a DriveInfo set already. + * No other BlockBackend may have the same DriveInfo set. + */ +DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo) +{ + assert(!blk->legacy_dinfo); + return blk->legacy_dinfo = dinfo; +} + +/* + * Return the BlockBackend with DriveInfo @dinfo. + * It must exist. + */ +BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo) +{ + BlockBackend *blk; + + QTAILQ_FOREACH(blk, &blk_backends, link) { + if (blk->legacy_dinfo == dinfo) { + return blk; + } + } + assert(0); +} + +/* * Hide @blk. * @blk must not have been hidden already. * Make attached BlockDriverState, if any, anonymous. diff --git a/blockdev.c b/blockdev.c index 5da6028..722d083 100644 --- a/blockdev.c +++ b/blockdev.c @@ -47,8 +47,6 @@ #include "trace.h" #include "sysemu/arch_init.h" -static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives); - static const char *const if_name[IF_COUNT] = { [IF_NONE] = "none", [IF_IDE] = "ide", @@ -89,7 +87,8 @@ static const int if_max_devs[IF_COUNT] = { */ void blockdev_mark_auto_del(BlockDriverState *bs) { - DriveInfo *dinfo = drive_get_by_blockdev(bs); + BlockBackend *blk = bs->blk; + DriveInfo *dinfo = blk_legacy_dinfo(blk); if (dinfo && !dinfo->enable_auto_del) { return; @@ -105,7 +104,8 @@ void blockdev_mark_auto_del(BlockDriverState *bs) void blockdev_auto_del(BlockDriverState *bs) { - DriveInfo *dinfo = drive_get_by_blockdev(bs); + BlockBackend *blk = bs->blk; + DriveInfo *dinfo = blk_legacy_dinfo(blk); if (dinfo && dinfo->auto_del) { drive_del(dinfo); @@ -153,15 +153,15 @@ QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file, DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit) { + BlockBackend *blk; DriveInfo *dinfo; - /* seek interface, bus and unit */ - - QTAILQ_FOREACH(dinfo, &drives, next) { - if (dinfo->type == type && - dinfo->bus == bus && - dinfo->unit == unit) + for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { + dinfo = blk_legacy_dinfo(blk); + if (dinfo && dinfo->type == type + && dinfo->bus == bus && dinfo->unit == unit) { return dinfo; + } } return NULL; @@ -177,13 +177,15 @@ DriveInfo *drive_get_by_index(BlockInterfaceType type, int index) int drive_get_max_bus(BlockInterfaceType type) { int max_bus; + BlockBackend *blk; DriveInfo *dinfo; max_bus = -1; - QTAILQ_FOREACH(dinfo, &drives, next) { - if(dinfo->type == type && - dinfo->bus > max_bus) + for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { + dinfo = blk_legacy_dinfo(blk); + if (dinfo && dinfo->type == type && dinfo->bus > max_bus) { max_bus = dinfo->bus; + } } return max_bus; } @@ -200,11 +202,11 @@ DriveInfo *drive_get_next(BlockInterfaceType type) DriveInfo *drive_get_by_blockdev(BlockDriverState *bs) { - DriveInfo *dinfo; + BlockBackend *blk; - QTAILQ_FOREACH(dinfo, &drives, next) { - if (dinfo->bdrv == bs) { - return dinfo; + for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { + if (blk_bs(blk) == bs) { + return blk_legacy_dinfo(blk); } } return NULL; @@ -218,6 +220,7 @@ static void bdrv_format_print(void *opaque, const char *name) void drive_del(DriveInfo *dinfo) { bdrv_unref(dinfo->bdrv); + blk_unref(blk_by_legacy_dinfo(dinfo)); } void drive_info_del(DriveInfo *dinfo) @@ -228,9 +231,7 @@ void drive_info_del(DriveInfo *dinfo) if (dinfo->opts) { qemu_opts_del(dinfo->opts); } - g_free(dinfo->id); - QTAILQ_REMOVE(&drives, dinfo, next); g_free(dinfo->serial); g_free(dinfo); } @@ -302,8 +303,8 @@ static bool check_throttle_config(ThrottleConfig *cfg, Error **errp) typedef enum { MEDIA_DISK, MEDIA_CDROM } DriveMediaType; /* Takes the ownership of bs_opts */ -static DriveInfo *blockdev_init(const char *file, QDict *bs_opts, - Error **errp) +static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, + Error **errp) { const char *buf; int ro = 0; @@ -486,7 +487,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts, dinfo = g_malloc0(sizeof(*dinfo)); dinfo->id = g_strdup(qemu_opts_id(opts)); dinfo->bdrv = bs; - QTAILQ_INSERT_TAIL(&drives, dinfo, next); + blk_set_legacy_dinfo(blk, dinfo); if (!file || !*file) { if (has_driver_specific_opts) { @@ -494,7 +495,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts, } else { QDECREF(bs_opts); qemu_opts_del(opts); - return dinfo; + return blk; } } if (snapshot) { @@ -531,7 +532,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts, QDECREF(bs_opts); qemu_opts_del(opts); - return dinfo; + return blk; err: bdrv_unref(bs); @@ -638,6 +639,7 @@ QemuOptsList qemu_legacy_drive_opts = { DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type) { const char *value; + BlockBackend *blk; DriveInfo *dinfo = NULL; QDict *bs_opts; QemuOpts *legacy_opts; @@ -920,19 +922,18 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type) } /* Actual block device init: Functionality shared with blockdev-add */ - dinfo = blockdev_init(filename, bs_opts, &local_err); + blk = blockdev_init(filename, bs_opts, &local_err); bs_opts = NULL; - if (dinfo == NULL) { - if (local_err) { - error_report("%s", error_get_pretty(local_err)); - error_free(local_err); - } + if (!blk) { + error_report("%s", error_get_pretty(local_err)); + error_free(local_err); goto fail; } else { assert(!local_err); } /* Set legacy DriveInfo fields */ + dinfo = blk_legacy_dinfo(blk); dinfo->enable_auto_del = true; dinfo->opts = all_opts; @@ -1762,7 +1763,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data) } bs = blk_bs(blk); - dinfo = drive_get_by_blockdev(bs); + dinfo = blk_legacy_dinfo(blk); if (dinfo && !dinfo->enable_auto_del) { error_report("Deleting device added with blockdev-add" " is not supported"); @@ -1797,7 +1798,6 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data) /* FIXME bs->blk leaked when bs dies */ } else { drive_del(dinfo); - blk_unref(blk); } aio_context_release(aio_context); @@ -2489,7 +2489,7 @@ void qmp_change_backing_file(const char *device, void qmp_blockdev_add(BlockdevOptions *options, Error **errp) { QmpOutputVisitor *ov = qmp_output_visitor_new(); - DriveInfo *dinfo; + BlockBackend *blk; QObject *obj; QDict *qdict; Error *local_err = NULL; @@ -2527,14 +2527,15 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp) qdict_flatten(qdict); - dinfo = blockdev_init(NULL, qdict, &local_err); + blk = blockdev_init(NULL, qdict, &local_err); if (local_err) { error_propagate(errp, local_err); goto fail; } - if (bdrv_key_required(dinfo->bdrv)) { - drive_del(dinfo); + if (bdrv_key_required(blk_bs(blk))) { + bdrv_unref(blk_bs(blk)); + blk_unref(blk); error_setg(errp, "blockdev-add doesn't support encrypted devices"); goto fail; } diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h index abec381..1dc5906 100644 --- a/include/sysemu/blockdev.h +++ b/include/sysemu/blockdev.h @@ -45,6 +45,10 @@ struct DriveInfo { QTAILQ_ENTRY(DriveInfo) next; }; +DriveInfo *blk_legacy_dinfo(BlockBackend *blk); +DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo); +BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo); + DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit); DriveInfo *drive_get_by_index(BlockInterfaceType type, int index); int drive_get_max_bus(BlockInterfaceType type);