[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v4 19/45] block: refactor bdrv_list_refresh_perms to allow any li
From: |
Vladimir Sementsov-Ogievskiy |
Subject: |
[PATCH v4 19/45] block: refactor bdrv_list_refresh_perms to allow any list of nodes |
Date: |
Tue, 29 Mar 2022 23:40:41 +0300 |
We are going to increase usage of collecting nodes in a list to then
update, and calling bdrv_topological_dfs() each time is not convenient,
and not correct as we are going to interleave graph modifying with
filling the node list.
So, let's switch to a function that takes any list of nodes, adds all
their subtrees and do topological sort. And finally, refresh
permissions.
While being here, make the function public, as we'll want to use it
from blockdev.c in near future.
Signed-off-by: Vladimir Sementsov-Ogievskiy <v.sementsov-og@mail.ru>
---
block.c | 51 ++++++++++++++++++++++++++++++++-------------------
1 file changed, 32 insertions(+), 19 deletions(-)
diff --git a/block.c b/block.c
index f2b70b81cf..54f1182f10 100644
--- a/block.c
+++ b/block.c
@@ -2406,8 +2406,12 @@ static int bdrv_node_refresh_perm(BlockDriverState *bs,
BlockReopenQueue *q,
return 0;
}
-static int bdrv_list_refresh_perms(GSList *list, BlockReopenQueue *q,
- Transaction *tran, Error **errp)
+/*
+ * @list is a product of bdrv_topological_dfs() (may be called several times) -
+ * a topologically sorted subgraph.
+ */
+static int bdrv_do_refresh_perms(GSList *list, BlockReopenQueue *q,
+ Transaction *tran, Error **errp)
{
int ret;
BlockDriverState *bs;
@@ -2428,6 +2432,24 @@ static int bdrv_list_refresh_perms(GSList *list,
BlockReopenQueue *q,
return 0;
}
+/*
+ * @list is any list of nodes. List is completed by all subtreees and
+ * topologically sorted. It's not a problem if some node occurs in the @list
+ * several times.
+ */
+static int bdrv_list_refresh_perms(GSList *list, BlockReopenQueue *q,
+ Transaction *tran, Error **errp)
+{
+ g_autoptr(GHashTable) found = g_hash_table_new(NULL, NULL);
+ g_autoptr(GSList) refresh_list = NULL;
+
+ for ( ; list; list = list->next) {
+ refresh_list = bdrv_topological_dfs(refresh_list, found, list->data);
+ }
+
+ return bdrv_do_refresh_perms(refresh_list, q, tran, errp);
+}
+
void bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm,
uint64_t *shared_perm)
{
@@ -2485,7 +2507,7 @@ static int bdrv_refresh_perms(BlockDriverState *bs,
Transaction *tran,
tran = local_tran = tran_new();
}
- ret = bdrv_list_refresh_perms(list, NULL, tran, errp);
+ ret = bdrv_do_refresh_perms(list, NULL, tran, errp);
if (local_tran) {
tran_finalize(local_tran, ret);
@@ -4213,7 +4235,6 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue,
Error **errp)
BlockReopenQueueEntry *bs_entry, *next;
AioContext *ctx;
Transaction *tran = tran_new();
- g_autoptr(GHashTable) found = NULL;
g_autoptr(GSList) refresh_list = NULL;
assert(qemu_get_current_aio_context() == qemu_get_aio_context());
@@ -4242,18 +4263,15 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue,
Error **errp)
bs_entry->prepared = true;
}
- found = g_hash_table_new(NULL, NULL);
QTAILQ_FOREACH(bs_entry, bs_queue, entry) {
BDRVReopenState *state = &bs_entry->state;
- refresh_list = bdrv_topological_dfs(refresh_list, found, state->bs);
+ refresh_list = g_slist_prepend(refresh_list, state->bs);
if (state->old_backing_bs) {
- refresh_list = bdrv_topological_dfs(refresh_list, found,
- state->old_backing_bs);
+ refresh_list = g_slist_prepend(refresh_list,
state->old_backing_bs);
}
if (state->old_file_bs) {
- refresh_list = bdrv_topological_dfs(refresh_list, found,
- state->old_file_bs);
+ refresh_list = g_slist_prepend(refresh_list, state->old_file_bs);
}
}
@@ -4959,7 +4977,6 @@ static int bdrv_replace_node_common(BlockDriverState
*from,
Error **errp)
{
Transaction *tran = tran_new();
- g_autoptr(GHashTable) found = NULL;
g_autoptr(GSList) refresh_list = NULL;
BlockDriverState *to_cow_parent = NULL;
int ret;
@@ -4998,10 +5015,8 @@ static int bdrv_replace_node_common(BlockDriverState
*from,
bdrv_remove_child(bdrv_filter_or_cow_child(to_cow_parent), tran);
}
- found = g_hash_table_new(NULL, NULL);
-
- refresh_list = bdrv_topological_dfs(refresh_list, found, to);
- refresh_list = bdrv_topological_dfs(refresh_list, found, from);
+ refresh_list = g_slist_prepend(refresh_list, to);
+ refresh_list = g_slist_prepend(refresh_list, from);
ret = bdrv_list_refresh_perms(refresh_list, NULL, tran, errp);
if (ret < 0) {
@@ -5078,7 +5093,6 @@ int bdrv_replace_child_bs(BdrvChild *child,
BlockDriverState *new_bs,
{
int ret;
Transaction *tran = tran_new();
- g_autoptr(GHashTable) found = NULL;
g_autoptr(GSList) refresh_list = NULL;
BlockDriverState *old_bs = child->bs;
@@ -5088,9 +5102,8 @@ int bdrv_replace_child_bs(BdrvChild *child,
BlockDriverState *new_bs,
bdrv_replace_child_tran(child, new_bs, tran);
- found = g_hash_table_new(NULL, NULL);
- refresh_list = bdrv_topological_dfs(refresh_list, found, old_bs);
- refresh_list = bdrv_topological_dfs(refresh_list, found, new_bs);
+ refresh_list = g_slist_prepend(refresh_list, old_bs);
+ refresh_list = g_slist_prepend(refresh_list, new_bs);
ret = bdrv_list_refresh_perms(refresh_list, NULL, tran, errp);
--
2.35.1
- [PATCH v4 10/45] Revert "block: Let replace_child_tran keep indirect pointer", (continued)
- [PATCH v4 10/45] Revert "block: Let replace_child_tran keep indirect pointer", Vladimir Sementsov-Ogievskiy, 2022/03/29
- [PATCH v4 11/45] Revert "block: Restructure remove_file_or_backing_child()", Vladimir Sementsov-Ogievskiy, 2022/03/29
- [PATCH v4 08/45] block/snapshot: stress that we fallback to primary child, Vladimir Sementsov-Ogievskiy, 2022/03/29
- [PATCH v4 12/45] Revert "block: Pass BdrvChild ** to replace_child_noperm", Vladimir Sementsov-Ogievskiy, 2022/03/29
- [PATCH v4 13/45] block: Manipulate bs->file / bs->backing pointers in .attach/.detach, Vladimir Sementsov-Ogievskiy, 2022/03/29
- [PATCH v4 14/45] block/snapshot: drop indirection around bdrv_snapshot_fallback_ptr, Vladimir Sementsov-Ogievskiy, 2022/03/29
- [PATCH v4 15/45] block: refactor bdrv_remove_file_or_backing_child to bdrv_remove_child, Vladimir Sementsov-Ogievskiy, 2022/03/29
- [PATCH v4 16/45] block: drop bdrv_detach_child(), Vladimir Sementsov-Ogievskiy, 2022/03/29
- [PATCH v4 17/45] block: drop bdrv_remove_filter_or_cow_child, Vladimir Sementsov-Ogievskiy, 2022/03/29
- [PATCH v4 18/45] block: bdrv_refresh_perms(): allow external tran, Vladimir Sementsov-Ogievskiy, 2022/03/29
- [PATCH v4 19/45] block: refactor bdrv_list_refresh_perms to allow any list of nodes,
Vladimir Sementsov-Ogievskiy <=
- [PATCH v4 20/45] block: make permission update functions public, Vladimir Sementsov-Ogievskiy, 2022/03/29
- [PATCH v4 21/45] block: add bdrv_try_set_aio_context_tran transaction action, Vladimir Sementsov-Ogievskiy, 2022/03/29
- [PATCH v4 22/45] block: implemet bdrv_unref_tran(), Vladimir Sementsov-Ogievskiy, 2022/03/29
- [PATCH v4 23/45] blockdev: refactor transaction to use Transaction API, Vladimir Sementsov-Ogievskiy, 2022/03/29
- [PATCH v4 24/45] blockdev: transactions: rename some things, Vladimir Sementsov-Ogievskiy, 2022/03/29
- [PATCH v4 25/45] blockdev: qmp_transaction: refactor loop to classic for, Vladimir Sementsov-Ogievskiy, 2022/03/29
- [PATCH v4 26/45] blockdev: transaction: refactor handling transaction properties, Vladimir Sementsov-Ogievskiy, 2022/03/29
- [PATCH v4 27/45] blockdev: qmp_transaction: drop extra generic layer, Vladimir Sementsov-Ogievskiy, 2022/03/29
- [PATCH v4 29/45] block: introduce BDRV_O_NOPERM flag, Vladimir Sementsov-Ogievskiy, 2022/03/29
- [PATCH v4 28/45] qapi: block: add blockdev-del transaction action, Vladimir Sementsov-Ogievskiy, 2022/03/29