From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42792) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cAoht-0001lN-0P for qemu-devel@nongnu.org; Sat, 26 Nov 2016 20:56:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cAohp-0006mE-U6 for qemu-devel@nongnu.org; Sat, 26 Nov 2016 20:56:41 -0500 From: Max Reitz Date: Sun, 27 Nov 2016 02:56:01 +0100 Message-Id: <20161127015622.24105-4-mreitz@redhat.com> In-Reply-To: <20161127015622.24105-1-mreitz@redhat.com> References: <20161127015622.24105-1-mreitz@redhat.com> Subject: [Qemu-devel] [PATCH v2 03/24] block: Add BDS.backing_overridden List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Max Reitz , Kevin Wolf , Alberto Garcia , Eric Blake If the backing file is overridden, this most probably does change the guest-visible data of a BDS. Therefore, we will need to consider this in bdrv_refresh_filename(). Adding a new field to the BDS is not nice, but it is very simple and exactly keeps track of whether the backing file has been overridden. Signed-off-by: Max Reitz --- While this patch adds a TODO comment that sounds like it could be resolved in a later patch in this series, it is not. Checking whether @options contains significant runtime options is not trivial, because we not only care about significant options at that level but also at levels below: Normally, it should be fine to check that for backing_hd and backing_hd->file->bs, but that's not for sure. So I decided a false positive is better than a false negative here, which is why the TODO persists throughout the series. --- block.c | 14 ++++++++++++++ block/mirror.c | 4 ++++ blockdev.c | 16 ++++++++++++++++ include/block/block_int.h | 1 + 4 files changed, 35 insertions(+) diff --git a/block.c b/block.c index 1615f5d..c6c62b2 100644 --- a/block.c +++ b/block.c @@ -1516,6 +1516,12 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options, goto free_exit; } + if (reference || qdict_size(options)) { + /* TODO: Should only be set to true if @options contains actually + * significant runtime options */ + bs->backing_overridden = true; + } + if (bs->backing_format[0] != '\0' && !qdict_haskey(options, "driver")) { qdict_put(options, "driver", qstring_from_str(bs->backing_format)); } @@ -1659,6 +1665,9 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs, bdrv_ref(bs_snapshot); bdrv_append(bs_snapshot, bs); + bs_snapshot->backing_overridden = true; + bdrv_refresh_filename(bs_snapshot); + g_free(tmp_filename); return bs_snapshot; @@ -1786,6 +1795,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename, backing = qdict_get_try_str(options, "backing"); if (backing && *backing == '\0') { flags |= BDRV_O_NO_BACKING; + bs->backing_overridden = true; qdict_del(options, "backing"); } @@ -3959,6 +3969,10 @@ void bdrv_refresh_filename(BlockDriverState *bs) * refresh those first */ QLIST_FOREACH(child, &bs->children, next) { bdrv_refresh_filename(child->bs); + + if (child->role == &child_backing && child->bs->backing_overridden) { + bs->backing_overridden = true; + } } if (drv->bdrv_refresh_filename) { diff --git a/block/mirror.c b/block/mirror.c index 4ece624..6cb6cbd 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -891,6 +891,10 @@ static void mirror_complete(BlockJob *job, Error **errp) assert(!target->backing); bdrv_set_backing_hd(target, backing); + + /* The target image's file already has been created with the backing + * file we just set, so there is no need to set backing_overridden or + * call bdrv_refresh_filename(). */ } s->should_complete = true; diff --git a/blockdev.c b/blockdev.c index 245e1e1..7889bab 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1771,6 +1771,8 @@ static void external_snapshot_commit(BlkActionState *common) { ExternalSnapshotState *state = DO_UPCAST(ExternalSnapshotState, common, common); + TransactionAction *action = common->action; + bool image_was_existing = false; bdrv_set_aio_context(state->new_bs, state->aio_context); @@ -1783,6 +1785,20 @@ static void external_snapshot_commit(BlkActionState *common) bdrv_reopen(state->old_bs, state->old_bs->open_flags & ~BDRV_O_RDWR, NULL); } + + if (action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC) { + BlockdevSnapshotSync *s = action->u.blockdev_snapshot_sync.data; + if (s->has_mode && s->mode == NEW_IMAGE_MODE_EXISTING) { + image_was_existing = true; + } + } else { + image_was_existing = true; + } + + if (image_was_existing) { + state->new_bs->backing_overridden = true; + bdrv_refresh_filename(state->new_bs); + } } static void external_snapshot_abort(BlkActionState *common) diff --git a/include/block/block_int.h b/include/block/block_int.h index 83a423c..555f3c2 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -461,6 +461,7 @@ struct BlockDriverState { char backing_file[PATH_MAX]; /* if non zero, the image is a diff of this file image */ char backing_format[16]; /* if non-zero and backing_file exists */ + bool backing_overridden; /* backing file has been specified by the user */ QDict *full_open_options; char exact_filename[PATH_MAX]; -- 2.10.2