|
|
495e37 |
From a221f5a8ed02690687e6709c49ae0e1e01c5f466 Mon Sep 17 00:00:00 2001
|
|
|
495e37 |
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
|
|
495e37 |
Date: Fri, 17 Dec 2021 17:46:54 +0100
|
|
|
495e37 |
Subject: [PATCH 09/12] qemu-img: make is_allocated_sectors() more efficient
|
|
|
495e37 |
|
|
|
495e37 |
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
|
|
495e37 |
RH-MergeRequest: 70: qemu-img convert: Fix sparseness of output image
|
|
|
495e37 |
RH-Commit: [2/2] cc05aa4ac506b57ff9b430c007618cdf1485a03f (kmwolf/centos-qemu-kvm)
|
|
|
495e37 |
RH-Bugzilla: 1882917
|
|
|
495e37 |
RH-Acked-by: Eric Blake <eblake@redhat.com>
|
|
|
495e37 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
495e37 |
RH-Acked-by: Hanna Reitz <hreitz@redhat.com>
|
|
|
495e37 |
|
|
|
495e37 |
Consider the case when the whole buffer is zero and end is unaligned.
|
|
|
495e37 |
|
|
|
495e37 |
If i <= tail, we return 1 and do one unaligned WRITE, RMW happens.
|
|
|
495e37 |
|
|
|
495e37 |
If i > tail, we do on aligned WRITE_ZERO (or skip if target is zeroed)
|
|
|
495e37 |
and again one unaligned WRITE, RMW happens.
|
|
|
495e37 |
|
|
|
495e37 |
Let's do better: don't fragment the whole-zero buffer and report it as
|
|
|
495e37 |
ZERO: in case of zeroed target we just do nothing and avoid RMW. If
|
|
|
495e37 |
target is not zeroes, one unaligned WRITE_ZERO should not be much worse
|
|
|
495e37 |
than one unaligned WRITE.
|
|
|
495e37 |
|
|
|
495e37 |
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
|
|
495e37 |
Message-Id: <20211217164654.1184218-3-vsementsov@virtuozzo.com>
|
|
|
495e37 |
Tested-by: Peter Lieven <pl@kamp.de>
|
|
|
495e37 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
495e37 |
(cherry picked from commit 96054c76ff2db74165385a69f234c57a6bbc941e)
|
|
|
495e37 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
495e37 |
---
|
|
|
495e37 |
qemu-img.c | 23 +++++++++++++++++++----
|
|
|
495e37 |
tests/qemu-iotests/122.out | 8 ++------
|
|
|
495e37 |
2 files changed, 21 insertions(+), 10 deletions(-)
|
|
|
495e37 |
|
|
|
495e37 |
diff --git a/qemu-img.c b/qemu-img.c
|
|
|
495e37 |
index f036a1d428..d7ddfcc528 100644
|
|
|
495e37 |
--- a/qemu-img.c
|
|
|
495e37 |
+++ b/qemu-img.c
|
|
|
495e37 |
@@ -1171,19 +1171,34 @@ static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum,
|
|
|
495e37 |
}
|
|
|
495e37 |
}
|
|
|
495e37 |
|
|
|
495e37 |
+ if (i == n) {
|
|
|
495e37 |
+ /*
|
|
|
495e37 |
+ * The whole buf is the same.
|
|
|
495e37 |
+ * No reason to split it into chunks, so return now.
|
|
|
495e37 |
+ */
|
|
|
495e37 |
+ *pnum = i;
|
|
|
495e37 |
+ return !is_zero;
|
|
|
495e37 |
+ }
|
|
|
495e37 |
+
|
|
|
495e37 |
tail = (sector_num + i) & (alignment - 1);
|
|
|
495e37 |
if (tail) {
|
|
|
495e37 |
if (is_zero && i <= tail) {
|
|
|
495e37 |
- /* treat unallocated areas which only consist
|
|
|
495e37 |
- * of a small tail as allocated. */
|
|
|
495e37 |
+ /*
|
|
|
495e37 |
+ * For sure next sector after i is data, and it will rewrite this
|
|
|
495e37 |
+ * tail anyway due to RMW. So, let's just write data now.
|
|
|
495e37 |
+ */
|
|
|
495e37 |
is_zero = false;
|
|
|
495e37 |
}
|
|
|
495e37 |
if (!is_zero) {
|
|
|
495e37 |
- /* align up end offset of allocated areas. */
|
|
|
495e37 |
+ /* If possible, align up end offset of allocated areas. */
|
|
|
495e37 |
i += alignment - tail;
|
|
|
495e37 |
i = MIN(i, n);
|
|
|
495e37 |
} else {
|
|
|
495e37 |
- /* align down end offset of zero areas. */
|
|
|
495e37 |
+ /*
|
|
|
495e37 |
+ * For sure next sector after i is data, and it will rewrite this
|
|
|
495e37 |
+ * tail anyway due to RMW. Better is avoid RMW and write zeroes up
|
|
|
495e37 |
+ * to aligned bound.
|
|
|
495e37 |
+ */
|
|
|
495e37 |
i -= tail;
|
|
|
495e37 |
}
|
|
|
495e37 |
}
|
|
|
495e37 |
diff --git a/tests/qemu-iotests/122.out b/tests/qemu-iotests/122.out
|
|
|
495e37 |
index 69b8e8b803..e18766e167 100644
|
|
|
495e37 |
--- a/tests/qemu-iotests/122.out
|
|
|
495e37 |
+++ b/tests/qemu-iotests/122.out
|
|
|
495e37 |
@@ -201,9 +201,7 @@ convert -S 4k
|
|
|
495e37 |
{ "start": 8192, "length": 4096, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET},
|
|
|
495e37 |
{ "start": 12288, "length": 4096, "depth": 0, "present": false, "zero": true, "data": false},
|
|
|
495e37 |
{ "start": 16384, "length": 4096, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET},
|
|
|
495e37 |
-{ "start": 20480, "length": 46080, "depth": 0, "present": false, "zero": true, "data": false},
|
|
|
495e37 |
-{ "start": 66560, "length": 1024, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET},
|
|
|
495e37 |
-{ "start": 67584, "length": 67041280, "depth": 0, "present": false, "zero": true, "data": false}]
|
|
|
495e37 |
+{ "start": 20480, "length": 67088384, "depth": 0, "present": false, "zero": true, "data": false}]
|
|
|
495e37 |
|
|
|
495e37 |
convert -c -S 4k
|
|
|
495e37 |
[{ "start": 0, "length": 1024, "depth": 0, "present": true, "zero": false, "data": true},
|
|
|
495e37 |
@@ -215,9 +213,7 @@ convert -c -S 4k
|
|
|
495e37 |
|
|
|
495e37 |
convert -S 8k
|
|
|
495e37 |
[{ "start": 0, "length": 24576, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET},
|
|
|
495e37 |
-{ "start": 24576, "length": 41984, "depth": 0, "present": false, "zero": true, "data": false},
|
|
|
495e37 |
-{ "start": 66560, "length": 1024, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET},
|
|
|
495e37 |
-{ "start": 67584, "length": 67041280, "depth": 0, "present": false, "zero": true, "data": false}]
|
|
|
495e37 |
+{ "start": 24576, "length": 67084288, "depth": 0, "present": false, "zero": true, "data": false}]
|
|
|
495e37 |
|
|
|
495e37 |
convert -c -S 8k
|
|
|
495e37 |
[{ "start": 0, "length": 1024, "depth": 0, "present": true, "zero": false, "data": true},
|
|
|
495e37 |
--
|
|
|
495e37 |
2.27.0
|
|
|
495e37 |
|