From 063dd40e110eba7fffff09850ea9116b8dee2ae6 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Thu, 17 Sep 2015 12:33:26 +0200 Subject: [PATCH] block: Split bdrv_move_feature_fields() After bdrv_swap(), some fields must be moved back to their original BDS to compensate for the effects that a swap of the contents of the objects has while keeping the old addresses. Other fields must be moved back because they should logically be moved and must stay on top When replacing bdrv_swap() with operations changing the pointers in the parents, we only need the latter and must avoid swapping the former. Split the function accordingly. Signed-off-by: Kevin Wolf Reviewed-by: Max Reitz Reviewed-by: Fam Zheng Reviewed-by: Alberto Garcia Reviewed-by: Stefan Hajnoczi --- block.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/block.c b/block.c index a9c7ea600c..a2d6238b82 100644 --- a/block.c +++ b/block.c @@ -1985,6 +1985,8 @@ static void bdrv_rebind(BlockDriverState *bs) } } +/* Fields that need to stay with the top-level BDS, no matter whether the + * address of the top-level BDS stays the same or not. */ static void bdrv_move_feature_fields(BlockDriverState *bs_dest, BlockDriverState *bs_src) { @@ -2020,7 +2022,13 @@ static void bdrv_move_feature_fields(BlockDriverState *bs_dest, /* dirty bitmap */ bs_dest->dirty_bitmaps = bs_src->dirty_bitmaps; +} +/* Fields that only need to be swapped if the contents of BDSes is swapped + * rather than pointers being changed in the parents. */ +static void bdrv_move_reference_fields(BlockDriverState *bs_dest, + BlockDriverState *bs_src) +{ /* reference count */ bs_dest->refcnt = bs_src->refcnt; @@ -2091,6 +2099,10 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old) bdrv_move_feature_fields(bs_old, bs_new); bdrv_move_feature_fields(bs_new, &tmp); + bdrv_move_reference_fields(&tmp, bs_old); + bdrv_move_reference_fields(bs_old, bs_new); + bdrv_move_reference_fields(bs_new, &tmp); + /* bs_new must remain unattached */ assert(!bs_new->blk);