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