block: Mark bdrv_root_unref_child() GRAPH_WRLOCK
Instead of taking the writer lock internally, require callers to already hold it when calling bdrv_root_unref_child(). These callers will typically already hold the graph lock once the locking work is completed, which means that they can't call functions that take it internally. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Message-ID: <20230911094620.45040-20-kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
7f831d29e3
commit
ede01e4635
6
block.c
6
block.c
@ -3268,7 +3268,6 @@ void bdrv_root_unref_child(BdrvChild *child)
|
|||||||
BlockDriverState *child_bs = child->bs;
|
BlockDriverState *child_bs = child->bs;
|
||||||
|
|
||||||
GLOBAL_STATE_CODE();
|
GLOBAL_STATE_CODE();
|
||||||
bdrv_graph_wrlock(NULL);
|
|
||||||
bdrv_replace_child_noperm(child, NULL);
|
bdrv_replace_child_noperm(child, NULL);
|
||||||
bdrv_child_free(child);
|
bdrv_child_free(child);
|
||||||
|
|
||||||
@ -3288,8 +3287,7 @@ void bdrv_root_unref_child(BdrvChild *child)
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bdrv_graph_wrunlock();
|
bdrv_schedule_unref(child_bs);
|
||||||
bdrv_unref(child_bs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct BdrvSetInheritsFrom {
|
typedef struct BdrvSetInheritsFrom {
|
||||||
@ -3366,8 +3364,10 @@ void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bdrv_graph_wrlock(NULL);
|
||||||
bdrv_unset_inherits_from(parent, child, NULL);
|
bdrv_unset_inherits_from(parent, child, NULL);
|
||||||
bdrv_root_unref_child(child);
|
bdrv_root_unref_child(child);
|
||||||
|
bdrv_graph_wrunlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -915,7 +915,10 @@ void blk_remove_bs(BlockBackend *blk)
|
|||||||
blk_drain(blk);
|
blk_drain(blk);
|
||||||
root = blk->root;
|
root = blk->root;
|
||||||
blk->root = NULL;
|
blk->root = NULL;
|
||||||
|
|
||||||
|
bdrv_graph_wrlock(NULL);
|
||||||
bdrv_root_unref_child(root);
|
bdrv_root_unref_child(root);
|
||||||
|
bdrv_graph_wrunlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -198,6 +198,7 @@ void block_job_remove_all_bdrv(BlockJob *job)
|
|||||||
* one to make sure that such a concurrent access does not attempt
|
* one to make sure that such a concurrent access does not attempt
|
||||||
* to process an already freed BdrvChild.
|
* to process an already freed BdrvChild.
|
||||||
*/
|
*/
|
||||||
|
bdrv_graph_wrlock(NULL);
|
||||||
while (job->nodes) {
|
while (job->nodes) {
|
||||||
GSList *l = job->nodes;
|
GSList *l = job->nodes;
|
||||||
BdrvChild *c = l->data;
|
BdrvChild *c = l->data;
|
||||||
@ -209,6 +210,7 @@ void block_job_remove_all_bdrv(BlockJob *job)
|
|||||||
|
|
||||||
g_slist_free_1(l);
|
g_slist_free_1(l);
|
||||||
}
|
}
|
||||||
|
bdrv_graph_wrunlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool block_job_has_bdrv(BlockJob *job, BlockDriverState *bs)
|
bool block_job_has_bdrv(BlockJob *job, BlockDriverState *bs)
|
||||||
|
@ -202,7 +202,7 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
|
|||||||
BdrvChildRole child_role,
|
BdrvChildRole child_role,
|
||||||
uint64_t perm, uint64_t shared_perm,
|
uint64_t perm, uint64_t shared_perm,
|
||||||
void *opaque, Error **errp);
|
void *opaque, Error **errp);
|
||||||
void bdrv_root_unref_child(BdrvChild *child);
|
void GRAPH_WRLOCK bdrv_root_unref_child(BdrvChild *child);
|
||||||
|
|
||||||
void GRAPH_RDLOCK bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm,
|
void GRAPH_RDLOCK bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm,
|
||||||
uint64_t *shared_perm);
|
uint64_t *shared_perm);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user