Skip to content

Commit 35e08b5

Browse files
mhkandakheubaum
authored andcommitted
block: lock AioContext in bdrv_replace_child_noperm() when in non-coroutine context
When called in non-coroutine context, bdrv_replace_child_noperm() needs to grab the AioContext lock because bdrv_parent_drained_begin_single() and bdrv_parent_drained_end_single() rely on AIO_WAIT_WHILE(). This prevents crashes when AIO_WAIT_WHILE() tries to temporarily release the lock. Orabug: 36514180 Signed-off-by: Mark Kanda <mark.kanda@oracle.com> Reviewed-by: Steve Sistare <steven.sistare@oracle.com>
1 parent 6d3d143 commit 35e08b5

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

block.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2832,6 +2832,7 @@ static void bdrv_replace_child_noperm(BdrvChild *child,
28322832
BlockDriverState *old_bs = child->bs;
28332833
int new_bs_quiesce_counter;
28342834
int drain_saldo;
2835+
AioContext *ctx = bdrv_child_get_parent_aio_context(child);
28352836

28362837
assert(!child->frozen);
28372838
assert(old_bs != new_bs);
@@ -2844,6 +2845,10 @@ static void bdrv_replace_child_noperm(BdrvChild *child,
28442845
new_bs_quiesce_counter = (new_bs ? new_bs->quiesce_counter : 0);
28452846
drain_saldo = new_bs_quiesce_counter - child->parent_quiesce_counter;
28462847

2848+
if (ctx != qemu_get_aio_context()) {
2849+
aio_context_acquire(ctx);
2850+
}
2851+
28472852
/*
28482853
* If the new child node is drained but the old one was not, flush
28492854
* all outstanding requests to the old child node.
@@ -2895,6 +2900,10 @@ static void bdrv_replace_child_noperm(BdrvChild *child,
28952900
bdrv_parent_drained_end_single(child);
28962901
drain_saldo++;
28972902
}
2903+
2904+
if (ctx != qemu_get_aio_context()) {
2905+
aio_context_release(ctx);
2906+
}
28982907
}
28992908

29002909
/**

0 commit comments

Comments
 (0)