From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56730) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YKtEe-0004IJ-Em for qemu-devel@nongnu.org; Mon, 09 Feb 2015 13:39:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YKtEd-0005b3-EH for qemu-devel@nongnu.org; Mon, 09 Feb 2015 13:39:04 -0500 Received: from mx1.redhat.com ([209.132.183.28]:33662) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YKtEd-0005aT-6J for qemu-devel@nongnu.org; Mon, 09 Feb 2015 13:39:03 -0500 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 t19Id2Qa008855 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Mon, 9 Feb 2015 13:39:02 -0500 From: Max Reitz Date: Mon, 9 Feb 2015 13:38:37 -0500 Message-Id: <1423507124-29809-16-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> Subject: [Qemu-devel] [PATCH v2 15/22] blockdev: Add list of monitor-owned BlockBackends List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , Paolo Bonzini , Stefan Hajnoczi , Max Reitz The monitor does hold references to some BlockBackends so it should have a list of those BBs; blk_backends is a different list, as it contains references to all BBs (after a follow-up patch, that is), and that should not be changed because we do need such a list. Signed-off-by: Max Reitz --- block/block-backend.c | 27 ++++++++++++++++++++++++++- blockdev.c | 14 ++++++++++++++ include/sysemu/block-backend.h | 2 ++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/block/block-backend.c b/block/block-backend.c index 1a411c2..208c16c 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -28,6 +28,7 @@ struct BlockBackend { BlockDriverState *bs; DriveInfo *legacy_dinfo; /* null unless created by drive_new() */ QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */ + QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */ void *dev; /* attached device model, if any */ /* TODO change to DeviceState when all users are qdevified */ @@ -69,6 +70,11 @@ static void drive_info_del(DriveInfo *dinfo); static QTAILQ_HEAD(, BlockBackend) blk_backends = QTAILQ_HEAD_INITIALIZER(blk_backends); +/* All BlockBackends referenced by the monitor and which are iterated through by + * blk_next() */ +static QTAILQ_HEAD(, BlockBackend) monitor_block_backends = + QTAILQ_HEAD_INITIALIZER(monitor_block_backends); + /* * Create a new BlockBackend with @name, with a reference count of one. * @name must not be null or empty. @@ -231,7 +237,8 @@ void blk_unref(BlockBackend *blk, Notifier *close_all_notifier) */ BlockBackend *blk_next(BlockBackend *blk) { - return blk ? QTAILQ_NEXT(blk, link) : QTAILQ_FIRST(&blk_backends); + return blk ? QTAILQ_NEXT(blk, monitor_link) + : QTAILQ_FIRST(&monitor_block_backends); } /* @@ -250,6 +257,24 @@ BlockBackend *blk_next_inserted(BlockBackend *blk) } /* + * Add a BlockBackend into the list of backends referenced by the monitor. + * Strictly for use by blockdev.c. + */ +void monitor_add_blk(BlockBackend *blk) +{ + QTAILQ_INSERT_TAIL(&monitor_block_backends, blk, monitor_link); +} + +/* + * Remove a BlockBackend from the list of backends referenced by the monitor. + * Strictly for use by blockdev.c. + */ +void monitor_remove_blk(BlockBackend *blk) +{ + QTAILQ_REMOVE(&monitor_block_backends, blk, monitor_link); +} + +/* * Return @blk's name, a non-null string. * Wart: the name is empty iff @blk has been hidden with * blk_hide_on_behalf_of_do_drive_del(). diff --git a/blockdev.c b/blockdev.c index 8f21c4a..7f1ad42 100644 --- a/blockdev.c +++ b/blockdev.c @@ -90,6 +90,8 @@ static int if_max_devs[IF_COUNT] = { static void monitor_blk_unref_with_can(BlockBackend *blk, BlockdevCloseAllNotifier *can) { + BlockBackend *blk1 = NULL; + if (can) { assert(can->blk == blk); } else { @@ -101,6 +103,15 @@ static void monitor_blk_unref_with_can(BlockBackend *blk, assert(can); } + /* Thanks to do_drive_del() magic, the BlockBackend is not necessarily + * listed at this point */ + while ((blk1 = blk_next(blk1)) != NULL) { + if (blk1 == blk) { + monitor_remove_blk(blk); + break; + } + } + blk_unref(blk, &can->n); QTAILQ_REMOVE(&close_all_notifiers, can, next); g_free(can); @@ -634,6 +645,8 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, blk_set_on_error(blk, on_read_error, on_write_error); + monitor_add_blk(blk); + err_no_bs_opts: qemu_opts_del(opts); return blk; @@ -2290,6 +2303,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data) */ if (blk_get_attached_dev(blk)) { blk_hide_on_behalf_of_do_drive_del(blk); + monitor_remove_blk(blk); /* Further I/O must not pause the guest */ blk_set_on_error(blk, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT); diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h index 4773878..5effc8f 100644 --- a/include/sysemu/block-backend.h +++ b/include/sysemu/block-backend.h @@ -75,6 +75,8 @@ BlockBackend *blk_by_name(const char *name); bool blk_name_taken(const char *name); BlockBackend *blk_next(BlockBackend *blk); BlockBackend *blk_next_inserted(BlockBackend *blk); +void monitor_add_blk(BlockBackend *blk); +void monitor_remove_blk(BlockBackend *blk); BlockDriverState *blk_bs(BlockBackend *blk); void blk_remove_bs(BlockBackend *blk); -- 2.1.0