yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone
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