Split part of bdrv_replace_node_common() to be used separately. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com> --- block.c | 47 ++++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-)
diff --git a/block.c b/block.c index 5f6ad1d016..1327254b8e 100644 --- a/block.c +++ b/block.c @@ -4859,6 +4859,33 @@ static bool should_update_child(BdrvChild *c, BlockDriverState *to) return ret; } +static int bdrv_replace_node_noperm(BlockDriverState *from, + BlockDriverState *to, + bool auto_skip, GSList **tran, Error **errp) +{ + BdrvChild *c, *next; + + QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) { + assert(c->bs == from); + if (!should_update_child(c, to)) { + if (auto_skip) { + continue; + } + error_setg(errp, "Should not change '%s' link to '%s'", + c->name, from->node_name); + return -EPERM; + } + if (c->frozen) { + error_setg(errp, "Cannot change '%s' link to '%s'", + c->name, from->node_name); + return -EPERM; + } + bdrv_replace_child_safe(c, to, tran); + } + + return 0; +} + /* * With auto_skip=true bdrv_replace_node_common skips updating from parents * if it creates a parent-child relation loop or if parent is block-job. @@ -4871,7 +4898,6 @@ static int bdrv_replace_node_common(BlockDriverState *from, bool auto_skip, Error **errp) { int ret = -EPERM; - BdrvChild *c, *next; GSList *tran = NULL; g_autoptr(GHashTable) found = NULL; g_autoptr(GSList) refresh_list = NULL; @@ -4890,22 +4916,9 @@ static int bdrv_replace_node_common(BlockDriverState *from, * permissions based on new graph. If we fail, we'll roll-back the * replacement. */ - QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) { - assert(c->bs == from); - if (!should_update_child(c, to)) { - if (auto_skip) { - continue; - } - error_setg(errp, "Should not change '%s' link to '%s'", - c->name, from->node_name); - goto out; - } - if (c->frozen) { - error_setg(errp, "Cannot change '%s' link to '%s'", - c->name, from->node_name); - goto out; - } - bdrv_replace_child_safe(c, to, &tran); + ret = bdrv_replace_node_noperm(from, to, auto_skip, &tran, errp); + if (ret < 0) { + goto out; } found = g_hash_table_new(NULL, NULL); -- 2.21.3