From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33607) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W0jGo-0003la-8B for qemu-devel@nongnu.org; Tue, 07 Jan 2014 21:53:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1W0jGi-0005IP-7E for qemu-devel@nongnu.org; Tue, 07 Jan 2014 21:53:26 -0500 Received: from mx1.redhat.com ([209.132.183.28]:24347) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W0jGh-0005IJ-T5 for qemu-devel@nongnu.org; Tue, 07 Jan 2014 21:53:20 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s082rJY5031311 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 7 Jan 2014 21:53:19 -0500 From: Fam Zheng Date: Wed, 8 Jan 2014 10:52:16 +0800 Message-Id: <1389149541-9829-7-git-send-email-famz@redhat.com> In-Reply-To: <1389149541-9829-1-git-send-email-famz@redhat.com> References: <1389149541-9829-1-git-send-email-famz@redhat.com> Subject: [Qemu-devel] [PATCH v9 06/11] block: Add backing_blocker in BlockDriverState List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kwolf@redhat.com, rjones@redhat.com, armbru@redhat.com, imain@redhat.com, stefanha@redhat.com, pbonzini@redhat.com This makes use of op_blocker and blocks all the operations except for commit target, on each BlockDriverState->backing_hd. Signed-off-by: Fam Zheng --- block.c | 16 ++++++++++++++-- include/block/block_int.h | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/block.c b/block.c index ff25749..907c483 100644 --- a/block.c +++ b/block.c @@ -961,13 +961,22 @@ fail: void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd) { if (bs->backing_hd) { + assert(error_is_set(&bs->backing_blocker)); + bdrv_op_unblock_all(bs->backing_hd, bs->backing_blocker); bdrv_unref(bs->backing_hd); + } else if (backing_hd) { + error_setg(&bs->backing_blocker, + "device is used as backing hd of '%s'", + bs->device_name); } bs->backing_hd = backing_hd; if (!backing_hd) { bs->backing_file[0] = '\0'; bs->backing_format[0] = '\0'; + if (error_is_set(&bs->backing_blocker)) { + error_free(bs->backing_blocker); + } return; } pstrcpy(bs->backing_file, sizeof(bs->backing_file), backing_hd->filename); @@ -975,6 +984,10 @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd) backing_hd->drv ? backing_hd->drv->format_name : ""); bdrv_ref(bs->backing_hd); + bdrv_op_block_all(bs->backing_hd, bs->backing_blocker); + /* Otherwise we won't be able to commit due to check in bdrv_commit */ + bdrv_op_unblock(bs->backing_hd, BLOCK_OP_TYPE_COMMIT, + bs->backing_blocker); pstrcpy(bs->backing_file, sizeof(bs->backing_file), bs->backing_hd->file->filename); pstrcpy(bs->backing_format, sizeof(bs->backing_format), @@ -1481,8 +1494,7 @@ void bdrv_close(BlockDriverState *bs) if (bs->drv) { if (bs->backing_hd) { - bdrv_unref(bs->backing_hd); - bs->backing_hd = NULL; + bdrv_set_backing_hd(bs, NULL); } bs->drv->bdrv_close(bs); g_free(bs->opaque); diff --git a/include/block/block_int.h b/include/block/block_int.h index 2f6556d..1ac17d5 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -341,6 +341,9 @@ struct BlockDriverState { BlockJob *job; QDict *options; + + /* The error object in use for blocking operations on backing_hd */ + Error *backing_blocker; }; int get_tmp_filename(char *filename, int size); -- 1.8.5.1