block: split out bdrv_replace_node_noperm()

Split part of bdrv_replace_node_common() to be used separately.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20210428151804.439460-21-vsementsov@virtuozzo.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Vladimir Sementsov-Ogievskiy 2021-04-28 18:17:48 +03:00 committed by Kevin Wolf
parent aa5a04c7db
commit 117caba9fc

50
block.c
View file

@ -4991,6 +4991,34 @@ static bool should_update_child(BdrvChild *c, BlockDriverState *to)
return ret;
}
static int bdrv_replace_node_noperm(BlockDriverState *from,
BlockDriverState *to,
bool auto_skip, Transaction *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 -EINVAL;
}
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.
@ -5002,7 +5030,6 @@ static int bdrv_replace_node_common(BlockDriverState *from,
BlockDriverState *to,
bool auto_skip, Error **errp)
{
BdrvChild *c, *next;
Transaction *tran = tran_new();
g_autoptr(GHashTable) found = NULL;
g_autoptr(GSList) refresh_list = NULL;
@ -5022,24 +5049,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;
}
ret = -EINVAL;
error_setg(errp, "Should not change '%s' link to '%s'",
c->name, from->node_name);
goto out;
}
if (c->frozen) {
ret = -EPERM;
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);