From: Kevin Wolf <kwolf@redhat.com>
To: qemu-block@nongnu.org
Cc: kwolf@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com
Subject: [PATCH 3/6] vmdk: Fix partial overwrite of zero cluster
Date: Thu, 30 Apr 2020 15:30:04 +0200 [thread overview]
Message-ID: <20200430133007.170335-4-kwolf@redhat.com> (raw)
In-Reply-To: <20200430133007.170335-1-kwolf@redhat.com>
When overwriting a zero cluster, we must not perform copy-on-write from
the backing file, but from a zeroed buffer.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vmdk.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/block/vmdk.c b/block/vmdk.c
index bdd7d2dcf1..da25b8992e 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1340,7 +1340,9 @@ static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp)
* get_whole_cluster
*
* Copy backing file's cluster that covers @sector_num, otherwise write zero,
- * to the cluster at @cluster_sector_num.
+ * to the cluster at @cluster_sector_num. If @zeroed is true, we're overwriting
+ * a zeroed cluster in the current layer and must not copy data from the
+ * backing file.
*
* If @skip_start_sector < @skip_end_sector, the relative range
* [@skip_start_sector, @skip_end_sector) is not copied or written, and leave
@@ -1351,18 +1353,21 @@ static int get_whole_cluster(BlockDriverState *bs,
uint64_t cluster_offset,
uint64_t offset,
uint64_t skip_start_bytes,
- uint64_t skip_end_bytes)
+ uint64_t skip_end_bytes,
+ bool zeroed)
{
int ret = VMDK_OK;
int64_t cluster_bytes;
uint8_t *whole_grain;
+ bool copy_from_backing;
/* For COW, align request sector_num to cluster start */
cluster_bytes = extent->cluster_sectors << BDRV_SECTOR_BITS;
offset = QEMU_ALIGN_DOWN(offset, cluster_bytes);
whole_grain = qemu_blockalign(bs, cluster_bytes);
+ copy_from_backing = bs->backing && !zeroed;
- if (!bs->backing) {
+ if (!copy_from_backing) {
memset(whole_grain, 0, skip_start_bytes);
memset(whole_grain + skip_end_bytes, 0, cluster_bytes - skip_end_bytes);
}
@@ -1377,7 +1382,7 @@ static int get_whole_cluster(BlockDriverState *bs,
/* Read backing data before skip range */
if (skip_start_bytes > 0) {
- if (bs->backing) {
+ if (copy_from_backing) {
/* qcow2 emits this on bs->file instead of bs->backing */
BLKDBG_EVENT(extent->file, BLKDBG_COW_READ);
ret = bdrv_pread(bs->backing, offset, whole_grain,
@@ -1397,7 +1402,7 @@ static int get_whole_cluster(BlockDriverState *bs,
}
/* Read backing data after skip range */
if (skip_end_bytes < cluster_bytes) {
- if (bs->backing) {
+ if (copy_from_backing) {
/* qcow2 emits this on bs->file instead of bs->backing */
BLKDBG_EVENT(extent->file, BLKDBG_COW_READ);
ret = bdrv_pread(bs->backing, offset + skip_end_bytes,
@@ -1631,7 +1636,8 @@ static int get_cluster_offset(BlockDriverState *bs,
* or inappropriate VM shutdown.
*/
ret = get_whole_cluster(bs, extent, cluster_sector * BDRV_SECTOR_SIZE,
- offset, skip_start_bytes, skip_end_bytes);
+ offset, skip_start_bytes, skip_end_bytes,
+ zeroed);
if (ret) {
return ret;
}
--
2.25.3
next prev parent reply other threads:[~2020-04-30 13:41 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-30 13:30 [PATCH 0/6] vmdk: Fix zero cluster handling Kevin Wolf
2020-04-30 13:30 ` [PATCH 1/6] vmdk: Rename VmdkMetaData.valid to new_allocation Kevin Wolf
2020-04-30 14:10 ` Eric Blake
2020-04-30 13:30 ` [PATCH 2/6] vmdk: Fix zero cluster allocation Kevin Wolf
2020-04-30 14:14 ` Eric Blake
2020-04-30 14:19 ` Eric Blake
2020-04-30 14:32 ` Kevin Wolf
2020-04-30 13:30 ` Kevin Wolf [this message]
2020-04-30 14:16 ` [PATCH 3/6] vmdk: Fix partial overwrite of zero cluster Eric Blake
2020-04-30 13:30 ` [PATCH 4/6] vmdk: Don't update L2 table for zero write on " Kevin Wolf
2020-04-30 14:17 ` Eric Blake
2020-04-30 13:30 ` [PATCH 5/6] vmdk: Flush only once in vmdk_L2update() Kevin Wolf
2020-04-30 14:18 ` Eric Blake
2020-04-30 13:30 ` [PATCH 6/6] iotests: vmdk: Enable zeroed_grained=on by default Kevin Wolf
2020-04-30 14:22 ` Eric Blake
2020-04-30 14:42 ` Kevin Wolf
2020-05-05 9:42 ` [PATCH 0/6] vmdk: Fix zero cluster handling 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=20200430133007.170335-4-kwolf@redhat.com \
--to=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.