95 lines
3.3 KiB
Diff
95 lines
3.3 KiB
Diff
|
From d84b9b93755ece6618ed98fa84386beeb1a0e40b Mon Sep 17 00:00:00 2001
|
||
|
From: Kevin Wolf <kwolf@redhat.com>
|
||
|
Date: Mon, 8 Jun 2020 15:01:36 +0100
|
||
|
Subject: [PATCH 08/17] block: truncate: Don't make backing file data visible
|
||
|
|
||
|
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||
|
Message-id: <20200608150140.38218-8-kwolf@redhat.com>
|
||
|
Patchwork-id: 97454
|
||
|
O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 07/11] block: truncate: Don't make backing file data visible
|
||
|
Bugzilla: 1780574
|
||
|
RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
|
||
|
RH-Acked-by: Eric Blake <eblake@redhat.com>
|
||
|
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
||
|
|
||
|
When extending the size of an image that has a backing file larger than
|
||
|
its old size, make sure that the backing file data doesn't become
|
||
|
visible in the guest, but the added area is properly zeroed out.
|
||
|
|
||
|
Consider the following scenario where the overlay is shorter than its
|
||
|
backing file:
|
||
|
|
||
|
base.qcow2: AAAAAAAA
|
||
|
overlay.qcow2: BBBB
|
||
|
|
||
|
When resizing (extending) overlay.qcow2, the new blocks should not stay
|
||
|
unallocated and make the additional As from base.qcow2 visible like
|
||
|
before this patch, but zeros should be read.
|
||
|
|
||
|
A similar case happens with the various variants of a commit job when an
|
||
|
intermediate file is short (- for unallocated):
|
||
|
|
||
|
base.qcow2: A-A-AAAA
|
||
|
mid.qcow2: BB-B
|
||
|
top.qcow2: C--C--C-
|
||
|
|
||
|
After commit top.qcow2 to mid.qcow2, the following happens:
|
||
|
|
||
|
mid.qcow2: CB-C00C0 (correct result)
|
||
|
mid.qcow2: CB-C--C- (before this fix)
|
||
|
|
||
|
Without the fix, blocks that previously read as zeros on top.qcow2
|
||
|
suddenly turn into A.
|
||
|
|
||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||
|
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
||
|
Message-Id: <20200424125448.63318-8-kwolf@redhat.com>
|
||
|
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||
|
(cherry picked from commit 955c7d6687fefcd903900a1e597fcbc896c661cd)
|
||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||
|
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
||
|
---
|
||
|
block/io.c | 25 +++++++++++++++++++++++++
|
||
|
1 file changed, 25 insertions(+)
|
||
|
|
||
|
diff --git a/block/io.c b/block/io.c
|
||
|
index 3235ce5..6c70b56 100644
|
||
|
--- a/block/io.c
|
||
|
+++ b/block/io.c
|
||
|
@@ -3370,6 +3370,31 @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
+ /*
|
||
|
+ * If the image has a backing file that is large enough that it would
|
||
|
+ * provide data for the new area, we cannot leave it unallocated because
|
||
|
+ * then the backing file content would become visible. Instead, zero-fill
|
||
|
+ * the new area.
|
||
|
+ *
|
||
|
+ * Note that if the image has a backing file, but was opened without the
|
||
|
+ * backing file, taking care of keeping things consistent with that backing
|
||
|
+ * file is the user's responsibility.
|
||
|
+ */
|
||
|
+ if (new_bytes && bs->backing) {
|
||
|
+ int64_t backing_len;
|
||
|
+
|
||
|
+ backing_len = bdrv_getlength(backing_bs(bs));
|
||
|
+ if (backing_len < 0) {
|
||
|
+ ret = backing_len;
|
||
|
+ error_setg_errno(errp, -ret, "Could not get backing file size");
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (backing_len > old_size) {
|
||
|
+ flags |= BDRV_REQ_ZERO_WRITE;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
if (drv->bdrv_co_truncate) {
|
||
|
if (flags & ~bs->supported_truncate_flags) {
|
||
|
error_setg(errp, "Block driver does not support requested flags");
|
||
|
--
|
||
|
1.8.3.1
|
||
|
|