Split no-perm part of bdrv_attach_child as separate transaction action. It will be used in later commits.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com> --- block.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 13 deletions(-) diff --git a/block.c b/block.c index b6bdc534d2..d810915684 100644 --- a/block.c +++ b/block.c @@ -85,6 +85,14 @@ static BlockDriverState *bdrv_open_inherit(const char *filename, static void bdrv_replace_child_noperm(BdrvChild *child, BlockDriverState *new_bs); +static int bdrv_attach_child_noperm(BlockDriverState *parent_bs, + BlockDriverState *child_bs, + const char *child_name, + const BdrvChildClass *child_class, + BdrvChildRole child_role, + BdrvChild **child, + Transaction *tran, + Error **errp); static int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue, Error **errp); @@ -3044,6 +3052,40 @@ static int bdrv_attach_child_common(BlockDriverState *child_bs, return 0; } +static int bdrv_attach_child_noperm(BlockDriverState *parent_bs, + BlockDriverState *child_bs, + const char *child_name, + const BdrvChildClass *child_class, + BdrvChildRole child_role, + BdrvChild **child, + Transaction *tran, + Error **errp) +{ + int ret; + uint64_t perm, shared_perm; + + assert(parent_bs->drv); + + bdrv_get_cumulative_perm(parent_bs, &perm, &shared_perm); + bdrv_child_perm(parent_bs, child_bs, NULL, child_role, NULL, + perm, shared_perm, &perm, &shared_perm); + + ret = bdrv_attach_child_common(child_bs, child_name, child_class, + child_role, perm, shared_perm, parent_bs, + child, tran, errp); + if (ret < 0) { + return ret; + } + + QLIST_INSERT_HEAD(&parent_bs->children, *child, next); + /* + * child is removed in bdrv_attach_child_common_abort(), so don't care to + * abort this change separately. + */ + + return 0; +} + static void bdrv_detach_child(BdrvChild *child) { bdrv_replace_child(child, NULL); @@ -3104,23 +3146,26 @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs, BdrvChildRole child_role, Error **errp) { - BdrvChild *child; - uint64_t perm, shared_perm; - - bdrv_get_cumulative_perm(parent_bs, &perm, &shared_perm); + int ret; + BdrvChild *child = NULL; + Transaction *tran = tran_new(); - assert(parent_bs->drv); - bdrv_child_perm(parent_bs, child_bs, NULL, child_role, NULL, - perm, shared_perm, &perm, &shared_perm); + ret = bdrv_attach_child_noperm(parent_bs, child_bs, child_name, child_class, + child_role, &child, tran, errp); + if (ret < 0) { + goto out; + } - child = bdrv_root_attach_child(child_bs, child_name, child_class, - child_role, perm, shared_perm, parent_bs, - errp); - if (child == NULL) { - return NULL; + ret = bdrv_refresh_perms(parent_bs, errp); + if (ret < 0) { + goto out; } - QLIST_INSERT_HEAD(&parent_bs->children, child, next); +out: + tran_finalize(tran, ret); + + bdrv_unref(child_bs); + return child; } -- 2.29.2