From patchwork Tue Jul 14 15:39:25 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 495142 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 2118F1402A9 for ; Wed, 15 Jul 2015 01:42:38 +1000 (AEST) Received: from localhost ([::1]:60146 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZF2Ls-0003vj-BN for incoming@patchwork.ozlabs.org; Tue, 14 Jul 2015 11:42:36 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50612) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZF2JA-0007kL-9z for qemu-devel@nongnu.org; Tue, 14 Jul 2015 11:39:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZF2J6-0004pp-Ts for qemu-devel@nongnu.org; Tue, 14 Jul 2015 11:39:48 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59049) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZF2J3-0004mn-RZ; Tue, 14 Jul 2015 11:39:42 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 77E57BBF60; Tue, 14 Jul 2015 15:39:41 +0000 (UTC) Received: from noname.redhat.com (ovpn-116-108.ams2.redhat.com [10.36.116.108]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t6EFdYBl031466; Tue, 14 Jul 2015 11:39:40 -0400 From: Kevin Wolf To: qemu-block@nongnu.org Date: Tue, 14 Jul 2015 17:39:25 +0200 Message-Id: <1436888372-27871-5-git-send-email-kwolf@redhat.com> In-Reply-To: <1436888372-27871-1-git-send-email-kwolf@redhat.com> References: <1436888372-27871-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: kwolf@redhat.com, qemu-devel@nongnu.org Subject: [Qemu-devel] [PULL 04/11] block: Introduce bdrv_open_child() 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 It is the same as bdrv_open_image(), except that it doesn't only return success or failure, but the newly created BdrvChild object for the new child node. As the BdrvChild object already contains a BlockDriverState pointer (and this is supposed to become the only pointer so that bdrv_append() and friends can just change a single pointer in BdrvChild), the pbs parameter is removed for bdrv_open_child(). Signed-off-by: Kevin Wolf Reviewed-by: Max Reitz --- block.c | 71 ++++++++++++++++++++++++++++++++++------------- include/block/block.h | 6 ++++ include/block/block_int.h | 4 +-- 3 files changed, 60 insertions(+), 21 deletions(-) diff --git a/block.c b/block.c index 0398bff..029feeb 100644 --- a/block.c +++ b/block.c @@ -1102,9 +1102,9 @@ static int bdrv_fill_options(QDict **options, const char **pfilename, return 0; } -static void bdrv_attach_child(BlockDriverState *parent_bs, - BlockDriverState *child_bs, - const BdrvChildRole *child_role) +static BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs, + BlockDriverState *child_bs, + const BdrvChildRole *child_role) { BdrvChild *child = g_new(BdrvChild, 1); *child = (BdrvChild) { @@ -1113,6 +1113,8 @@ static void bdrv_attach_child(BlockDriverState *parent_bs, }; QLIST_INSERT_HEAD(&parent_bs->children, child, next); + + return child; } void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd) @@ -1229,7 +1231,7 @@ free_exit: * device's options. * * If allow_none is true, no image will be opened if filename is false and no - * BlockdevRef is given. *pbs will remain unchanged and 0 will be returned. + * BlockdevRef is given. NULL will be returned, but errp remains unset. * * bdrev_key specifies the key for the image's BlockdevRef in the options QDict. * That QDict has to be flattened; therefore, if the BlockdevRef is a QDict @@ -1237,21 +1239,20 @@ free_exit: * BlockdevRef. * * The BlockdevRef will be removed from the options QDict. - * - * To conform with the behavior of bdrv_open(), *pbs has to be NULL. */ -int bdrv_open_image(BlockDriverState **pbs, const char *filename, - QDict *options, const char *bdref_key, - BlockDriverState* parent, const BdrvChildRole *child_role, - bool allow_none, Error **errp) +BdrvChild *bdrv_open_child(const char *filename, + QDict *options, const char *bdref_key, + BlockDriverState* parent, + const BdrvChildRole *child_role, + bool allow_none, Error **errp) { + BdrvChild *c = NULL; + BlockDriverState *bs; QDict *image_options; int ret; char *bdref_key_dot; const char *reference; - assert(pbs); - assert(*pbs == NULL); assert(child_role != NULL); bdref_key_dot = g_strdup_printf("%s.", bdref_key); @@ -1260,28 +1261,60 @@ int bdrv_open_image(BlockDriverState **pbs, const char *filename, reference = qdict_get_try_str(options, bdref_key); if (!filename && !reference && !qdict_size(image_options)) { - if (allow_none) { - ret = 0; - } else { + if (!allow_none) { error_setg(errp, "A block device must be specified for \"%s\"", bdref_key); - ret = -EINVAL; } QDECREF(image_options); goto done; } - ret = bdrv_open_inherit(pbs, filename, reference, image_options, 0, + bs = NULL; + ret = bdrv_open_inherit(&bs, filename, reference, image_options, 0, parent, child_role, NULL, errp); if (ret < 0) { goto done; } - bdrv_attach_child(parent, *pbs, child_role); + c = bdrv_attach_child(parent, bs, child_role); done: qdict_del(options, bdref_key); - return ret; + return c; +} + +/* + * This is a version of bdrv_open_child() that returns 0/-EINVAL instead of + * a BdrvChild object. + * + * If allow_none is true, no image will be opened if filename is false and no + * BlockdevRef is given. *pbs will remain unchanged and 0 will be returned. + * + * To conform with the behavior of bdrv_open(), *pbs has to be NULL. + */ +int bdrv_open_image(BlockDriverState **pbs, const char *filename, + QDict *options, const char *bdref_key, + BlockDriverState* parent, const BdrvChildRole *child_role, + bool allow_none, Error **errp) +{ + Error *local_err = NULL; + BdrvChild *c; + + assert(pbs); + assert(*pbs == NULL); + + c = bdrv_open_child(filename, options, bdref_key, parent, child_role, + allow_none, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return -EINVAL; + } + + if (c != NULL) { + *pbs = c->bs; + } + + return 0; } int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp) diff --git a/include/block/block.h b/include/block/block.h index 06e4137..5048772 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -12,6 +12,7 @@ /* block.c */ typedef struct BlockDriver BlockDriver; typedef struct BlockJob BlockJob; +typedef struct BdrvChild BdrvChild; typedef struct BdrvChildRole BdrvChildRole; typedef struct BlockDriverInfo { @@ -208,6 +209,11 @@ int bdrv_open_image(BlockDriverState **pbs, const char *filename, QDict *options, const char *bdref_key, BlockDriverState* parent, const BdrvChildRole *child_role, bool allow_none, Error **errp); +BdrvChild *bdrv_open_child(const char *filename, + QDict *options, const char *bdref_key, + BlockDriverState* parent, + const BdrvChildRole *child_role, + bool allow_none, Error **errp); void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd); int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp); int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp); diff --git a/include/block/block_int.h b/include/block/block_int.h index 8996baf..ec244b5 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -335,11 +335,11 @@ struct BdrvChildRole { extern const BdrvChildRole child_file; extern const BdrvChildRole child_format; -typedef struct BdrvChild { +struct BdrvChild { BlockDriverState *bs; const BdrvChildRole *role; QLIST_ENTRY(BdrvChild) next; -} BdrvChild; +}; /* * Note: the function bdrv_append() copies and swaps contents of