From: Hanna Reitz <hreitz@redhat.com>
To: qemu-block@nongnu.org
Cc: qemu-devel@nongnu.org, Hanna Reitz <hreitz@redhat.com>,
Kevin Wolf <kwolf@redhat.com>,
Stefan Hajnoczi <stefanha@redhat.com>
Subject: [PATCH 1/3] block/qcow2: Keep auto_backing_file if possible
Date: Wed, 3 Aug 2022 16:44:44 +0200 [thread overview]
Message-ID: <20220803144446.20723-2-hreitz@redhat.com> (raw)
In-Reply-To: <20220803144446.20723-1-hreitz@redhat.com>
qcow2_do_open() is used by qcow2_co_invalidate_cache(), i.e. may be run
on an image that has been opened before. When reading the backing file
string from the image header, compare it against the existing
bs->backing_file, and update bs->auto_backing_file only if they differ.
auto_backing_file should ideally contain the filename the backing BDS
will actually have after opening, i.e. a post-bdrv_refresh_filename()
version of what is in the image header. So for example, if the image
header reports the following backing file string:
json:{"driver": "qcow2", "file": {
"driver": "file", "filename": "/tmp/backing.qcow2"
}}
Then auto_backing_file should contain simply "/tmp/backing.qcow2".
Because bdrv_refresh_filename() only works on existing BDSs, though, the
way how we get this auto_backing_file value is to have the format driver
set it to whatever is in the image header, and when the backing BDS is
opened based on that, we update it with the filename the backing BDS
actually got.
However, qcow2's qcow2_co_invalidate_cache() implementation breaks this
because it just resets auto_backing_file to whatever is in the image
file without opening a BDS based on it, so we never get
auto_backing_file back to the "refreshed" version, and in the example
above, it would stay "json:{...}".
Then, bs->backing->bs->filename will differ from bs->auto_backing_file,
making bdrv_backing_overridden(bs) return true, which will lead
bdrv_refresh_filename(bs) to generate a json:{} filename for bs, even
though that may not have been necessary. This is reported in the issue
linked below.
Therefore, skip updating auto_backing_file if nothing has changed in the
image header since we last read it.
Fixes: https://gitlab.com/qemu-project/qemu/-/issues/1117
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
---
block/qcow2.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/block/qcow2.c b/block/qcow2.c
index c6c6692fb7..a43fee2067 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1696,16 +1696,27 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
ret = -EINVAL;
goto fail;
}
+
+ s->image_backing_file = g_malloc(len + 1);
ret = bdrv_pread(bs->file, header.backing_file_offset, len,
- bs->auto_backing_file, 0);
+ s->image_backing_file, 0);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not read backing file name");
goto fail;
}
- bs->auto_backing_file[len] = '\0';
- pstrcpy(bs->backing_file, sizeof(bs->backing_file),
- bs->auto_backing_file);
- s->image_backing_file = g_strdup(bs->auto_backing_file);
+ s->image_backing_file[len] = '\0';
+
+ /*
+ * Update only when something has changed. This function is called by
+ * qcow2_co_invalidate_cache(), and we do not want to reset
+ * auto_backing_file unless necessary.
+ */
+ if (!g_str_equal(s->image_backing_file, bs->backing_file)) {
+ pstrcpy(bs->backing_file, sizeof(bs->backing_file),
+ s->image_backing_file);
+ pstrcpy(bs->auto_backing_file, sizeof(bs->auto_backing_file),
+ s->image_backing_file);
+ }
}
/*
--
2.36.1
next prev parent reply other threads:[~2022-08-03 14:48 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-03 14:44 [PATCH 0/3] block: Keep auto_backing_file post-migration Hanna Reitz
2022-08-03 14:44 ` Hanna Reitz [this message]
2022-08-03 14:44 ` [PATCH 2/3] block/qed: Keep auto_backing_file if possible Hanna Reitz
2022-08-03 14:44 ` [PATCH 3/3] iotests/backing-file-invalidation: Add new test Hanna Reitz
2022-09-22 16:26 ` [PATCH 0/3] block: Keep auto_backing_file post-migration Kevin Wolf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220803144446.20723-2-hreitz@redhat.com \
--to=hreitz@redhat.com \
--cc=kwolf@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).