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