From: John Snow <jsnow@redhat.com>
To: qemu-block@nongnu.org, qemu-devel@nongnu.org
Cc: Max Reitz <mreitz@redhat.com>,
Markus Armbruster <armbru@redhat.com>,
Kevin Wolf <kwolf@redhat.com>, Eric Blake <eblake@redhat.com>,
Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>,
John Snow <jsnow@redhat.com>
Subject: [Qemu-devel] [RFC PATCH 01/12] qcow2-bitmap: cache bm_list
Date: Fri, 11 May 2018 21:25:26 -0400 [thread overview]
Message-ID: <20180512012537.22478-2-jsnow@redhat.com> (raw)
In-Reply-To: <20180512012537.22478-1-jsnow@redhat.com>
We don't need to re-read this list every time, exactly. We can keep it cached
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 <jsnow@redhat.com>
---
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_list)
* 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 offset,
- uint64_t size, Error **errp)
+static Qcow2BitmapList *bitmap_list_load(BlockDriverState *bs, Error **errp)
{
int ret;
BDRVQcow2State *s = bs->opaque;
@@ -545,6 +544,8 @@ static Qcow2BitmapList *bitmap_list_load(BlockDriverState *bs, uint64_t offset,
Qcow2BitmapDirEntry *e;
uint32_t nb_dir_entries = 0;
Qcow2BitmapList *bm_list = NULL;
+ uint64_t offset = s->bitmap_directory_offset;
+ uint64_t size = s->bitmap_directory_size;
if (size == 0) {
error_setg(errp, "Requested bitmap directory size is zero");
@@ -636,6 +637,30 @@ fail:
return NULL;
}
+static Qcow2BitmapList *get_bitmap_list(BlockDriverState *bs, Error **errp)
+{
+ BDRVQcow2State *s = bs->opaque;
+ Qcow2BitmapList *bm_list;
+
+ if (s->bitmap_list) {
+ return (Qcow2BitmapList *)s->bitmap_list;
+ }
+
+ bm_list = bitmap_list_load(bs, errp);
+ s->bitmap_list = bm_list;
+ return bm_list;
+}
+
+static void del_bitmap_list(BlockDriverState *bs)
+{
+ BDRVQcow2State *s = bs->opaque;
+
+ if (s->bitmap_list) {
+ bitmap_list_free(s->bitmap_list);
+ s->bitmap_list = NULL;
+ }
+}
+
int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
void **refcount_table,
int64_t *refcount_table_size)
@@ -656,8 +681,7 @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
return ret;
}
- bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
- s->bitmap_directory_size, NULL);
+ bm_list = get_bitmap_list(bs, NULL);
if (bm_list == NULL) {
res->corruptions++;
return -EINVAL;
@@ -707,8 +731,6 @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
}
out:
- bitmap_list_free(bm_list);
-
return ret;
}
@@ -953,8 +975,7 @@ bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, Error **errp)
return false;
}
- bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
- s->bitmap_directory_size, errp);
+ bm_list = get_bitmap_list(bs, errp);
if (bm_list == NULL) {
return false;
}
@@ -992,14 +1013,12 @@ bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, Error **errp)
}
g_slist_free(created_dirty_bitmaps);
- bitmap_list_free(bm_list);
-
return header_updated;
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);
return false;
}
@@ -1027,8 +1046,7 @@ int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs, bool *header_updated,
return -EINVAL;
}
- bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
- s->bitmap_directory_size, errp);
+ bm_list = get_bitmap_list(bs, errp);
if (bm_list == NULL) {
return -EINVAL;
}
@@ -1068,7 +1086,6 @@ int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs, bool *header_updated,
out:
g_slist_free(ro_dirty_bitmaps);
- bitmap_list_free(bm_list);
return ret;
}
@@ -1277,8 +1294,7 @@ void qcow2_remove_persistent_dirty_bitmap(BlockDriverState *bs,
return;
}
- bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
- s->bitmap_directory_size, errp);
+ bm_list = get_bitmap_list(bs, errp);
if (bm_list == NULL) {
return;
}
@@ -1300,7 +1316,11 @@ void qcow2_remove_persistent_dirty_bitmap(BlockDriverState *bs,
fail:
bitmap_free(bm);
- bitmap_list_free(bm_list);
+}
+
+void qcow2_persistent_dirty_bitmaps_cache_destroy(BlockDriverState *bs)
+{
+ del_bitmap_list(bs);
}
void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp)
@@ -1317,12 +1337,12 @@ void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp)
if (!bdrv_has_changed_persistent_bitmaps(bs)) {
/* nothing to do */
- return;
+ goto out;
}
if (!can_write(bs)) {
error_setg(errp, "No write access");
- return;
+ goto out;
}
QSIMPLEQ_INIT(&drop_tables);
@@ -1330,10 +1350,9 @@ void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp)
if (s->nb_bitmaps == 0) {
bm_list = bitmap_list_new();
} else {
- bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
- s->bitmap_directory_size, errp);
+ bm_list = get_bitmap_list(bs, errp);
if (bm_list == NULL) {
- return;
+ goto out;
}
}
@@ -1414,8 +1433,7 @@ void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp)
g_free(tb);
}
- bitmap_list_free(bm_list);
- return;
+ goto out;
fail:
QSIMPLEQ_FOREACH(bm, bm_list, entry) {
@@ -1430,7 +1448,9 @@ fail:
g_free(tb);
}
- bitmap_list_free(bm_list);
+ out:
+ del_bitmap_list(bs);
+ return;
}
int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp)
@@ -1495,14 +1515,12 @@ bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs,
goto fail;
}
- bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
- s->bitmap_directory_size, errp);
+ bm_list = get_bitmap_list(bs, errp);
if (bm_list == NULL) {
goto fail;
}
found = 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)
if (!(s->flags & BDRV_O_INACTIVE)) {
qcow2_inactivate(bs);
+ } else {
+ qcow2_persistent_dirty_bitmaps_cache_destroy(bs);
}
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;
int flags;
int qcow_version;
@@ -675,6 +676,7 @@ bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, Error **errp);
int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs, bool *header_updated,
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 **errp);
int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp);
bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs,
--
2.14.3
next prev parent reply other threads:[~2018-05-12 1:25 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-12 1:25 [Qemu-devel] [RFC PATCH 00/12] qemu-img: add bitmap queries John Snow
2018-05-12 1:25 ` John Snow [this message]
2018-05-14 11:55 ` [Qemu-devel] [RFC PATCH 01/12] qcow2-bitmap: cache bm_list Vladimir Sementsov-Ogievskiy
2018-05-14 12:15 ` Vladimir Sementsov-Ogievskiy
2018-05-15 20:38 ` John Snow
2018-05-15 20:27 ` John Snow
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 02/12] qcow2/dirty-bitmap: cache loaded bitmaps John Snow
2018-05-14 12:33 ` Vladimir Sementsov-Ogievskiy
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 03/12] block/qcow2-bitmap: avoid adjusting bm->flags for RO bitmaps John Snow
2018-05-14 12:44 ` Vladimir Sementsov-Ogievskiy
2018-05-15 20:59 ` John Snow
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 04/12] qcow2/dirty-bitmaps: load IN_USE bitmaps if disk is RO John Snow
2018-05-14 12:55 ` Vladimir Sementsov-Ogievskiy
2018-05-15 20:52 ` John Snow
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 05/12] qcow2-bitmap: track bitmap type John Snow
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 06/12] qapi: add bitmap info John Snow
2018-05-14 14:30 ` Vladimir Sementsov-Ogievskiy
2018-05-15 20:56 ` John Snow
2018-05-16 21:15 ` John Snow
2018-05-17 10:01 ` Vladimir Sementsov-Ogievskiy
2018-05-17 16:43 ` John Snow
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 07/12] qcow2-bitmap: add basic bitmaps info John Snow
2018-05-14 15:12 ` Vladimir Sementsov-Ogievskiy
2018-05-15 21:03 ` John Snow
2018-05-16 21:17 ` John Snow
2018-05-17 10:03 ` Vladimir Sementsov-Ogievskiy
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 08/12] qjson: allow caller to ask for arbitrary indent John Snow
2018-05-16 21:34 ` Eric Blake
2018-05-16 21:49 ` John Snow
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 09/12] qapi/block-core: add BitmapMapping and BitmapEntry structs John Snow
2018-05-16 21:37 ` Eric Blake
2018-05-16 21:55 ` John Snow
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 10/12] qemu-img: split off common chunk of map command John Snow
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 11/12] qemu-img: add bitmap dump John Snow
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 12/12] qemu-img: add bitmap clear John Snow
2018-05-12 1:38 ` [Qemu-devel] [RFC PATCH 00/12] qemu-img: add bitmap queries no-reply
2018-05-14 11:32 ` Vladimir Sementsov-Ogievskiy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180512012537.22478-2-jsnow@redhat.com \
--to=jsnow@redhat.com \
--cc=armbru@redhat.com \
--cc=eblake@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=vsementsov@virtuozzo.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).