diff --git a/cutils.c b/cutils.c index a6ffd4644..af308cd7b 100644 --- a/cutils.c +++ b/cutils.c @@ -303,6 +303,41 @@ void qemu_iovec_memset_skip(QEMUIOVector *qiov, int c, size_t count, } } +/* + * Checks if a buffer is all zeroes + * + * Attention! The len must be a multiple of 4 * sizeof(long) due to + * restriction of optimizations in this function. + */ +bool buffer_is_zero(const void *buf, size_t len) +{ + /* + * Use long as the biggest available internal data type that fits into the + * CPU register and unroll the loop to smooth out the effect of memory + * latency. + */ + + size_t i; + long d0, d1, d2, d3; + const long * const data = buf; + + assert(len % (4 * sizeof(long)) == 0); + len /= sizeof(long); + + for (i = 0; i < len; i += 4) { + d0 = data[i + 0]; + d1 = data[i + 1]; + d2 = data[i + 2]; + d3 = data[i + 3]; + + if (d0 || d1 || d2 || d3) { + return false; + } + } + + return true; +} + #ifndef _WIN32 /* Sets a specific flag */ int fcntl_setfl(int fd, int flag) diff --git a/qemu-common.h b/qemu-common.h index 9b997f883..c5e9cad35 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -335,6 +335,8 @@ void qemu_iovec_memset(QEMUIOVector *qiov, int c, size_t count); void qemu_iovec_memset_skip(QEMUIOVector *qiov, int c, size_t count, size_t skip); +bool buffer_is_zero(const void *buf, size_t len); + void qemu_progress_init(int enabled, float min_skip); void qemu_progress_end(void); void qemu_progress_print(float delta, int max); diff --git a/qemu-img.c b/qemu-img.c index 01cc0d35a..c4bcf41e1 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -514,40 +514,6 @@ static int img_commit(int argc, char **argv) return 0; } -/* - * Checks whether the sector is not a zero sector. - * - * Attention! The len must be a multiple of 4 * sizeof(long) due to - * restriction of optimizations in this function. - */ -static int is_not_zero(const uint8_t *sector, int len) -{ - /* - * Use long as the biggest available internal data type that fits into the - * CPU register and unroll the loop to smooth out the effect of memory - * latency. - */ - - int i; - long d0, d1, d2, d3; - const long * const data = (const long *) sector; - - len /= sizeof(long); - - for(i = 0; i < len; i += 4) { - d0 = data[i + 0]; - d1 = data[i + 1]; - d2 = data[i + 2]; - d3 = data[i + 3]; - - if (d0 || d1 || d2 || d3) { - return 1; - } - } - - return 0; -} - /* * Returns true iff the first sector pointed to by 'buf' contains at least * a non-NUL byte. @@ -557,20 +523,22 @@ static int is_not_zero(const uint8_t *sector, int len) */ static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum) { - int v, i; + bool is_zero; + int i; if (n <= 0) { *pnum = 0; return 0; } - v = is_not_zero(buf, 512); + is_zero = buffer_is_zero(buf, 512); for(i = 1; i < n; i++) { buf += 512; - if (v != is_not_zero(buf, 512)) + if (is_zero != buffer_is_zero(buf, 512)) { break; + } } *pnum = i; - return v; + return !is_zero; } /* @@ -955,7 +923,7 @@ static int img_convert(int argc, char **argv) if (n < cluster_sectors) { memset(buf + n * 512, 0, cluster_size - n * 512); } - if (is_not_zero(buf, cluster_size)) { + if (!buffer_is_zero(buf, cluster_size)) { ret = bdrv_write_compressed(out_bs, sector_num, buf, cluster_sectors); if (ret != 0) {