@@ -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;
}