From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57129) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VjjF6-0007cn-EJ for qemu-devel@nongnu.org; Fri, 22 Nov 2013 00:25:30 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VjjF0-0004c4-5T for qemu-devel@nongnu.org; Fri, 22 Nov 2013 00:25:24 -0500 Received: from mx1.redhat.com ([209.132.183.28]:49652) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VjjEz-0004bw-St for qemu-devel@nongnu.org; Fri, 22 Nov 2013 00:25:18 -0500 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id rAM5PH3L002931 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 22 Nov 2013 00:25:17 -0500 From: Fam Zheng Date: Fri, 22 Nov 2013 13:24:52 +0800 Message-Id: <1385097894-1380-6-git-send-email-famz@redhat.com> In-Reply-To: <1385097894-1380-1-git-send-email-famz@redhat.com> References: <1385097894-1380-1-git-send-email-famz@redhat.com> Subject: [Qemu-devel] [PATCH v4 5/7] block: Parse "backing" option to reference existing BDS List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kwolf@redhat.com, hbrock@redhat.com, rjones@redhat.com, imain@redhat.com, stefanha@redhat.com, pbonzini@redhat.com Signed-off-by: Fam Zheng --- block.c | 37 ++++++++++++++++++++++++++++++++----- include/block/block_int.h | 3 +++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/block.c b/block.c index 3bf4c8a..a5da656 100644 --- a/block.c +++ b/block.c @@ -1166,11 +1166,33 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, /* If there is a backing file, use it */ if ((flags & BDRV_O_NO_BACKING) == 0) { QDict *backing_options; - - qdict_extract_subqdict(options, &backing_options, "backing."); - ret = bdrv_open_backing_file(bs, backing_options, &local_err); - if (ret < 0) { - goto close_and_fail; + const char *backing_bs; + + backing_bs = qdict_get_try_str(options, "backing"); + if (backing_bs) { + bs->backing_hd = bdrv_find(backing_bs); + qdict_del(options, "backing"); + if (bs->backing_hd) { + bdrv_ref(bs->backing_hd); + assert(!bs->backing_blocker); + error_setg(&bs->backing_blocker, + "device is used as backing hd of '%s'", + bs->device_name); + bdrv_op_block_all(bs->backing_hd, bs->backing_blocker); + pstrcpy(bs->backing_file, sizeof(bs->backing_file), + bs->backing_hd->filename); + pstrcpy(bs->backing_format, sizeof(bs->backing_format), + bs->backing_hd->drv->format_name); + } else { + error_setg(errp, "Backing device not found: %s", backing_bs); + goto close_and_fail; + } + } else { + qdict_extract_subqdict(options, &backing_options, "backing."); + ret = bdrv_open_backing_file(bs, backing_options, &local_err); + if (ret < 0) { + goto close_and_fail; + } } } @@ -1461,6 +1483,11 @@ void bdrv_close(BlockDriverState *bs) if (bs->drv) { if (bs->backing_hd) { + if (error_is_set(&bs->backing_blocker)) { + bdrv_op_unblock_all(bs->backing_hd, + bs->backing_blocker); + error_free(bs->backing_blocker); + } bdrv_unref(bs->backing_hd); bs->backing_hd = NULL; } diff --git a/include/block/block_int.h b/include/block/block_int.h index 60edc80..6db30c9 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -316,6 +316,9 @@ struct BlockDriverState { BlockJob *job; QDict *options; + + /* For backing reference, block the operations of named backing device */ + Error *backing_blocker; }; int get_tmp_filename(char *filename, int size); -- 1.8.4.2