From 680e0cc40c5830ebcbfa0bce99bf932e1a4cf6c6 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Fri, 29 Sep 2023 16:51:56 +0200 Subject: [PATCH] block: Protect bs->children with graph_lock Almost all functions that access the child links already take the graph lock now. Add locking to the remaining users and finally annotate the struct field itself as protected by the graph lock. Signed-off-by: Kevin Wolf Message-ID: <20230929145157.45443-22-kwolf@redhat.com> Reviewed-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- block.c | 2 ++ block/replication.c | 3 ++- include/block/block_int-common.h | 4 ++-- tests/unit/test-bdrv-drain.c | 4 ++++ 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/block.c b/block.c index 2ac7406c77..f9cf05ddcf 100644 --- a/block.c +++ b/block.c @@ -2973,6 +2973,8 @@ static void bdrv_child_free(BdrvChild *child) { assert(!child->bs); GLOBAL_STATE_CODE(); + GRAPH_RDLOCK_GUARD_MAINLOOP(); + assert(!child->next.le_prev); /* not in children list */ g_free(child->name); diff --git a/block/replication.c b/block/replication.c index 3459f50669..d522c7396f 100644 --- a/block/replication.c +++ b/block/replication.c @@ -430,7 +430,8 @@ static void backup_job_completed(void *opaque, int ret) backup_job_cleanup(bs); } -static bool check_top_bs(BlockDriverState *top_bs, BlockDriverState *bs) +static bool GRAPH_RDLOCK +check_top_bs(BlockDriverState *top_bs, BlockDriverState *bs) { BdrvChild *child; diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index 0e37acd976..b8d9d24f39 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -1042,7 +1042,7 @@ struct BdrvChild { */ bool quiesced_parent; - QLIST_ENTRY(BdrvChild) next; + QLIST_ENTRY(BdrvChild GRAPH_RDLOCK_PTR) next; QLIST_ENTRY(BdrvChild GRAPH_RDLOCK_PTR) next_parent; }; @@ -1176,7 +1176,7 @@ struct BlockDriverState { * See also comment in include/block/block.h, to learn how backing and file * are connected with BdrvChildRole. */ - QLIST_HEAD(, BdrvChild) children; + QLIST_HEAD(, BdrvChild GRAPH_RDLOCK_PTR) children; BdrvChild *backing; BdrvChild *file; diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c index d734829778..f67e9df01c 100644 --- a/tests/unit/test-bdrv-drain.c +++ b/tests/unit/test-bdrv-drain.c @@ -1034,9 +1034,13 @@ static void coroutine_fn test_co_delete_by_drain(void *opaque) blk_co_unref(blk); } else { BdrvChild *c, *next_c; + bdrv_graph_co_rdlock(); QLIST_FOREACH_SAFE(c, &bs->children, next, next_c) { + bdrv_graph_co_rdunlock(); bdrv_co_unref_child(bs, c); + bdrv_graph_co_rdlock(); } + bdrv_graph_co_rdunlock(); } dbdd->done = true; -- 2.11.4.GIT