From nobody Mon Feb 9 01:34:42 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; dkim=fail; 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 1513343588082785.5175400965919; Fri, 15 Dec 2017 05:13:08 -0800 (PST) Received: from localhost ([::1]:46161 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ePpnU-0000OZ-8a for importer@patchew.org; Fri, 15 Dec 2017 08:13:04 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55503) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ePpVH-0000Wp-1N for qemu-devel@nongnu.org; Fri, 15 Dec 2017 07:54:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ePpVC-0003J5-SV for qemu-devel@nongnu.org; Fri, 15 Dec 2017 07:54:15 -0500 Received: from fanzine.igalia.com ([91.117.99.155]:48077) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ePpVA-0003CI-UE; Fri, 15 Dec 2017 07:54:10 -0500 Received: from [192.168.12.179] (helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1ePpV8-00084n-72; Fri, 15 Dec 2017 13:54:06 +0100 Received: from berto by perseus.local with local (Exim 4.89) (envelope-from ) id 1ePpV8-0004Dw-20; Fri, 15 Dec 2017 14:54:06 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=References:In-Reply-To:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=odlRpW5Y0jby/rx93hE9IMopOeXgpSoh2By9u2fT7V0=; b=l0LJdRw2bnYEDJ5j/S2+E/KKth8sxVbqaboT8oJ/XtxCjOZ8LP4oG2AiLEgrgHm4IDN+LRyncZbV2sahcylV0+readoSI/uyFEszFkowKzyCmz1VXaoQpwzbhMEmRZ7g0xaweO2Fr7hPIFSgX4+DczI774YYruAXgOhFK2C0iiPtMfIfDuNBFpd+ie/jl2asAmWAplXezrNN/ULyyNaCbJsSV0gcu2Ah0BE8TAUdLK6NBdAla2nC3pdp2ni0LzbarNJot7PH9H3XxvndTg5fZl356pBB0JbD6aAOref8EpImHGF9RiK+tYuLxPC4Gv0sdsLCy05hR4XXNnT0UDDbbA==; From: Alberto Garcia To: qemu-devel@nongnu.org Date: Fri, 15 Dec 2017 13:53:52 +0100 Message-Id: <192f0a4a1888e7e18cb7cec9fdbeadad5417b4ef.1513342045.git.berto@igalia.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Received-From: 91.117.99.155 Subject: [Qemu-devel] [PATCH v2 24/32] qcow2: Update qcow2_update_snapshot_refcount() to support L2 slices 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: Kevin Wolf , "Denis V . Lunev" , Alberto Garcia , qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" qcow2_update_snapshot_refcount() increases the refcount of all clusters of a given snapshot. In order to do that it needs to load all its L2 tables and iterate over their entries. Since we'll be loading L2 slices instead of full tables we need to add an extra loop that iterates over all slices of each L2 table. This function doesn't need any additional changes so apart from that this patch simply updates the variable name from l2_table to l2_slice. Signed-off-by: Alberto Garcia Reviewed-by: Eric Blake --- block/qcow2-refcount.c | 150 ++++++++++++++++++++++++++-------------------= ---- 1 file changed, 80 insertions(+), 70 deletions(-) diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 51094fbcfb..45c7bb0ff6 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -1183,18 +1183,22 @@ int qcow2_update_snapshot_refcount(BlockDriverState= *bs, int64_t l1_table_offset, int l1_size, int addend) { BDRVQcow2State *s =3D bs->opaque; - uint64_t *l1_table, *l2_table, l2_offset, entry, l1_size2, refcount; + uint64_t *l1_table, *l2_slice, l2_offset, entry, l1_size2, refcount; bool l1_allocated =3D false; int64_t old_entry, old_l2_offset; + unsigned slice, slice_size, n_slices; int i, j, l1_modified =3D 0, nb_csectors; int ret; =20 assert(addend >=3D -1 && addend <=3D 1); =20 - l2_table =3D NULL; + l2_slice =3D NULL; l1_table =3D NULL; l1_size2 =3D l1_size * sizeof(uint64_t); =20 + slice_size =3D s->l2_slice_size * sizeof(uint64_t); + n_slices =3D s->cluster_size / slice_size; + s->cache_discards =3D true; =20 /* WARNING: qcow2_snapshot_goto relies on this function not using the @@ -1236,91 +1240,97 @@ int qcow2_update_snapshot_refcount(BlockDriverState= *bs, goto fail; } =20 - ret =3D qcow2_cache_get(bs, s->l2_table_cache, l2_offset, - (void**) &l2_table); - if (ret < 0) { - goto fail; - } + for (slice =3D 0; slice < n_slices; slice++) { + ret =3D qcow2_cache_get(bs, s->l2_table_cache, + l2_offset + slice * slice_size, + (void **) &l2_slice); + if (ret < 0) { + goto fail; + } =20 - for (j =3D 0; j < s->l2_size; j++) { - uint64_t cluster_index; - uint64_t offset; + for (j =3D 0; j < s->l2_slice_size; j++) { + uint64_t cluster_index; + uint64_t offset; =20 - entry =3D be64_to_cpu(l2_table[j]); - old_entry =3D entry; - entry &=3D ~QCOW_OFLAG_COPIED; - offset =3D entry & L2E_OFFSET_MASK; + entry =3D be64_to_cpu(l2_slice[j]); + old_entry =3D entry; + entry &=3D ~QCOW_OFLAG_COPIED; + offset =3D entry & L2E_OFFSET_MASK; =20 - switch (qcow2_get_cluster_type(entry)) { - case QCOW2_CLUSTER_COMPRESSED: - nb_csectors =3D ((entry >> s->csize_shift) & - s->csize_mask) + 1; - if (addend !=3D 0) { - ret =3D update_refcount(bs, - (entry & s->cluster_offset_mask) & ~511, + switch (qcow2_get_cluster_type(entry)) { + case QCOW2_CLUSTER_COMPRESSED: + nb_csectors =3D ((entry >> s->csize_shift) & + s->csize_mask) + 1; + if (addend !=3D 0) { + ret =3D update_refcount( + bs, (entry & s->cluster_offset_mask) & ~51= 1, nb_csectors * 512, abs(addend), addend < 0, QCOW2_DISCARD_SNAPSHOT); - if (ret < 0) { + if (ret < 0) { + goto fail; + } + } + /* compressed clusters are never modified */ + refcount =3D 2; + break; + + case QCOW2_CLUSTER_NORMAL: + case QCOW2_CLUSTER_ZERO_ALLOC: + if (offset_into_cluster(s, offset)) { + int l2_index =3D slice * s->l2_slice_size + j; + qcow2_signal_corruption( + bs, true, -1, -1, "Cluster " + "allocation offset %#" PRIx64 + " unaligned (L2 offset: %#" + PRIx64 ", L2 index: %#x)", + offset, l2_offset, l2_index); + ret =3D -EIO; goto fail; } - } - /* compressed clusters are never modified */ - refcount =3D 2; - break; =20 - case QCOW2_CLUSTER_NORMAL: - case QCOW2_CLUSTER_ZERO_ALLOC: - if (offset_into_cluster(s, offset)) { - qcow2_signal_corruption(bs, true, -1, -1, "Cluster= " - "allocation offset %#" PRI= x64 - " unaligned (L2 offset: %#" - PRIx64 ", L2 index: %#x)", - offset, l2_offset, j); - ret =3D -EIO; - goto fail; - } + cluster_index =3D offset >> s->cluster_bits; + assert(cluster_index); + if (addend !=3D 0) { + ret =3D qcow2_update_cluster_refcount( + bs, cluster_index, abs(addend), addend < 0, + QCOW2_DISCARD_SNAPSHOT); + if (ret < 0) { + goto fail; + } + } =20 - cluster_index =3D offset >> s->cluster_bits; - assert(cluster_index); - if (addend !=3D 0) { - ret =3D qcow2_update_cluster_refcount(bs, - cluster_index, abs(addend), addend < 0, - QCOW2_DISCARD_SNAPSHOT); + ret =3D qcow2_get_refcount(bs, cluster_index, &ref= count); if (ret < 0) { goto fail; } - } + break; =20 - ret =3D qcow2_get_refcount(bs, cluster_index, &refcoun= t); - if (ret < 0) { - goto fail; - } - break; + case QCOW2_CLUSTER_ZERO_PLAIN: + case QCOW2_CLUSTER_UNALLOCATED: + refcount =3D 0; + break; =20 - case QCOW2_CLUSTER_ZERO_PLAIN: - case QCOW2_CLUSTER_UNALLOCATED: - refcount =3D 0; - break; - - default: - abort(); - } + default: + abort(); + } =20 - if (refcount =3D=3D 1) { - entry |=3D QCOW_OFLAG_COPIED; - } - if (entry !=3D old_entry) { - if (addend > 0) { - qcow2_cache_set_dependency(bs, s->l2_table_cache, - s->refcount_block_cache); + if (refcount =3D=3D 1) { + entry |=3D QCOW_OFLAG_COPIED; + } + if (entry !=3D old_entry) { + if (addend > 0) { + qcow2_cache_set_dependency(bs, s->l2_table_cac= he, + s->refcount_block_c= ache); + } + l2_slice[j] =3D cpu_to_be64(entry); + qcow2_cache_entry_mark_dirty(s->l2_table_cache, + l2_slice); } - l2_table[j] =3D cpu_to_be64(entry); - qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_tab= le); } + + qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice); } =20 - qcow2_cache_put(s->l2_table_cache, (void **) &l2_table); - if (addend !=3D 0) { ret =3D qcow2_update_cluster_refcount(bs, l2_offset >> s->cluster_bits, @@ -1346,8 +1356,8 @@ int qcow2_update_snapshot_refcount(BlockDriverState *= bs, =20 ret =3D bdrv_flush(bs); fail: - if (l2_table) { - qcow2_cache_put(s->l2_table_cache, (void **) &l2_table); + if (l2_slice) { + qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice); } =20 s->cache_discards =3D false; --=20 2.11.0