| 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 |
| |
| |
| @@ -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 |
| |
| |
| @@ -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}] |
| |
| |
| 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}] |
| |
| |
| Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16 |
| -- |
| 1.8.3.1 |
| |