block: make bdrv_unset_inherits_from to be a transaction action

To be used in the further commit.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20210428151804.439460-27-vsementsov@virtuozzo.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Vladimir Sementsov-Ogievskiy 2021-04-28 18:17:54 +03:00 committed by Kevin Wolf
parent 9397c14fcb
commit 332b3a175f
1 changed files with 42 additions and 4 deletions

46
block.c
View File

@ -3205,11 +3205,49 @@ void bdrv_root_unref_child(BdrvChild *child)
bdrv_unref(child_bs);
}
typedef struct BdrvSetInheritsFrom {
BlockDriverState *bs;
BlockDriverState *old_inherits_from;
} BdrvSetInheritsFrom;
static void bdrv_set_inherits_from_abort(void *opaque)
{
BdrvSetInheritsFrom *s = opaque;
s->bs->inherits_from = s->old_inherits_from;
}
static TransactionActionDrv bdrv_set_inherits_from_drv = {
.abort = bdrv_set_inherits_from_abort,
.clean = g_free,
};
/* @tran is allowed to be NULL. In this case no rollback is possible */
static void bdrv_set_inherits_from(BlockDriverState *bs,
BlockDriverState *new_inherits_from,
Transaction *tran)
{
if (tran) {
BdrvSetInheritsFrom *s = g_new(BdrvSetInheritsFrom, 1);
*s = (BdrvSetInheritsFrom) {
.bs = bs,
.old_inherits_from = bs->inherits_from,
};
tran_add(tran, &bdrv_set_inherits_from_drv, s);
}
bs->inherits_from = new_inherits_from;
}
/**
* Clear all inherits_from pointers from children and grandchildren of
* @root that point to @root, where necessary.
* @tran is allowed to be NULL. In this case no rollback is possible
*/
static void bdrv_unset_inherits_from(BlockDriverState *root, BdrvChild *child)
static void bdrv_unset_inherits_from(BlockDriverState *root, BdrvChild *child,
Transaction *tran)
{
BdrvChild *c;
@ -3224,12 +3262,12 @@ static void bdrv_unset_inherits_from(BlockDriverState *root, BdrvChild *child)
}
}
if (c == NULL) {
child->bs->inherits_from = NULL;
bdrv_set_inherits_from(child->bs, NULL, tran);
}
}
QLIST_FOREACH(c, &child->bs->children, next) {
bdrv_unset_inherits_from(root, c);
bdrv_unset_inherits_from(root, c, tran);
}
}
@ -3240,7 +3278,7 @@ void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child)
return;
}
bdrv_unset_inherits_from(parent, child);
bdrv_unset_inherits_from(parent, child, NULL);
bdrv_root_unref_child(child);
}