block: adapt bdrv_append() for inserting filters

bdrv_append is not very good for inserting filters: it does extra
permission update as part of bdrv_set_backing_hd(). During this update
filter may conflict with other parents of top_bs.

Instead, let's first do all graph modifications and after it update
permissions.

append-greedy-filter test-case in test-bdrv-graph-mod is now works, so
move it out of debug option.

Note: bdrv_append() is still only works for backing-child based
filters. It's something to improve later.

Note2: we use the fact that bdrv_append() is used to append new nodes,
without backing child, so we don't need frozen check and inherits_from
logic from bdrv_set_backing_hd().

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20210428151804.439460-22-vsementsov@virtuozzo.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Vladimir Sementsov-Ogievskiy 2021-04-28 18:17:49 +03:00 committed by Kevin Wolf
parent 117caba9fc
commit 2272edcfff
2 changed files with 22 additions and 22 deletions

27
block.c
View File

@ -5088,25 +5088,38 @@ int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
* This will modify the BlockDriverState fields, and swap contents
* between bs_new and bs_top. Both bs_new and bs_top are modified.
*
* bs_new must not be attached to a BlockBackend.
* bs_new must not be attached to a BlockBackend and must not have backing
* child.
*
* This function does not create any image files.
*/
int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
Error **errp)
{
int ret = bdrv_set_backing_hd(bs_new, bs_top, errp);
int ret;
Transaction *tran = tran_new();
assert(!bs_new->backing);
ret = bdrv_attach_child_noperm(bs_new, bs_top, "backing",
&child_of_bds, bdrv_backing_role(bs_new),
&bs_new->backing, tran, errp);
if (ret < 0) {
return ret;
goto out;
}
ret = bdrv_replace_node(bs_top, bs_new, errp);
ret = bdrv_replace_node_noperm(bs_top, bs_new, true, tran, errp);
if (ret < 0) {
bdrv_set_backing_hd(bs_new, NULL, &error_abort);
return ret;
goto out;
}
return 0;
ret = bdrv_refresh_perms(bs_new, errp);
out:
tran_finalize(tran, ret);
bdrv_refresh_limits(bs_top, NULL);
return ret;
}
static void bdrv_delete(BlockDriverState *bs)

View File

@ -388,16 +388,6 @@ static void test_append_greedy_filter(void)
int main(int argc, char *argv[])
{
int i;
bool debug = false;
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-d")) {
debug = true;
break;
}
}
bdrv_init();
qemu_init_main_loop(&error_abort);
@ -410,11 +400,8 @@ int main(int argc, char *argv[])
test_parallel_perm_update);
g_test_add_func("/bdrv-graph-mod/parallel-exclusive-write",
test_parallel_exclusive_write);
if (debug) {
g_test_add_func("/bdrv-graph-mod/append-greedy-filter",
test_append_greedy_filter);
}
g_test_add_func("/bdrv-graph-mod/append-greedy-filter",
test_append_greedy_filter);
return g_test_run();
}