From cb9ff6c25a25179736b7d8d9ddf00d45e5112a2b Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Wed, 28 Jun 2017 15:05:13 +0300 Subject: [PATCH] block: new bdrv_reopen_bitmaps_rw interface Add format driver handler, which should mark loaded read-only bitmaps as 'IN_USE' in the image and unset read_only field in corresponding BdrvDirtyBitmap's. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: John Snow Reviewed-by: Max Reitz Message-id: 20170628120530.31251-14-vsementsov@virtuozzo.com Signed-off-by: Max Reitz --- block.c | 19 +++++++++++++++++++ include/block/block_int.h | 7 +++++++ 2 files changed, 26 insertions(+) diff --git a/block.c b/block.c index 15a4e75ff5..3ec6624cb7 100644 --- a/block.c +++ b/block.c @@ -2983,12 +2983,16 @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state) { BlockDriver *drv; BlockDriverState *bs; + bool old_can_write, new_can_write; assert(reopen_state != NULL); bs = reopen_state->bs; drv = bs->drv; assert(drv != NULL); + old_can_write = + !bdrv_is_read_only(bs) && !(bdrv_get_flags(bs) & BDRV_O_INACTIVE); + /* If there are any driver level actions to take */ if (drv->bdrv_reopen_commit) { drv->bdrv_reopen_commit(reopen_state); @@ -3002,6 +3006,21 @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state) bs->read_only = !(reopen_state->flags & BDRV_O_RDWR); bdrv_refresh_limits(bs, NULL); + + new_can_write = + !bdrv_is_read_only(bs) && !(bdrv_get_flags(bs) & BDRV_O_INACTIVE); + if (!old_can_write && new_can_write && drv->bdrv_reopen_bitmaps_rw) { + Error *local_err = NULL; + if (drv->bdrv_reopen_bitmaps_rw(bs, &local_err) < 0) { + /* This is not fatal, bitmaps just left read-only, so all following + * writes will fail. User can remove read-only bitmaps to unblock + * writes. + */ + error_reportf_err(local_err, + "%s: Failed to make dirty bitmaps writable: ", + bdrv_get_node_name(bs)); + } + } } /* diff --git a/include/block/block_int.h b/include/block/block_int.h index b9069c514f..254f860972 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -381,6 +381,13 @@ struct BlockDriver { uint64_t parent_perm, uint64_t parent_shared, uint64_t *nperm, uint64_t *nshared); + /** + * Bitmaps should be marked as 'IN_USE' in the image on reopening image + * as rw. This handler should realize it. It also should unset readonly + * field of BlockDirtyBitmap's in case of success. + */ + int (*bdrv_reopen_bitmaps_rw)(BlockDriverState *bs, Error **errp); + QLIST_ENTRY(BlockDriver) list; };