Blame SOURCES/kvm-qcow2-Forward-ZERO_WRITE-flag-for-full-preallocation.patch

902636
From 4290173219e15065e9a7c2e95774ac979b5fd869 Mon Sep 17 00:00:00 2001
902636
From: Kevin Wolf <kwolf@redhat.com>
902636
Date: Mon, 8 Jun 2020 15:01:40 +0100
902636
Subject: [PATCH 12/17] qcow2: Forward ZERO_WRITE flag for full preallocation
902636
902636
RH-Author: Kevin Wolf <kwolf@redhat.com>
902636
Message-id: <20200608150140.38218-12-kwolf@redhat.com>
902636
Patchwork-id: 97456
902636
O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 11/11] qcow2: Forward ZERO_WRITE flag for full preallocation
902636
Bugzilla: 1780574
902636
RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
902636
RH-Acked-by: Eric Blake <eblake@redhat.com>
902636
RH-Acked-by: Max Reitz <mreitz@redhat.com>
902636
902636
The BDRV_REQ_ZERO_WRITE is currently implemented in a way that first the
902636
image is possibly preallocated and then the zero flag is added to all
902636
clusters. This means that a copy-on-write operation may be needed when
902636
writing to these clusters, despite having used preallocation, negating
902636
one of the major benefits of preallocation.
902636
902636
Instead, try to forward the BDRV_REQ_ZERO_WRITE to the protocol driver,
902636
and if the protocol driver can ensure that the new area reads as zeros,
902636
we can skip setting the zero flag in the qcow2 layer.
902636
902636
Unfortunately, the same approach doesn't work for metadata
902636
preallocation, so we'll still set the zero flag there.
902636
902636
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
902636
Reviewed-by: Max Reitz <mreitz@redhat.com>
902636
Message-Id: <20200424142701.67053-1-kwolf@redhat.com>
902636
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
902636
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
902636
(cherry picked from commit eb8a0cf3ba26611f3981f8f45ac6a868975a68cc)
902636
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
902636
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
902636
---
902636
 block/qcow2.c              | 22 +++++++++++++++++++---
902636
 tests/qemu-iotests/274.out |  4 ++--
902636
 2 files changed, 21 insertions(+), 5 deletions(-)
902636
902636
diff --git a/block/qcow2.c b/block/qcow2.c
902636
index f3d6cb0..b783662 100644
902636
--- a/block/qcow2.c
902636
+++ b/block/qcow2.c
902636
@@ -4153,9 +4153,25 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
902636
         /* Allocate the data area */
902636
         new_file_size = allocation_start +
902636
                         nb_new_data_clusters * s->cluster_size;
902636
-        /* Image file grows, so @exact does not matter */
902636
-        ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
902636
-                               errp);
902636
+        /*
902636
+         * Image file grows, so @exact does not matter.
902636
+         *
902636
+         * If we need to zero out the new area, try first whether the protocol
902636
+         * driver can already take care of this.
902636
+         */
902636
+        if (flags & BDRV_REQ_ZERO_WRITE) {
902636
+            ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc,
902636
+                                   BDRV_REQ_ZERO_WRITE, NULL);
902636
+            if (ret >= 0) {
902636
+                flags &= ~BDRV_REQ_ZERO_WRITE;
902636
+            }
902636
+        } else {
902636
+            ret = -1;
902636
+        }
902636
+        if (ret < 0) {
902636
+            ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
902636
+                                   errp);
902636
+        }
902636
         if (ret < 0) {
902636
             error_prepend(errp, "Failed to resize underlying file: ");
902636
             qcow2_free_clusters(bs, allocation_start,
902636
diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
902636
index 1a796fd..9d6fdeb 100644
902636
--- a/tests/qemu-iotests/274.out
902636
+++ b/tests/qemu-iotests/274.out
902636
@@ -187,7 +187,7 @@ read 65536/65536 bytes at offset 9437184
902636
 10 MiB (0xa00000) bytes     allocated at offset 5 MiB (0x500000)
902636
 
902636
 [{ "start": 0, "length": 5242880, "depth": 1, "zero": true, "data": false},
902636
-{ "start": 5242880, "length": 10485760, "depth": 0, "zero": true, "data": false, "offset": 327680}]
902636
+{ "start": 5242880, "length": 10485760, "depth": 0, "zero": false, "data": true, "offset": 327680}]
902636
 
902636
 === preallocation=full ===
902636
 Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
902636
@@ -206,7 +206,7 @@ read 65536/65536 bytes at offset 11534336
902636
 4 MiB (0x400000) bytes     allocated at offset 8 MiB (0x800000)
902636
 
902636
 [{ "start": 0, "length": 8388608, "depth": 1, "zero": true, "data": false},
902636
-{ "start": 8388608, "length": 4194304, "depth": 0, "zero": true, "data": false, "offset": 327680}]
902636
+{ "start": 8388608, "length": 4194304, "depth": 0, "zero": false, "data": true, "offset": 327680}]
902636
 
902636
 === preallocation=off ===
902636
 Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
902636
-- 
902636
1.8.3.1
902636