From nobody Wed Dec 17 21:44:49 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 149451525020770.7358968602498; Thu, 11 May 2017 08:07:30 -0700 (PDT) Received: from localhost ([::1]:48705 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d8pga-0007NC-KQ for importer@patchew.org; Thu, 11 May 2017 11:07:24 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37633) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d8pBC-00034u-Bx for qemu-devel@nongnu.org; Thu, 11 May 2017 10:34:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d8pBB-0008Jy-Ab for qemu-devel@nongnu.org; Thu, 11 May 2017 10:34:58 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38162) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1d8pB5-0008De-Kx; Thu, 11 May 2017 10:34:51 -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 9D50E80C2D; Thu, 11 May 2017 14:34:50 +0000 (UTC) Received: from noname.str.redhat.com (dhcp-192-175.str.redhat.com [10.33.192.175]) by smtp.corp.redhat.com (Postfix) with ESMTP id B622C8A8CF; Thu, 11 May 2017 14:34:42 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 9D50E80C2D 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=kwolf@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 9D50E80C2D From: Kevin Wolf To: qemu-block@nongnu.org Date: Thu, 11 May 2017 16:32:52 +0200 Message-Id: <1494513181-7900-50-git-send-email-kwolf@redhat.com> In-Reply-To: <1494513181-7900-1-git-send-email-kwolf@redhat.com> References: <1494513181-7900-1-git-send-email-kwolf@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, 11 May 2017 14:34:50 +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] [PULL 49/58] 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-devel@nongnu.org, stefanha@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" From: Eric Blake 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 Message-id: 20170507000552.20847-5-eblake@redhat.com Signed-off-by: Max Reitz --- 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; } =20 -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; =20 + 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); =20 - 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 1.8.3.1