From nobody Mon Feb 9 01:11:17 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 1507814707496330.6203826035636; Thu, 12 Oct 2017 06:25:07 -0700 (PDT) Received: from localhost ([::1]:45504 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2dTz-0003uh-Mf for importer@patchew.org; Thu, 12 Oct 2017 09:25:03 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44559) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2dIe-0003AN-To for qemu-devel@nongnu.org; Thu, 12 Oct 2017 09:13:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2dIa-0005Tg-RA for qemu-devel@nongnu.org; Thu, 12 Oct 2017 09:13:20 -0400 Received: from fanzine.igalia.com ([91.117.99.155]:53036) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1e2dIa-0005T5-Ha; Thu, 12 Oct 2017 09:13:16 -0400 Received: from a88-114-101-76.elisa-laajakaista.fi ([88.114.101.76] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1e2dIZ-0006pW-9F; Thu, 12 Oct 2017 15:13:15 +0200 Received: from berto by perseus.local with local (Exim 4.89) (envelope-from ) id 1e2dCy-0003a7-Qb; Thu, 12 Oct 2017 16:07:28 +0300 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=GCCJOZLG9e0P8uuwgYLvPV2KjCLZF14xVPTV/aMPfjA=; b=EwxFqqLHGdUb8swQIIiccUsaix5Fgm6/ycwqNWCyVGrCkmdqrru4IMjVroEOJbKyhW2bJbh+zbBko/Yxn3967/D1UUMTHnQ3KAQpJ22XHxtRcrUY2i+v/WQDekkFMiXMe6nfeeZFrZWbzMFfu66wu78CJS1xY9w4nO86DG73c9Krs1U6SqzR+KyWAttY4o8SrUI9E9u/SGMDhmhk5TX0UFKyXWkhmnl5sHF53hktV8PZmK+o1FH4xoK8bqZqg1pRe8jCx1Htal/XZe7vL1qFsrBcAaznvDVlZJOd5nheA1I9F7WzipHrYD2zXFmLzkKMiyM/rJHdqgRJBEJMF/FHLw==; From: Alberto Garcia To: qemu-devel@nongnu.org Date: Thu, 12 Oct 2017 16:05:30 +0300 Message-Id: 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 16/31] qcow2: Update l2_allocate() 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" This patch updates l2_allocate() to support the qcow2 cache returning L2 slices instead of full L2 tables. The old code simply gets an L2 table from the cache and initializes it with zeroes or with the contents of an existing table. With a cache that returns slices instead of tables the idea remains the same, but the code must now iterate over all the slices that are contained in an L2 table. Since now we're operating with slices the function can no longer return the newly-allocated table, so it's up to the caller to retrieve the appropriate L2 slice after calling l2_allocate() (note that with this patch the caller is still loading full L2 tables, but we'll deal with that in a separate patch). Signed-off-by: Alberto Garcia --- block/qcow2-cluster.c | 86 +++++++++++++++++++++++++++++++----------------= ---- 1 file changed, 52 insertions(+), 34 deletions(-) diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index aafc19a21b..d3548cc667 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -264,11 +264,12 @@ int qcow2_write_l1_entry(BlockDriverState *bs, int l1= _index) * */ =20 -static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **tabl= e) +static int l2_allocate(BlockDriverState *bs, int l1_index) { BDRVQcow2State *s =3D bs->opaque; uint64_t old_l2_offset; - uint64_t *l2_table =3D NULL; + uint64_t *l2_slice =3D NULL; + unsigned slice, slice_size, n_slices; int64_t l2_offset; int ret; =20 @@ -291,42 +292,50 @@ static int l2_allocate(BlockDriverState *bs, int l1_i= ndex, uint64_t **table) =20 /* allocate a new entry in the l2 cache */ =20 + slice_size =3D s->l2_slice_size * sizeof(uint64_t); + n_slices =3D s->cluster_size / slice_size; + trace_qcow2_l2_allocate_get_empty(bs, l1_index); - ret =3D qcow2_cache_get_empty(bs, s->l2_table_cache, l2_offset, (void*= *) table); - if (ret < 0) { - goto fail; - } - - l2_table =3D *table; - - if ((old_l2_offset & L1E_OFFSET_MASK) =3D=3D 0) { - /* if there was no old l2 table, clear the new table */ - memset(l2_table, 0, s->l2_size * sizeof(uint64_t)); - } else { - uint64_t* old_table; - - /* if there was an old l2 table, read it from the disk */ - BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_COW_READ); - ret =3D qcow2_cache_get(bs, s->l2_table_cache, - old_l2_offset & L1E_OFFSET_MASK, - (void**) &old_table); + for (slice =3D 0; slice < n_slices; slice++) { + ret =3D qcow2_cache_get_empty(bs, s->l2_table_cache, + l2_offset + slice * slice_size, + (void **) &l2_slice); if (ret < 0) { goto fail; } =20 - memcpy(l2_table, old_table, s->cluster_size); + if ((old_l2_offset & L1E_OFFSET_MASK) =3D=3D 0) { + /* if there was no old l2 table, clear the new slice */ + memset(l2_slice, 0, slice_size); + } else { + uint64_t *old_slice; + uint64_t old_l2_slice_offset =3D + (old_l2_offset & L1E_OFFSET_MASK) + slice * slice_size; + + /* if there was an old l2 table, read an slice from the disk */ + BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_COW_READ); + ret =3D qcow2_cache_get(bs, s->l2_table_cache, old_l2_slice_of= fset, + (void **) &old_slice); + if (ret < 0) { + goto fail; + } + + memcpy(l2_slice, old_slice, slice_size); =20 - qcow2_cache_put(s->l2_table_cache, (void **) &old_table); - } + qcow2_cache_put(s->l2_table_cache, (void **) &old_slice); + } + + /* write the l2 slice to the file */ + BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_WRITE); =20 - /* write the l2 table to the file */ - BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_WRITE); + trace_qcow2_l2_allocate_write_l2(bs, l1_index); + qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_slice); + ret =3D qcow2_cache_flush(bs, s->l2_table_cache); + if (ret < 0) { + goto fail; + } =20 - trace_qcow2_l2_allocate_write_l2(bs, l1_index); - qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table); - ret =3D qcow2_cache_flush(bs, s->l2_table_cache); - if (ret < 0) { - goto fail; + qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice); } =20 /* update the L1 entry */ @@ -337,14 +346,13 @@ static int l2_allocate(BlockDriverState *bs, int l1_i= ndex, uint64_t **table) goto fail; } =20 - *table =3D l2_table; trace_qcow2_l2_allocate_done(bs, l1_index, 0); return 0; =20 fail: trace_qcow2_l2_allocate_done(bs, l1_index, ret); - if (l2_table !=3D NULL) { - qcow2_cache_put(s->l2_table_cache, (void **) table); + if (l2_slice !=3D NULL) { + qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice); } s->l1_table[l1_index] =3D old_l2_offset; if (l2_offset > 0) { @@ -688,8 +696,18 @@ static int get_cluster_table(BlockDriverState *bs, uin= t64_t offset, return ret; } } else { + uint64_t new_l2_offset; /* First allocate a new L2 table (and do COW if needed) */ - ret =3D l2_allocate(bs, l1_index, &l2_table); + ret =3D l2_allocate(bs, l1_index); + if (ret < 0) { + return ret; + } + + /* Get the offset of the newly-allocated l2 table */ + new_l2_offset =3D s->l1_table[l1_index] & L1E_OFFSET_MASK; + assert(offset_into_cluster(s, new_l2_offset) =3D=3D 0); + /* Load the l2 table in memory */ + ret =3D l2_load(bs, offset, new_l2_offset, &l2_table); if (ret < 0) { return ret; } --=20 2.11.0