From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44699) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yqlz1-0002GF-6R for qemu-devel@nongnu.org; Fri, 08 May 2015 13:22:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Yqlz0-0004UK-C5 for qemu-devel@nongnu.org; Fri, 08 May 2015 13:22:43 -0400 From: Kevin Wolf Date: Fri, 8 May 2015 19:21:40 +0200 Message-Id: <1431105726-3682-9-git-send-email-kwolf@redhat.com> In-Reply-To: <1431105726-3682-1-git-send-email-kwolf@redhat.com> References: <1431105726-3682-1-git-send-email-kwolf@redhat.com> Subject: [Qemu-devel] [PATCH 08/34] block: Add list of children to BlockDriverState List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-block@nongnu.org Cc: kwolf@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, mreitz@redhat.com This allows iterating over all children of a given BDS, not only including bs->file and bs->backing_hd, but also driver-specific ones like VMDK extents or Quorum children. Signed-off-by: Kevin Wolf --- block.c | 27 +++++++++++++++++++++++++++ include/block/block_int.h | 8 ++++++++ 2 files changed, 35 insertions(+) diff --git a/block.c b/block.c index c4f0fb4..59f54ed 100644 --- a/block.c +++ b/block.c @@ -1301,6 +1301,19 @@ out: return ret; } +static void bdrv_attach_child(BlockDriverState *parent_bs, + BlockDriverState *child_bs, + const BdrvChildRole *child_role) +{ + BdrvChild *child = g_new(BdrvChild, 1); + *child = (BdrvChild) { + .bs = child_bs, + .role = child_role, + }; + + QLIST_INSERT_HEAD(&parent_bs->children, child, next); +} + /* * Opens a disk image (raw, qcow2, vmdk, ...) * @@ -1353,6 +1366,9 @@ static int bdrv_open_inherit(BlockDriverState **pbs, const char *filename, return -ENODEV; } bdrv_ref(bs); + if (child_role) { + bdrv_attach_child(parent, bs, child_role); + } *pbs = bs; return 0; } @@ -1495,6 +1511,10 @@ static int bdrv_open_inherit(BlockDriverState **pbs, const char *filename, goto close_and_fail; } + if (child_role) { + bdrv_attach_child(parent, bs, child_role); + } + QDECREF(options); *pbs = bs; return 0; @@ -1789,6 +1809,12 @@ void bdrv_close(BlockDriverState *bs) notifier_list_notify(&bs->close_notifiers, bs); if (bs->drv) { + BdrvChild *child, *next; + + QLIST_FOREACH_SAFE(child, &bs->children, next, next) { + g_free(child); + } + if (bs->backing_hd) { BlockDriverState *backing_hd = bs->backing_hd; bdrv_set_backing_hd(bs, NULL); @@ -1999,6 +2025,7 @@ void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top) /* The contents of 'tmp' will become bs_top, as we are * swapping bs_new and bs_top contents. */ bdrv_set_backing_hd(bs_top, bs_new); + bdrv_attach_child(bs_top, bs_new, &child_backing); } static void bdrv_delete(BlockDriverState *bs) diff --git a/include/block/block_int.h b/include/block/block_int.h index eb01ea2..12c7fb3 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -334,6 +334,12 @@ struct BdrvChildRole { extern const BdrvChildRole child_file; extern const BdrvChildRole child_format; +typedef struct BdrvChild { + BlockDriverState *bs; + const BdrvChildRole *role; + QLIST_ENTRY(BdrvChild) next; +} BdrvChild; + /* * Note: the function bdrv_append() copies and swaps contents of * BlockDriverStates, so if you add new fields to this struct, please @@ -428,6 +434,8 @@ struct BlockDriverState { /* long-running background operation */ BlockJob *job; + QLIST_HEAD(, BdrvChild) children; + QDict *options; BlockdevDetectZeroesOptions detect_zeroes; -- 1.8.3.1