[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PULL 17/35] qemu-img: Add find_nonzero()
From: |
Kevin Wolf |
Subject: |
[Qemu-block] [PULL 17/35] qemu-img: Add find_nonzero() |
Date: |
Thu, 26 Oct 2017 15:17:23 +0200 |
From: Eric Blake <address@hidden>
During 'qemu-img compare', when we are checking that an allocated
portion of one file is all zeros, we don't need to waste time
computing how many additional sectors after the first non-zero
byte are also non-zero. Create a new helper find_nonzero() to do
the check for a first non-zero sector, and rebase
check_empty_sectors() to use it.
The new interface intentionally uses bytes in its interface, even
though it still crawls the buffer a sector at a time; it is robust
to a partial sector at the end of the buffer.
Signed-off-by: Eric Blake <address@hidden>
Reviewed-by: John Snow <address@hidden>
Signed-off-by: Kevin Wolf <address@hidden>
---
qemu-img.c | 32 ++++++++++++++++++++++++++++----
1 file changed, 28 insertions(+), 4 deletions(-)
diff --git a/qemu-img.c b/qemu-img.c
index e4b84c4f56..89f1093d81 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1065,6 +1065,28 @@ done:
}
/*
+ * Returns -1 if 'buf' contains only zeroes, otherwise the byte index
+ * of the first sector boundary within buf where the sector contains a
+ * non-zero byte. This function is robust to a buffer that is not
+ * sector-aligned.
+ */
+static int64_t find_nonzero(const uint8_t *buf, int64_t n)
+{
+ int64_t i;
+ int64_t end = QEMU_ALIGN_DOWN(n, BDRV_SECTOR_SIZE);
+
+ for (i = 0; i < end; i += BDRV_SECTOR_SIZE) {
+ if (!buffer_is_zero(buf + i, BDRV_SECTOR_SIZE)) {
+ return i;
+ }
+ }
+ if (i < n && !buffer_is_zero(buf + i, n - end)) {
+ return i;
+ }
+ return -1;
+}
+
+/*
* Returns true iff the first sector pointed to by 'buf' contains at least
* a non-NUL byte.
*
@@ -1189,7 +1211,9 @@ static int check_empty_sectors(BlockBackend *blk, int64_t
sect_num,
int sect_count, const char *filename,
uint8_t *buffer, bool quiet)
{
- int pnum, ret = 0;
+ int ret = 0;
+ int64_t idx;
+
ret = blk_pread(blk, sect_num << BDRV_SECTOR_BITS, buffer,
sect_count << BDRV_SECTOR_BITS);
if (ret < 0) {
@@ -1197,10 +1221,10 @@ static int check_empty_sectors(BlockBackend *blk,
int64_t sect_num,
sectors_to_bytes(sect_num), filename, strerror(-ret));
return ret;
}
- ret = is_allocated_sectors(buffer, sect_count, &pnum);
- if (ret || pnum != sect_count) {
+ idx = find_nonzero(buffer, sect_count * BDRV_SECTOR_SIZE);
+ if (idx >= 0) {
qprintf(quiet, "Content mismatch at offset %" PRId64 "!\n",
- sectors_to_bytes(ret ? sect_num : sect_num + pnum));
+ sectors_to_bytes(sect_num) + idx);
return 1;
}
--
2.13.6
- [Qemu-block] [PULL 08/35] qemu-img: Switch get_block_status() to byte-based, (continued)
- [Qemu-block] [PULL 08/35] qemu-img: Switch get_block_status() to byte-based, Kevin Wolf, 2017/10/26
- [Qemu-block] [PULL 06/35] qcow2: Switch is_zero_sectors() to byte-based, Kevin Wolf, 2017/10/26
- [Qemu-block] [PULL 09/35] block: Convert bdrv_get_block_status() to bytes, Kevin Wolf, 2017/10/26
- [Qemu-block] [PULL 07/35] block: Switch bdrv_make_zero() to byte-based, Kevin Wolf, 2017/10/26
- [Qemu-block] [PULL 11/35] block: Switch BdrvCoGetBlockStatusData to byte-based, Kevin Wolf, 2017/10/26
- [Qemu-block] [PULL 10/35] block: Switch bdrv_co_get_block_status() to byte-based, Kevin Wolf, 2017/10/26
- [Qemu-block] [PULL 12/35] block: Switch bdrv_common_block_status_above() to byte-based, Kevin Wolf, 2017/10/26
- [Qemu-block] [PULL 13/35] block: Switch bdrv_co_get_block_status_above() to byte-based, Kevin Wolf, 2017/10/26
- [Qemu-block] [PULL 15/35] qemu-img: Simplify logic in img_compare(), Kevin Wolf, 2017/10/26
- [Qemu-block] [PULL 16/35] qemu-img: Speed up compare on pre-allocated larger file, Kevin Wolf, 2017/10/26
- [Qemu-block] [PULL 17/35] qemu-img: Add find_nonzero(),
Kevin Wolf <=
- [Qemu-block] [PULL 14/35] block: Convert bdrv_get_block_status_above() to bytes, Kevin Wolf, 2017/10/26
- [Qemu-block] [PULL 18/35] qemu-img: Drop redundant error message in compare, Kevin Wolf, 2017/10/26
- [Qemu-block] [PULL 19/35] qemu-img: Change check_empty_sectors() to byte-based, Kevin Wolf, 2017/10/26
- [Qemu-block] [PULL 23/35] block: Align block status requests, Kevin Wolf, 2017/10/26
- [Qemu-block] [PULL 24/35] block: Reduce bdrv_aligned_preadv() rounding, Kevin Wolf, 2017/10/26
- [Qemu-block] [PULL 20/35] qemu-img: Change compare_sectors() to be byte-based, Kevin Wolf, 2017/10/26
- [Qemu-block] [PULL 22/35] qemu-img: Change img_compare() to be byte-based, Kevin Wolf, 2017/10/26
- [Qemu-block] [PULL 21/35] qemu-img: Change img_rebase() to be byte-based, Kevin Wolf, 2017/10/26
- [Qemu-block] [PULL 25/35] qcow2: Reduce is_zero() rounding, Kevin Wolf, 2017/10/26
- [Qemu-block] [PULL 27/35] qemu-img.1: Image invalidation on qemu-img commit, Kevin Wolf, 2017/10/26