mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 00:03: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
|
* Hot add a BDS's child. Used in combination with bdrv_del_child, so the user
|
||||||
* it is broken and take a new child online
|
* 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,
|
void bdrv_add_child(BlockDriverState *parent_bs, BlockDriverState *child_bs,
|
||||||
Error **errp)
|
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);
|
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)
|
void bdrv_del_child(BlockDriverState *parent_bs, BdrvChild *child, Error **errp)
|
||||||
{
|
{
|
||||||
BdrvChild *tmp;
|
BdrvChild *tmp;
|
||||||
|
|
|
@ -1096,10 +1096,8 @@ quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs, Error **errp)
|
||||||
/* We can safely add the child now */
|
/* We can safely add the child now */
|
||||||
bdrv_ref(child_bs);
|
bdrv_ref(child_bs);
|
||||||
|
|
||||||
bdrv_drain_all_begin();
|
|
||||||
child = bdrv_attach_child(bs, child_bs, indexstr, &child_of_bds,
|
child = bdrv_attach_child(bs, child_bs, indexstr, &child_of_bds,
|
||||||
BDRV_CHILD_DATA, errp);
|
BDRV_CHILD_DATA, errp);
|
||||||
bdrv_drain_all_end();
|
|
||||||
if (child == NULL) {
|
if (child == NULL) {
|
||||||
s->next_child_index--;
|
s->next_child_index--;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -3531,6 +3531,7 @@ void qmp_x_blockdev_change(const char *parent, const char *child,
|
||||||
BlockDriverState *parent_bs, *new_bs = NULL;
|
BlockDriverState *parent_bs, *new_bs = NULL;
|
||||||
BdrvChild *p_child;
|
BdrvChild *p_child;
|
||||||
|
|
||||||
|
bdrv_drain_all_begin();
|
||||||
bdrv_graph_wrlock();
|
bdrv_graph_wrlock();
|
||||||
|
|
||||||
parent_bs = bdrv_lookup_bs(parent, parent, errp);
|
parent_bs = bdrv_lookup_bs(parent, parent, errp);
|
||||||
|
@ -3568,6 +3569,7 @@ void qmp_x_blockdev_change(const char *parent, const char *child,
|
||||||
|
|
||||||
out:
|
out:
|
||||||
bdrv_graph_wrunlock();
|
bdrv_graph_wrunlock();
|
||||||
|
bdrv_drain_all_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockJobInfoList *qmp_query_block_jobs(Error **errp)
|
BlockJobInfoList *qmp_query_block_jobs(Error **errp)
|
||||||
|
|
|
@ -396,6 +396,13 @@ struct BlockDriver {
|
||||||
int GRAPH_RDLOCK_PTR (*bdrv_probe_geometry)(
|
int GRAPH_RDLOCK_PTR (*bdrv_probe_geometry)(
|
||||||
BlockDriverState *bs, HDGeometry *geo);
|
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)(
|
void GRAPH_WRLOCK_PTR (*bdrv_add_child)(
|
||||||
BlockDriverState *parent, BlockDriverState *child, Error **errp);
|
BlockDriverState *parent, BlockDriverState *child, Error **errp);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue