From nobody Mon Feb 9 07:55:43 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.zoho.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 1493867419917857.8144213011417; Wed, 3 May 2017 20:10:19 -0700 (PDT) Received: from localhost ([::1]:39510 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d679m-0004Pi-FC for importer@patchew.org; Wed, 03 May 2017 23:10:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52473) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d677g-0002tw-Uj for qemu-devel@nongnu.org; Wed, 03 May 2017 23:08:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d677f-0001G1-Uk for qemu-devel@nongnu.org; Wed, 03 May 2017 23:08:08 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53370) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1d677d-0001E8-A3; Wed, 03 May 2017 23:08:05 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6DE6B80C17; Thu, 4 May 2017 03:08:04 +0000 (UTC) Received: from red.redhat.com (ovpn-122-206.rdu2.redhat.com [10.10.122.206]) by smtp.corp.redhat.com (Postfix) with ESMTP id A491F18350; Thu, 4 May 2017 03:08:03 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 6DE6B80C17 Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=eblake@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 6DE6B80C17 From: Eric Blake To: qemu-devel@nongnu.org Date: Wed, 3 May 2017 22:07:48 -0500 Message-Id: <20170504030755.1001-4-eblake@redhat.com> In-Reply-To: <20170504030755.1001-1-eblake@redhat.com> References: <20170504030755.1001-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Thu, 04 May 2017 03:08:04 +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 v12 03/10] qcow2: Correctly report status of preallocated zero clusters 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, qemu-block@nongnu.org, mreitz@redhat.com 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" We were throwing away the preallocation information associated with zero clusters. But we should be matching the well-defined semantics in bdrv_get_block_status(), where (BDRV_BLOCK_ZERO | BDRV_BLOCK_OFFSET_VALID) informs the user which offset is reserved, while still reminding the user that reading from that offset is likely to read garbage. count_contiguous_clusters_by_type() is now used only for unallocated cluster runs, hence it gets renamed and tightened. Making this change lets us see which portions of an image are zero but preallocated, when using qemu-img map --output=3Djson. The --output=3Dhuman side intentionally ignores all zero clusters, whether or not they are preallocated. The fact that there is no change to qemu-iotests './check -qcow2' merely means that we aren't yet testing this aspect of qemu-img; a later patch will add a test. Signed-off-by: Eric Blake Reviewed-by: Max Reitz --- v12: rename helper function v11: reserved for blkdebug half of v10 v10: new patch --- block/qcow2-cluster.c | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 335a505..f3bfce6 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -334,16 +334,23 @@ static int count_contiguous_clusters(int nb_clusters,= int cluster_size, return i; } -static int count_contiguous_clusters_by_type(int nb_clusters, - uint64_t *l2_table, - int wanted_type) +/* + * Checks how many consecutive unallocated clusters in a given L2 + * table have the same cluster type. + */ +static int count_contiguous_clusters_unallocated(int nb_clusters, + uint64_t *l2_table, + int wanted_type) { int i; + assert(wanted_type =3D=3D QCOW2_CLUSTER_ZERO || + wanted_type =3D=3D QCOW2_CLUSTER_UNALLOCATED); for (i =3D 0; i < nb_clusters; i++) { - int type =3D qcow2_get_cluster_type(be64_to_cpu(l2_table[i])); + uint64_t entry =3D be64_to_cpu(l2_table[i]); + int type =3D qcow2_get_cluster_type(entry); - if (type !=3D wanted_type) { + if (type !=3D wanted_type || entry & L2E_OFFSET_MASK) { break; } } @@ -565,14 +572,32 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, ui= nt64_t offset, ret =3D -EIO; goto fail; } - c =3D count_contiguous_clusters_by_type(nb_clusters, &l2_table[l2_= index], - QCOW2_CLUSTER_ZERO); - *cluster_offset =3D 0; + /* Distinguish between pure zero clusters and pre-allocated ones */ + if (*cluster_offset & L2E_OFFSET_MASK) { + c =3D count_contiguous_clusters(nb_clusters, s->cluster_size, + &l2_table[l2_index], QCOW_OFLAG_= ZERO); + *cluster_offset &=3D L2E_OFFSET_MASK; + if (offset_into_cluster(s, *cluster_offset)) { + qcow2_signal_corruption(bs, true, -1, -1, + "Preallocated zero cluster offset = %#" + PRIx64 " unaligned (L2 offset: %#" + PRIx64 ", L2 index: %#x)", + *cluster_offset, l2_offset, l2_ind= ex); + ret =3D -EIO; + goto fail; + } + } else { + c =3D count_contiguous_clusters_unallocated(nb_clusters, + &l2_table[l2_index], + QCOW2_CLUSTER_ZERO); + *cluster_offset =3D 0; + } break; case QCOW2_CLUSTER_UNALLOCATED: /* how many empty clusters ? */ - c =3D count_contiguous_clusters_by_type(nb_clusters, &l2_table[l2_= index], - QCOW2_CLUSTER_UNALLOCATED); + c =3D count_contiguous_clusters_unallocated(nb_clusters, + &l2_table[l2_index], + QCOW2_CLUSTER_UNALLOCATE= D); *cluster_offset =3D 0; break; case QCOW2_CLUSTER_NORMAL: --=20 2.9.3