Presently, an image with IN_USE bitmaps cannot be loaded as RO. In preparation for changing that, IN_USE bitmaps ought to create an error on reload instead of being skipped.
While we're here, update the function to work with two new facts: - All bm_list entries will have a BdrvDirtyBitmap (because we load and disable bitmaps when the autoload flag isn't set), and - The dirty_bitmap will be cached, so we don't have to look it up. Signed-off-by: John Snow <js...@redhat.com> --- block/qcow2-bitmap.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index d94b6bd5cf..859819639b 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -1046,23 +1046,22 @@ int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs, bool *header_updated, } QSIMPLEQ_FOREACH(bm, bm_list, entry) { - if (!(bm->flags & BME_FLAG_IN_USE)) { - BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(bs, bm->name); - if (bitmap == NULL) { - continue; - } - - if (!bdrv_dirty_bitmap_readonly(bitmap)) { - error_setg(errp, "Bitmap %s is not readonly but not marked" - "'IN_USE' in the image. Something went wrong," - "all the bitmaps may be corrupted", bm->name); - ret = -EINVAL; - goto out; - } - - bm->flags |= BME_FLAG_IN_USE; - ro_dirty_bitmaps = g_slist_append(ro_dirty_bitmaps, bitmap); + if (bm->flags & BME_FLAG_IN_USE) { + error_setg(errp, "Bitmap '%s' is in use; can't reopen RW", + bm->name); + ret = -EINVAL; + goto out; + } else if (!bdrv_dirty_bitmap_readonly(bm->dirty_bitmap)) { + error_setg(errp, "Bitmap %s is neither readonly nor 'IN_USE' in " + "the image. Something went wrong, all the bitmaps may " + "be corrupted. Please report this to the developers at " + " qemu-devel@nongnu.org", bm->name); + ret = -EINVAL; + goto out; } + + bm->flags |= BME_FLAG_IN_USE; + ro_dirty_bitmaps = g_slist_append(ro_dirty_bitmaps, bm->dirty_bitmap); } if (ro_dirty_bitmaps != NULL) { -- 2.14.3