From nobody Sun Oct 5 21:15:27 2025 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 14932577392911019.0105349617403; Wed, 26 Apr 2017 18:48:59 -0700 (PDT) Received: from localhost ([::1]:57793 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d3YYD-0000ry-Mu for importer@patchew.org; Wed, 26 Apr 2017 21:48:57 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33530) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d3YVx-0007RF-7z for qemu-devel@nongnu.org; Wed, 26 Apr 2017 21:46:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d3YVw-00042B-9T for qemu-devel@nongnu.org; Wed, 26 Apr 2017 21:46:37 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52978) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1d3YVs-0003ys-Rn; Wed, 26 Apr 2017 21:46:33 -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 A9BC0811AC; Thu, 27 Apr 2017 01:46:31 +0000 (UTC) Received: from red.redhat.com (ovpn-123-177.rdu2.redhat.com [10.10.123.177]) by smtp.corp.redhat.com (Postfix) with ESMTP id EE931784A4; Thu, 27 Apr 2017 01:46:30 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com A9BC0811AC Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=eblake@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com A9BC0811AC From: Eric Blake To: qemu-devel@nongnu.org Date: Wed, 26 Apr 2017 20:46:11 -0500 Message-Id: <20170427014626.11553-3-eblake@redhat.com> In-Reply-To: <20170427014626.11553-1-eblake@redhat.com> References: <20170427014626.11553-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.27]); Thu, 27 Apr 2017 01:46:31 +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 v10 02/17] 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. 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 --- v10: new patch --- block/qcow2-cluster.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 100398c..d1063df 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -328,6 +328,10 @@ static int count_contiguous_clusters(int nb_clusters, = int cluster_size, return i; } +/* + * Checks how many consecutive clusters in a given L2 table have the same + * cluster type with no corresponding allocation. + */ static int count_contiguous_clusters_by_type(int nb_clusters, uint64_t *l2_table, int wanted_type) @@ -335,9 +339,10 @@ static int count_contiguous_clusters_by_type(int nb_cl= usters, int i; 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; } } @@ -559,9 +564,26 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uin= t64_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_by_type(nb_clusters, + &l2_table[l2_index], + QCOW2_CLUSTER_ZERO); + *cluster_offset =3D 0; + } break; case QCOW2_CLUSTER_UNALLOCATED: /* how many empty clusters ? */ --=20 2.9.3