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 * This will modify the BlockDriverState fields, and swap contents
* between bs_new and bs_top. Both bs_new and bs_top are modified. * 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. * This function does not create any image files.
*/ */
int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top, int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
Error **errp) 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) { 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) { if (ret < 0) {
bdrv_set_backing_hd(bs_new, NULL, &error_abort); goto out;
return ret;
} }
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) 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 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(); bdrv_init();
qemu_init_main_loop(&error_abort); qemu_init_main_loop(&error_abort);
@ -410,11 +400,8 @@ int main(int argc, char *argv[])
test_parallel_perm_update); test_parallel_perm_update);
g_test_add_func("/bdrv-graph-mod/parallel-exclusive-write", g_test_add_func("/bdrv-graph-mod/parallel-exclusive-write",
test_parallel_exclusive_write); test_parallel_exclusive_write);
g_test_add_func("/bdrv-graph-mod/append-greedy-filter",
if (debug) { test_append_greedy_filter);
g_test_add_func("/bdrv-graph-mod/append-greedy-filter",
test_append_greedy_filter);
}
return g_test_run(); return g_test_run();
} }