Skip to content

Commit

Permalink
block: Mark bdrv_recurse_can_replace() and callers GRAPH_RDLOCK
Browse files Browse the repository at this point in the history
This adds GRAPH_RDLOCK annotations to declare that callers of
bdrv_recurse_can_replace() need to hold a reader lock for the graph
because it accesses the children list of a node.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20230504115750.54437-20-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
  • Loading branch information
kevmw committed May 10, 2023
1 parent 4f0bef8 commit 533c6e4
Show file tree
Hide file tree
Showing 7 changed files with 19 additions and 10 deletions.
5 changes: 3 additions & 2 deletions block/blkverify.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,9 @@ static int coroutine_fn GRAPH_RDLOCK blkverify_co_flush(BlockDriverState *bs)
return bdrv_co_flush(s->test_file->bs);
}

static bool blkverify_recurse_can_replace(BlockDriverState *bs,
BlockDriverState *to_replace)
static bool GRAPH_RDLOCK
blkverify_recurse_can_replace(BlockDriverState *bs,
BlockDriverState *to_replace)
{
BDRVBlkverifyState *s = bs->opaque;

Expand Down
4 changes: 4 additions & 0 deletions block/mirror.c
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,10 @@ static int mirror_exit_common(Job *job)
* Cannot use check_to_replace_node() here, because that would
* check for an op blocker on @to_replace, and we have our own
* there.
*
* TODO Pull out the writer lock from bdrv_replace_node() to here
*/
bdrv_graph_rdlock_main_loop();
if (bdrv_recurse_can_replace(src, to_replace)) {
bdrv_replace_node(to_replace, target_bs, &local_err);
} else {
Expand All @@ -756,6 +759,7 @@ static int mirror_exit_common(Job *job)
"would not lead to an abrupt change of visible data",
to_replace->node_name, target_bs->node_name);
}
bdrv_graph_rdunlock_main_loop();
bdrv_drained_end(target_bs);
if (local_err) {
error_report_err(local_err);
Expand Down
4 changes: 2 additions & 2 deletions block/quorum.c
Original file line number Diff line number Diff line change
Expand Up @@ -825,8 +825,8 @@ static coroutine_fn GRAPH_RDLOCK int quorum_co_flush(BlockDriverState *bs)
return result;
}

static bool quorum_recurse_can_replace(BlockDriverState *bs,
BlockDriverState *to_replace)
static bool GRAPH_RDLOCK
quorum_recurse_can_replace(BlockDriverState *bs, BlockDriverState *to_replace)
{
BDRVQuorumState *s = bs->opaque;
int i;
Expand Down
3 changes: 3 additions & 0 deletions blockdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -2961,6 +2961,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
BlockDriverState *unfiltered_bs;
int job_flags = JOB_DEFAULT;

GLOBAL_STATE_CODE();
GRAPH_RDLOCK_GUARD_MAINLOOP();

if (!has_speed) {
speed = 0;
}
Expand Down
5 changes: 3 additions & 2 deletions include/block/block-global-state.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,9 @@ int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts,
Error **errp);

/* check if a named node can be replaced when doing drive-mirror */
BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
const char *node_name, Error **errp);
BlockDriverState * GRAPH_RDLOCK
check_to_replace_node(BlockDriverState *parent_bs, const char *node_name,
Error **errp);

int no_coroutine_fn bdrv_activate(BlockDriverState *bs, Error **errp);

Expand Down
4 changes: 2 additions & 2 deletions include/block/block_int-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,8 @@ struct BlockDriver {
* same data as @bs without it affecting @bs's behavior (that is,
* without it being visible to @bs's parents).
*/
bool (*bdrv_recurse_can_replace)(BlockDriverState *bs,
BlockDriverState *to_replace);
bool GRAPH_RDLOCK_PTR (*bdrv_recurse_can_replace)(
BlockDriverState *bs, BlockDriverState *to_replace);

int (*bdrv_probe_device)(const char *filename);

Expand Down
4 changes: 2 additions & 2 deletions include/block/block_int-global-state.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,8 @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
*/
int bdrv_child_refresh_perms(BlockDriverState *bs, BdrvChild *c, Error **errp);

bool bdrv_recurse_can_replace(BlockDriverState *bs,
BlockDriverState *to_replace);
bool GRAPH_RDLOCK bdrv_recurse_can_replace(BlockDriverState *bs,
BlockDriverState *to_replace);

/*
* Default implementation for BlockDriver.bdrv_child_perm() that can
Expand Down

0 comments on commit 533c6e4

Please sign in to comment.