mirror of https://github.com/xemu-project/xemu.git
block: add bdrv_remove_filter_or_cow transaction action
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Message-Id: <20210428151804.439460-23-vsementsov@virtuozzo.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
2272edcfff
commit
46541ee579
84
block.c
84
block.c
|
@ -2963,12 +2963,19 @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bdrv_child_free(void *opaque)
|
||||||
|
{
|
||||||
|
BdrvChild *c = opaque;
|
||||||
|
|
||||||
|
g_free(c->name);
|
||||||
|
g_free(c);
|
||||||
|
}
|
||||||
|
|
||||||
static void bdrv_remove_empty_child(BdrvChild *child)
|
static void bdrv_remove_empty_child(BdrvChild *child)
|
||||||
{
|
{
|
||||||
assert(!child->bs);
|
assert(!child->bs);
|
||||||
QLIST_SAFE_REMOVE(child, next);
|
QLIST_SAFE_REMOVE(child, next);
|
||||||
g_free(child->name);
|
bdrv_child_free(child);
|
||||||
g_free(child);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct BdrvAttachChildCommonState {
|
typedef struct BdrvAttachChildCommonState {
|
||||||
|
@ -4991,6 +4998,79 @@ static bool should_update_child(BdrvChild *c, BlockDriverState *to)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct BdrvRemoveFilterOrCowChild {
|
||||||
|
BdrvChild *child;
|
||||||
|
bool is_backing;
|
||||||
|
} BdrvRemoveFilterOrCowChild;
|
||||||
|
|
||||||
|
static void bdrv_remove_filter_or_cow_child_abort(void *opaque)
|
||||||
|
{
|
||||||
|
BdrvRemoveFilterOrCowChild *s = opaque;
|
||||||
|
BlockDriverState *parent_bs = s->child->opaque;
|
||||||
|
|
||||||
|
QLIST_INSERT_HEAD(&parent_bs->children, s->child, next);
|
||||||
|
if (s->is_backing) {
|
||||||
|
parent_bs->backing = s->child;
|
||||||
|
} else {
|
||||||
|
parent_bs->file = s->child;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We don't have to restore child->bs here to undo bdrv_replace_child()
|
||||||
|
* because that function is transactionable and it registered own completion
|
||||||
|
* entries in @tran, so .abort() for bdrv_replace_child_safe() will be
|
||||||
|
* called automatically.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bdrv_remove_filter_or_cow_child_commit(void *opaque)
|
||||||
|
{
|
||||||
|
BdrvRemoveFilterOrCowChild *s = opaque;
|
||||||
|
|
||||||
|
bdrv_child_free(s->child);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TransactionActionDrv bdrv_remove_filter_or_cow_child_drv = {
|
||||||
|
.abort = bdrv_remove_filter_or_cow_child_abort,
|
||||||
|
.commit = bdrv_remove_filter_or_cow_child_commit,
|
||||||
|
.clean = g_free,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A function to remove backing-chain child of @bs if exists: cow child for
|
||||||
|
* format nodes (always .backing) and filter child for filters (may be .file or
|
||||||
|
* .backing)
|
||||||
|
*/
|
||||||
|
__attribute__((unused))
|
||||||
|
static void bdrv_remove_filter_or_cow_child(BlockDriverState *bs,
|
||||||
|
Transaction *tran)
|
||||||
|
{
|
||||||
|
BdrvRemoveFilterOrCowChild *s;
|
||||||
|
BdrvChild *child = bdrv_filter_or_cow_child(bs);
|
||||||
|
|
||||||
|
if (!child) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child->bs) {
|
||||||
|
bdrv_replace_child_safe(child, NULL, tran);
|
||||||
|
}
|
||||||
|
|
||||||
|
s = g_new(BdrvRemoveFilterOrCowChild, 1);
|
||||||
|
*s = (BdrvRemoveFilterOrCowChild) {
|
||||||
|
.child = child,
|
||||||
|
.is_backing = (child == bs->backing),
|
||||||
|
};
|
||||||
|
tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, s);
|
||||||
|
|
||||||
|
QLIST_SAFE_REMOVE(child, next);
|
||||||
|
if (s->is_backing) {
|
||||||
|
bs->backing = NULL;
|
||||||
|
} else {
|
||||||
|
bs->file = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int bdrv_replace_node_noperm(BlockDriverState *from,
|
static int bdrv_replace_node_noperm(BlockDriverState *from,
|
||||||
BlockDriverState *to,
|
BlockDriverState *to,
|
||||||
bool auto_skip, Transaction *tran,
|
bool auto_skip, Transaction *tran,
|
||||||
|
|
Loading…
Reference in New Issue