[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v4 29/36] block: bdrv_reopen_multiple(): move bdrv_flush to separ
From: |
Vladimir Sementsov-Ogievskiy |
Subject: |
[PATCH v4 29/36] block: bdrv_reopen_multiple(): move bdrv_flush to separate pre-prepare |
Date: |
Wed, 28 Apr 2021 18:17:57 +0300 |
During reopen we may add backing bs from other aio context, which may
lead to changing original context of top bs.
We are going to move graph modification to prepare stage. So, it will
be possible that bdrv_flush() in bdrv_reopen_prepare called on bs in
non-original aio context, which we didn't aquire which leads to crash.
To avoid this problem move bdrv_flush() to be a separate reopen stage
before bdrv_reopen_prepare().
This doesn't seem correct to acquire only one aio context and not all
contexts participating in reopen. But it's not obvious how to do it
correctly, keeping in mind:
1. rules of bdrv_set_aio_context_ignore() that requires new_context
lock not being held
2. possible deadlocks because of holding all (or several?) AioContext
locks
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/block.c b/block.c
index bdfe59d94d..357ec1be2c 100644
--- a/block.c
+++ b/block.c
@@ -4274,6 +4274,14 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue,
Error **errp)
assert(bs_queue != NULL);
+ QTAILQ_FOREACH(bs_entry, bs_queue, entry) {
+ ret = bdrv_flush(bs_entry->state.bs);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "Error flushing drive");
+ goto cleanup;
+ }
+ }
+
QTAILQ_FOREACH(bs_entry, bs_queue, entry) {
assert(bs_entry->state.bs->quiesce_counter > 0);
if (bdrv_reopen_prepare(&bs_entry->state, bs_queue, errp)) {
@@ -4669,12 +4677,6 @@ static int bdrv_reopen_prepare(BDRVReopenState
*reopen_state,
bdrv_reopen_perm(queue, reopen_state->bs,
&reopen_state->perm, &reopen_state->shared_perm);
- ret = bdrv_flush(reopen_state->bs);
- if (ret) {
- error_setg_errno(errp, -ret, "Error flushing drive");
- goto error;
- }
-
if (drv->bdrv_reopen_prepare) {
/*
* If a driver-specific option is missing, it means that we
--
2.29.2
- [PATCH v4 20/36] block: split out bdrv_replace_node_noperm(), (continued)
- [PATCH v4 20/36] block: split out bdrv_replace_node_noperm(), Vladimir Sementsov-Ogievskiy, 2021/04/28
- [PATCH v4 23/36] block: introduce bdrv_drop_filter(), Vladimir Sementsov-Ogievskiy, 2021/04/28
- [PATCH v4 25/36] block: drop ignore_children for permission update functions, Vladimir Sementsov-Ogievskiy, 2021/04/28
- [PATCH v4 27/36] block: make bdrv_refresh_limits() to be a transaction action, Vladimir Sementsov-Ogievskiy, 2021/04/28
- [PATCH v4 28/36] block: add bdrv_set_backing_noperm() transaction action, Vladimir Sementsov-Ogievskiy, 2021/04/28
- [PATCH v4 26/36] block: make bdrv_unset_inherits_from to be a transaction action, Vladimir Sementsov-Ogievskiy, 2021/04/28
- [PATCH v4 33/36] block: inline bdrv_replace_child(), Vladimir Sementsov-Ogievskiy, 2021/04/28
- [PATCH v4 32/36] block: inline bdrv_check_perm_common(), Vladimir Sementsov-Ogievskiy, 2021/04/28
- [PATCH v4 30/36] block: bdrv_reopen_multiple: refresh permissions on updated graph, Vladimir Sementsov-Ogievskiy, 2021/04/28
- [PATCH v4 34/36] block: refactor bdrv_child_set_perm_safe() transaction action, Vladimir Sementsov-Ogievskiy, 2021/04/28
- [PATCH v4 29/36] block: bdrv_reopen_multiple(): move bdrv_flush to separate pre-prepare,
Vladimir Sementsov-Ogievskiy <=
- [PATCH v4 35/36] block: rename bdrv_replace_child_safe() to bdrv_replace_child(), Vladimir Sementsov-Ogievskiy, 2021/04/28
- [PATCH v4 36/36] block: refactor bdrv_node_check_perm(), Vladimir Sementsov-Ogievskiy, 2021/04/28
- Re: [PATCH v4 00/36] block: update graph permissions update, no-reply, 2021/04/28
- Re: [PATCH v4 00/36] block: update graph permissions update, Kevin Wolf, 2021/04/28