From nobody Thu Oct 30 08:09:39 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.zohomail.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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1526088672457666.6214346443232; Fri, 11 May 2018 18:31:12 -0700 (PDT) Received: from localhost ([::1]:33839 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJNP-0002SN-Id for importer@patchew.org; Fri, 11 May 2018 21:31:11 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40262) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJIA-0006Mm-0c for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fHJI7-0006Tg-Tq for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:45 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:33386 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fHJI2-0006GW-QT; Fri, 11 May 2018 21:25:38 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 678E07D65F; Sat, 12 May 2018 01:25:38 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-231.bos.redhat.com [10.18.17.231]) by smtp.corp.redhat.com (Postfix) with ESMTP id 07A76215CDA7; Sat, 12 May 2018 01:25:37 +0000 (UTC) From: John Snow To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Fri, 11 May 2018 21:25:26 -0400 Message-Id: <20180512012537.22478-2-jsnow@redhat.com> In-Reply-To: <20180512012537.22478-1-jsnow@redhat.com> References: <20180512012537.22478-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Sat, 12 May 2018 01:25:38 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Sat, 12 May 2018 01:25:38 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'jsnow@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [RFC PATCH 01/12] qcow2-bitmap: cache bm_list 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 , Vladimir Sementsov-Ogievskiy , Markus Armbruster , Max Reitz , John Snow 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 don't need to re-read this list every time, exactly. We can keep it cach= ed and delete our copy when we flush to disk. Because we don't try to flush bitmaps on close if there's nothing to flush, add a new conditional to delete the state anyway for a clean exit. Signed-off-by: John Snow --- block/qcow2-bitmap.c | 74 ++++++++++++++++++++++++++++++++----------------= ---- block/qcow2.c | 2 ++ block/qcow2.h | 2 ++ 3 files changed, 50 insertions(+), 28 deletions(-) diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index 6e93ec43e1..fb0a4f3ec4 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -536,8 +536,7 @@ static uint32_t bitmap_list_count(Qcow2BitmapList *bm_l= ist) * Get bitmap list from qcow2 image. Actually reads bitmap directory, * checks it and convert to bitmap list. */ -static Qcow2BitmapList *bitmap_list_load(BlockDriverState *bs, uint64_t of= fset, - uint64_t size, Error **errp) +static Qcow2BitmapList *bitmap_list_load(BlockDriverState *bs, Error **err= p) { int ret; BDRVQcow2State *s =3D bs->opaque; @@ -545,6 +544,8 @@ static Qcow2BitmapList *bitmap_list_load(BlockDriverSta= te *bs, uint64_t offset, Qcow2BitmapDirEntry *e; uint32_t nb_dir_entries =3D 0; Qcow2BitmapList *bm_list =3D NULL; + uint64_t offset =3D s->bitmap_directory_offset; + uint64_t size =3D s->bitmap_directory_size; =20 if (size =3D=3D 0) { error_setg(errp, "Requested bitmap directory size is zero"); @@ -636,6 +637,30 @@ fail: return NULL; } =20 +static Qcow2BitmapList *get_bitmap_list(BlockDriverState *bs, Error **errp) +{ + BDRVQcow2State *s =3D bs->opaque; + Qcow2BitmapList *bm_list; + + if (s->bitmap_list) { + return (Qcow2BitmapList *)s->bitmap_list; + } + + bm_list =3D bitmap_list_load(bs, errp); + s->bitmap_list =3D bm_list; + return bm_list; +} + +static void del_bitmap_list(BlockDriverState *bs) +{ + BDRVQcow2State *s =3D bs->opaque; + + if (s->bitmap_list) { + bitmap_list_free(s->bitmap_list); + s->bitmap_list =3D NULL; + } +} + int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *r= es, void **refcount_table, int64_t *refcount_table_size) @@ -656,8 +681,7 @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs,= BdrvCheckResult *res, return ret; } =20 - bm_list =3D bitmap_list_load(bs, s->bitmap_directory_offset, - s->bitmap_directory_size, NULL); + bm_list =3D get_bitmap_list(bs, NULL); if (bm_list =3D=3D NULL) { res->corruptions++; return -EINVAL; @@ -707,8 +731,6 @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs,= BdrvCheckResult *res, } =20 out: - bitmap_list_free(bm_list); - return ret; } =20 @@ -953,8 +975,7 @@ bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, Err= or **errp) return false; } =20 - bm_list =3D bitmap_list_load(bs, s->bitmap_directory_offset, - s->bitmap_directory_size, errp); + bm_list =3D get_bitmap_list(bs, errp); if (bm_list =3D=3D NULL) { return false; } @@ -992,14 +1013,12 @@ bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, = Error **errp) } =20 g_slist_free(created_dirty_bitmaps); - bitmap_list_free(bm_list); - return header_updated; =20 fail: g_slist_foreach(created_dirty_bitmaps, release_dirty_bitmap_helper, bs= ); g_slist_free(created_dirty_bitmaps); - bitmap_list_free(bm_list); + del_bitmap_list(bs); =20 return false; } @@ -1027,8 +1046,7 @@ int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs= , bool *header_updated, return -EINVAL; } =20 - bm_list =3D bitmap_list_load(bs, s->bitmap_directory_offset, - s->bitmap_directory_size, errp); + bm_list =3D get_bitmap_list(bs, errp); if (bm_list =3D=3D NULL) { return -EINVAL; } @@ -1068,7 +1086,6 @@ int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs= , bool *header_updated, =20 out: g_slist_free(ro_dirty_bitmaps); - bitmap_list_free(bm_list); =20 return ret; } @@ -1277,8 +1294,7 @@ void qcow2_remove_persistent_dirty_bitmap(BlockDriver= State *bs, return; } =20 - bm_list =3D bitmap_list_load(bs, s->bitmap_directory_offset, - s->bitmap_directory_size, errp); + bm_list =3D get_bitmap_list(bs, errp); if (bm_list =3D=3D NULL) { return; } @@ -1300,7 +1316,11 @@ void qcow2_remove_persistent_dirty_bitmap(BlockDrive= rState *bs, =20 fail: bitmap_free(bm); - bitmap_list_free(bm_list); +} + +void qcow2_persistent_dirty_bitmaps_cache_destroy(BlockDriverState *bs) +{ + del_bitmap_list(bs); } =20 void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **er= rp) @@ -1317,12 +1337,12 @@ void qcow2_store_persistent_dirty_bitmaps(BlockDriv= erState *bs, Error **errp) =20 if (!bdrv_has_changed_persistent_bitmaps(bs)) { /* nothing to do */ - return; + goto out; } =20 if (!can_write(bs)) { error_setg(errp, "No write access"); - return; + goto out; } =20 QSIMPLEQ_INIT(&drop_tables); @@ -1330,10 +1350,9 @@ void qcow2_store_persistent_dirty_bitmaps(BlockDrive= rState *bs, Error **errp) if (s->nb_bitmaps =3D=3D 0) { bm_list =3D bitmap_list_new(); } else { - bm_list =3D bitmap_list_load(bs, s->bitmap_directory_offset, - s->bitmap_directory_size, errp); + bm_list =3D get_bitmap_list(bs, errp); if (bm_list =3D=3D NULL) { - return; + goto out; } } =20 @@ -1414,8 +1433,7 @@ void qcow2_store_persistent_dirty_bitmaps(BlockDriver= State *bs, Error **errp) g_free(tb); } =20 - bitmap_list_free(bm_list); - return; + goto out; =20 fail: QSIMPLEQ_FOREACH(bm, bm_list, entry) { @@ -1430,7 +1448,9 @@ fail: g_free(tb); } =20 - bitmap_list_free(bm_list); + out: + del_bitmap_list(bs); + return; } =20 int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp) @@ -1495,14 +1515,12 @@ bool qcow2_can_store_new_dirty_bitmap(BlockDriverSt= ate *bs, goto fail; } =20 - bm_list =3D bitmap_list_load(bs, s->bitmap_directory_offset, - s->bitmap_directory_size, errp); + bm_list =3D get_bitmap_list(bs, errp); if (bm_list =3D=3D NULL) { goto fail; } =20 found =3D find_bitmap_by_name(bm_list, name); - bitmap_list_free(bm_list); if (found) { error_setg(errp, "Bitmap with the same name is already stored"); goto fail; diff --git a/block/qcow2.c b/block/qcow2.c index 2f36e632f9..7ae9000656 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2135,6 +2135,8 @@ static void qcow2_close(BlockDriverState *bs) =20 if (!(s->flags & BDRV_O_INACTIVE)) { qcow2_inactivate(bs); + } else { + qcow2_persistent_dirty_bitmaps_cache_destroy(bs); } =20 cache_clean_timer_del(bs); diff --git a/block/qcow2.h b/block/qcow2.h index adf5c3950f..796a8c914b 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -299,6 +299,7 @@ typedef struct BDRVQcow2State { uint64_t bitmap_directory_size; uint64_t bitmap_directory_offset; bool dirty_bitmaps_loaded; + void *bitmap_list; =20 int flags; int qcow_version; @@ -675,6 +676,7 @@ bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, Err= or **errp); int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs, bool *header_update= d, Error **errp); int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp); +void qcow2_persistent_dirty_bitmaps_cache_destroy(BlockDriverState *bs); void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **er= rp); int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp); bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs, --=20 2.14.3