[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 1/2] qcow2: Release read-only bitmaps when inactivated
From: |
Eric Blake |
Subject: |
[PULL 1/2] qcow2: Release read-only bitmaps when inactivated |
Date: |
Mon, 3 Aug 2020 09:11:46 -0500 |
From: Max Reitz <mreitz@redhat.com>
During migration, we release all bitmaps after storing them on disk, as
long as they are (1) stored on disk, (2) not read-only, and (3)
consistent.
(2) seems arbitrary, though. The reason we do not release them is
because we do not write them, as there is no need to; and then we just
forget about all bitmaps that we have not written to the file. However,
read-only persistent bitmaps are still in the file and in sync with
their in-memory representation, so we may as well release them just like
any R/W bitmap that we have updated.
It leads to actual problems, too: After migration, letting the source
continue may result in an error if there were any bitmaps on read-only
nodes (such as backing images), because those have not been released by
bdrv_inactive_all(), but bdrv_invalidate_cache_all() attempts to reload
them (which fails, because they are still present in memory).
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20200730120234.49288-2-mreitz@redhat.com>
Tested-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
---
block/qcow2-bitmap.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
index 1f38806ca6ea..8c34b2aef7cd 100644
--- a/block/qcow2-bitmap.c
+++ b/block/qcow2-bitmap.c
@@ -1562,11 +1562,22 @@ void
qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs,
Qcow2Bitmap *bm;
if (!bdrv_dirty_bitmap_get_persistence(bitmap) ||
- bdrv_dirty_bitmap_readonly(bitmap) ||
bdrv_dirty_bitmap_inconsistent(bitmap)) {
continue;
}
+ if (bdrv_dirty_bitmap_readonly(bitmap)) {
+ /*
+ * Store the bitmap in the associated Qcow2Bitmap so it
+ * can be released later
+ */
+ bm = find_bitmap_by_name(bm_list, name);
+ if (bm) {
+ bm->dirty_bitmap = bitmap;
+ }
+ continue;
+ }
+
need_write = true;
if (check_constraints_on_bitmap(bs, name, granularity, errp) < 0) {
@@ -1618,7 +1629,9 @@ void
qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs,
/* allocate clusters and store bitmaps */
QSIMPLEQ_FOREACH(bm, bm_list, entry) {
- if (bm->dirty_bitmap == NULL) {
+ BdrvDirtyBitmap *bitmap = bm->dirty_bitmap;
+
+ if (bitmap == NULL || bdrv_dirty_bitmap_readonly(bitmap)) {
continue;
}
@@ -1641,6 +1654,7 @@ void
qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs,
g_free(tb);
}
+success:
if (release_stored) {
QSIMPLEQ_FOREACH(bm, bm_list, entry) {
if (bm->dirty_bitmap == NULL) {
@@ -1651,13 +1665,14 @@ void
qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs,
}
}
-success:
bitmap_list_free(bm_list);
return;
fail:
QSIMPLEQ_FOREACH(bm, bm_list, entry) {
- if (bm->dirty_bitmap == NULL || bm->table.offset == 0) {
+ if (bm->dirty_bitmap == NULL || bm->table.offset == 0 ||
+ bdrv_dirty_bitmap_readonly(bm->dirty_bitmap))
+ {
continue;
}
--
2.28.0