From nobody Mon Feb 9 07:55:48 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507780725806538.3717771576036; Wed, 11 Oct 2017 20:58:45 -0700 (PDT) Received: from localhost ([::1]:43584 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2Udx-00031P-1e for importer@patchew.org; Wed, 11 Oct 2017 23:58:45 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58507) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2UTi-0002vG-On for qemu-devel@nongnu.org; Wed, 11 Oct 2017 23:48:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2UTh-0007ht-QY for qemu-devel@nongnu.org; Wed, 11 Oct 2017 23:48:10 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48970) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2UTf-0007cc-JQ; Wed, 11 Oct 2017 23:48:07 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8BE9C5114F; Thu, 12 Oct 2017 03:48:06 +0000 (UTC) Received: from red.redhat.com (ovpn-122-223.rdu2.redhat.com [10.10.122.223]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4C7626955E; Thu, 12 Oct 2017 03:48:05 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 8BE9C5114F Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=eblake@redhat.com From: Eric Blake To: qemu-devel@nongnu.org Date: Wed, 11 Oct 2017 22:47:11 -0500 Message-Id: <20171012034720.11947-16-eblake@redhat.com> In-Reply-To: <20171012034720.11947-1-eblake@redhat.com> References: <20171012034720.11947-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 12 Oct 2017 03:48:06 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v6 15/24] qemu-img: Add find_nonzero() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, jsnow@redhat.com, famz@redhat.com, qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: John Snow --- v4-v5: no change v3: new patch --- 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 =3D QEMU_ALIGN_DOWN(n, BDRV_SECTOR_SIZE); + + for (i =3D 0; i < end; i +=3D 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, int= 64_t sect_num, int sect_count, const char *filename, uint8_t *buffer, bool quiet) { - int pnum, ret =3D 0; + int ret =3D 0; + int64_t idx; + ret =3D 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, i= nt64_t sect_num, sectors_to_bytes(sect_num), filename, strerror(-ret)); return ret; } - ret =3D is_allocated_sectors(buffer, sect_count, &pnum); - if (ret || pnum !=3D sect_count) { + idx =3D find_nonzero(buffer, sect_count * BDRV_SECTOR_SIZE); + if (idx >=3D 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; } --=20 2.13.6