open_failed:
bs->drv = NULL;
if (bs->file != NULL) {
+ bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, bs->file);
+ bdrv_graph_wrunlock();
assert(!bs->file);
}
g_free(bs->opaque);
* @root that point to @root, where necessary.
* @tran is allowed to be NULL. In this case no rollback is possible
*/
-static void bdrv_unset_inherits_from(BlockDriverState *root, BdrvChild *child,
- Transaction *tran)
+static void GRAPH_WRLOCK
+bdrv_unset_inherits_from(BlockDriverState *root, BdrvChild *child,
+ Transaction *tran)
{
BdrvChild *c;
return;
}
- bdrv_graph_wrlock(NULL);
bdrv_unset_inherits_from(parent, child, NULL);
bdrv_root_unref_child(child);
- bdrv_graph_wrunlock();
}
bs->drv = NULL;
}
+ bdrv_graph_wrlock(NULL);
QLIST_FOREACH_SAFE(child, &bs->children, next, next) {
bdrv_unref_child(bs, child);
}
+ bdrv_graph_wrunlock();
assert(!bs->backing);
assert(!bs->file);
ret = 0;
fail_log:
if (ret < 0) {
+ bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, s->log_file);
+ bdrv_graph_wrunlock();
s->log_file = NULL;
}
fail:
{
BDRVBlkLogWritesState *s = bs->opaque;
+ bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, s->log_file);
s->log_file = NULL;
+ bdrv_graph_wrunlock();
}
static int64_t coroutine_fn GRAPH_RDLOCK
{
BDRVBlkverifyState *s = bs->opaque;
+ bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, s->test_file);
s->test_file = NULL;
+ bdrv_graph_wrunlock();
}
static int64_t coroutine_fn GRAPH_RDLOCK
g_free(s->image_data_file);
if (open_data_file && has_data_file(bs)) {
bdrv_graph_co_rdunlock();
- bdrv_unref_child(bs, s->data_file);
+ bdrv_co_unref_child(bs, s->data_file);
bdrv_graph_co_rdlock();
s->data_file = NULL;
}
g_free(s->image_backing_format);
if (close_data_file && has_data_file(bs)) {
+ bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, s->data_file);
+ bdrv_graph_wrunlock();
s->data_file = NULL;
}
close_exit:
/* cleanup on error */
+ bdrv_graph_wrlock(NULL);
for (i = 0; i < s->num_children; i++) {
if (!opened[i]) {
continue;
}
bdrv_unref_child(bs, s->children[i]);
}
+ bdrv_graph_wrunlock();
g_free(s->children);
g_free(opened);
exit:
BDRVQuorumState *s = bs->opaque;
int i;
+ bdrv_graph_wrlock(NULL);
for (i = 0; i < s->num_children; i++) {
bdrv_unref_child(bs, s->children[i]);
}
+ bdrv_graph_wrunlock();
g_free(s->children);
}
memmove(&s->children[i], &s->children[i + 1],
(s->num_children - i - 1) * sizeof(BdrvChild *));
s->children = g_renew(BdrvChild *, s->children, --s->num_children);
+ bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, child);
+ bdrv_graph_wrunlock();
quorum_refresh_flags(bs);
bdrv_drained_end(bs);
if (ret == 0) {
s->stage = BLOCK_REPLICATION_DONE;
+ bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, s->secondary_disk);
s->secondary_disk = NULL;
bdrv_unref_child(bs, s->hidden_disk);
s->hidden_disk = NULL;
+ bdrv_graph_wrunlock();
+
s->error = 0;
} else {
s->stage = BLOCK_REPLICATION_FAILOVER_FAILED;
}
/* .bdrv_open() will re-attach it */
+ bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, fallback);
+ bdrv_graph_wrunlock();
ret = bdrv_snapshot_goto(fallback_bs, snapshot_id, errp);
open_ret = drv->bdrv_open(bs, options, bs->open_flags, &local_err);
BDRVVmdkState *s = bs->opaque;
VmdkExtent *e;
+ bdrv_graph_wrlock(NULL);
for (i = 0; i < s->num_extents; i++) {
e = &s->extents[i];
g_free(e->l1_table);
bdrv_unref_child(bs, e->file);
}
}
+ bdrv_graph_wrunlock();
+
g_free(s->extents);
}
ret = vmdk_add_extent(bs, extent_file, true, sectors,
0, 0, 0, 0, 0, &extent, errp);
if (ret < 0) {
+ bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, extent_file);
+ bdrv_graph_wrunlock();
goto out;
}
extent->flat_start_offset = flat_offset << 9;
}
g_free(buf);
if (ret) {
+ bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, extent_file);
+ bdrv_graph_wrunlock();
goto out;
}
extent = &s->extents[s->num_extents - 1];
} else if (!strcmp(type, "SESPARSE")) {
ret = vmdk_open_se_sparse(bs, extent_file, bs->open_flags, errp);
if (ret) {
+ bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, extent_file);
+ bdrv_graph_wrunlock();
goto out;
}
extent = &s->extents[s->num_extents - 1];
} else {
error_setg(errp, "Unsupported extent type '%s'", type);
+ bdrv_graph_wrlock(NULL);
bdrv_unref_child(bs, extent_file);
+ bdrv_graph_wrunlock();
ret = -ENOTSUP;
goto out;
}
void no_coroutine_fn bdrv_unref(BlockDriverState *bs);
void coroutine_fn no_co_wrapper bdrv_co_unref(BlockDriverState *bs);
void GRAPH_WRLOCK bdrv_schedule_unref(BlockDriverState *bs);
-void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child);
+
+void GRAPH_WRLOCK
+bdrv_unref_child(BlockDriverState *parent, BdrvChild *child);
+
+void coroutine_fn no_co_wrapper_bdrv_wrlock
+bdrv_co_unref_child(BlockDriverState *parent, BdrvChild *child);
BdrvChild * GRAPH_WRLOCK
bdrv_attach_child(BlockDriverState *parent_bs,
static void bdrv_test_top_close(BlockDriverState *bs)
{
BdrvChild *c, *next_c;
+
+ bdrv_graph_wrlock(NULL);
QLIST_FOREACH_SAFE(c, &bs->children, next, next_c) {
bdrv_unref_child(bs, c);
}
+ bdrv_graph_wrunlock();
}
static int coroutine_fn GRAPH_RDLOCK
} else {
BdrvChild *c, *next_c;
QLIST_FOREACH_SAFE(c, &bs->children, next, next_c) {
- bdrv_unref_child(bs, c);
+ bdrv_co_unref_child(bs, c);
}
}
struct detach_by_parent_data *data = opaque;
bdrv_dec_in_flight(data->child_b->bs);
+
+ bdrv_graph_wrlock(NULL);
bdrv_unref_child(data->parent_b, data->child_b);
bdrv_ref(data->c);
- bdrv_graph_wrlock(NULL);
data->child_c = bdrv_attach_child(data->parent_b, data->c, "PB-C",
&child_of_bds, BDRV_CHILD_DATA,
&error_abort);