mirror of
https://github.com/qemu/qemu.git
synced 2024-11-23 10:53:37 +08:00
block: add bdrv_replace_child_safe() transaction action
To be used in the following commit. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Message-Id: <20210428151804.439460-17-vsementsov@virtuozzo.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
b1d2bbeb3a
commit
0978623e0f
54
block.c
54
block.c
@ -83,6 +83,9 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
|
||||
BdrvChildRole child_role,
|
||||
Error **errp);
|
||||
|
||||
static void bdrv_replace_child_noperm(BdrvChild *child,
|
||||
BlockDriverState *new_bs);
|
||||
|
||||
static int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue
|
||||
*queue, Error **errp);
|
||||
static void bdrv_reopen_commit(BDRVReopenState *reopen_state);
|
||||
@ -2237,6 +2240,57 @@ static int bdrv_drv_set_perm(BlockDriverState *bs, uint64_t perm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct BdrvReplaceChildState {
|
||||
BdrvChild *child;
|
||||
BlockDriverState *old_bs;
|
||||
} BdrvReplaceChildState;
|
||||
|
||||
static void bdrv_replace_child_commit(void *opaque)
|
||||
{
|
||||
BdrvReplaceChildState *s = opaque;
|
||||
|
||||
bdrv_unref(s->old_bs);
|
||||
}
|
||||
|
||||
static void bdrv_replace_child_abort(void *opaque)
|
||||
{
|
||||
BdrvReplaceChildState *s = opaque;
|
||||
BlockDriverState *new_bs = s->child->bs;
|
||||
|
||||
/* old_bs reference is transparently moved from @s to @s->child */
|
||||
bdrv_replace_child_noperm(s->child, s->old_bs);
|
||||
bdrv_unref(new_bs);
|
||||
}
|
||||
|
||||
static TransactionActionDrv bdrv_replace_child_drv = {
|
||||
.commit = bdrv_replace_child_commit,
|
||||
.abort = bdrv_replace_child_abort,
|
||||
.clean = g_free,
|
||||
};
|
||||
|
||||
/*
|
||||
* bdrv_replace_child_safe
|
||||
*
|
||||
* Note: real unref of old_bs is done only on commit.
|
||||
*/
|
||||
__attribute__((unused))
|
||||
static void bdrv_replace_child_safe(BdrvChild *child, BlockDriverState *new_bs,
|
||||
Transaction *tran)
|
||||
{
|
||||
BdrvReplaceChildState *s = g_new(BdrvReplaceChildState, 1);
|
||||
*s = (BdrvReplaceChildState) {
|
||||
.child = child,
|
||||
.old_bs = child->bs,
|
||||
};
|
||||
tran_add(tran, &bdrv_replace_child_drv, s);
|
||||
|
||||
if (new_bs) {
|
||||
bdrv_ref(new_bs);
|
||||
}
|
||||
bdrv_replace_child_noperm(child, new_bs);
|
||||
/* old_bs reference is transparently moved from @child to @s */
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether permissions on this node can be changed in a way that
|
||||
* @cumulative_perms and @cumulative_shared_perms are the new cumulative
|
||||
|
Loading…
Reference in New Issue
Block a user