mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 07:13:54 -06:00
block: move drain outside of quorum_add_child()
This is part of resolving the deadlock mentioned in commit "block: move draining out of bdrv_change_aio_context() and mark GRAPH_RDLOCK". The quorum_add_child() callback runs under the graph lock, so it is not allowed to drain. It is only called as the .bdrv_add_child() callback, which is only called in the bdrv_add_child() function, which also runs under the graph lock. The bdrv_add_child() function is called by qmp_x_blockdev_change(), where a drained section is introduced. Signed-off-by: Fiona Ebner <f.ebner@proxmox.com> Message-ID: <20250530151125.955508-15-f.ebner@proxmox.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
77f3965ba7
commit
0414930d3a
4 changed files with 17 additions and 4 deletions
10
block.c
10
block.c
|
@ -8220,8 +8220,10 @@ char *bdrv_dirname(BlockDriverState *bs, Error **errp)
|
|||
}
|
||||
|
||||
/*
|
||||
* Hot add/remove a BDS's child. So the user can take a child offline when
|
||||
* it is broken and take a new child online
|
||||
* Hot add a BDS's child. Used in combination with bdrv_del_child, so the user
|
||||
* can take a child offline when it is broken and take a new child online.
|
||||
*
|
||||
* All block nodes must be drained.
|
||||
*/
|
||||
void bdrv_add_child(BlockDriverState *parent_bs, BlockDriverState *child_bs,
|
||||
Error **errp)
|
||||
|
@ -8261,6 +8263,10 @@ void bdrv_add_child(BlockDriverState *parent_bs, BlockDriverState *child_bs,
|
|||
parent_bs->drv->bdrv_add_child(parent_bs, child_bs, errp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hot remove a BDS's child. Used in combination with bdrv_add_child, so the
|
||||
* user can take a child offline when it is broken and take a new child online.
|
||||
*/
|
||||
void bdrv_del_child(BlockDriverState *parent_bs, BdrvChild *child, Error **errp)
|
||||
{
|
||||
BdrvChild *tmp;
|
||||
|
|
|
@ -1096,10 +1096,8 @@ quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs, Error **errp)
|
|||
/* We can safely add the child now */
|
||||
bdrv_ref(child_bs);
|
||||
|
||||
bdrv_drain_all_begin();
|
||||
child = bdrv_attach_child(bs, child_bs, indexstr, &child_of_bds,
|
||||
BDRV_CHILD_DATA, errp);
|
||||
bdrv_drain_all_end();
|
||||
if (child == NULL) {
|
||||
s->next_child_index--;
|
||||
return;
|
||||
|
|
|
@ -3531,6 +3531,7 @@ void qmp_x_blockdev_change(const char *parent, const char *child,
|
|||
BlockDriverState *parent_bs, *new_bs = NULL;
|
||||
BdrvChild *p_child;
|
||||
|
||||
bdrv_drain_all_begin();
|
||||
bdrv_graph_wrlock();
|
||||
|
||||
parent_bs = bdrv_lookup_bs(parent, parent, errp);
|
||||
|
@ -3568,6 +3569,7 @@ void qmp_x_blockdev_change(const char *parent, const char *child,
|
|||
|
||||
out:
|
||||
bdrv_graph_wrunlock();
|
||||
bdrv_drain_all_end();
|
||||
}
|
||||
|
||||
BlockJobInfoList *qmp_query_block_jobs(Error **errp)
|
||||
|
|
|
@ -396,6 +396,13 @@ struct BlockDriver {
|
|||
int GRAPH_RDLOCK_PTR (*bdrv_probe_geometry)(
|
||||
BlockDriverState *bs, HDGeometry *geo);
|
||||
|
||||
/**
|
||||
* Hot add a BDS's child. Used in combination with bdrv_del_child, so the
|
||||
* user can take a child offline when it is broken and take a new child
|
||||
* online.
|
||||
*
|
||||
* All block nodes must be drained.
|
||||
*/
|
||||
void GRAPH_WRLOCK_PTR (*bdrv_add_child)(
|
||||
BlockDriverState *parent, BlockDriverState *child, Error **errp);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue