blk_insert_bs(root, bs, &error_abort);
+ bdrv_graph_wrlock(NULL);
bdrv_attach_child(filter, bs, "child", &child_of_bds,
BDRV_CHILD_DATA, &error_abort);
+ bdrv_graph_wrunlock(NULL);
+ aio_context_acquire(qemu_get_aio_context());
ret = bdrv_append(filter, bs, NULL);
g_assert_cmpint(ret, <, 0);
+ aio_context_release(qemu_get_aio_context());
bdrv_unref(filter);
blk_unref(root);
bdrv_set_backing_hd(target, bs, &error_abort);
+ bdrv_graph_wrlock(NULL);
g_assert(target->backing->bs == bs);
bdrv_attach_child(filter, target, "target", &child_of_bds,
BDRV_CHILD_DATA, &error_abort);
+ bdrv_graph_wrunlock(NULL);
+ aio_context_acquire(qemu_get_aio_context());
bdrv_append(filter, bs, &error_abort);
+ aio_context_release(qemu_get_aio_context());
+
+ bdrv_graph_rdlock_main_loop();
g_assert(target->backing->bs == bs);
+ bdrv_graph_rdunlock_main_loop();
bdrv_unref(filter);
bdrv_unref(bs);
BlockDriverState *fl1 = pass_through_node("fl1");
BlockDriverState *fl2 = pass_through_node("fl2");
+ bdrv_drained_begin(fl1);
+ bdrv_drained_begin(fl2);
+
/*
* bdrv_attach_child() eats child bs reference, so we need two @base
- * references for two filters:
+ * references for two filters. We also need an additional @fl1 reference so
+ * that it still exists when we want to undrain it.
*/
bdrv_ref(base);
+ bdrv_ref(fl1);
+ bdrv_graph_wrlock(NULL);
bdrv_attach_child(top, fl1, "backing", &child_of_bds,
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
&error_abort);
&error_abort);
bdrv_replace_node(fl1, fl2, &error_abort);
+ bdrv_graph_wrunlock(NULL);
+ bdrv_drained_end(fl2);
+ bdrv_drained_end(fl1);
+
+ bdrv_unref(fl1);
bdrv_unref(fl2);
bdrv_unref(top);
}
*/
bdrv_ref(base);
+ bdrv_graph_wrlock(NULL);
bdrv_attach_child(top, ws, "file", &child_of_bds, BDRV_CHILD_DATA,
&error_abort);
c_fl1 = bdrv_attach_child(ws, fl1, "first", &child_of_bds,
bdrv_attach_child(fl2, base, "backing", &child_of_bds,
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
&error_abort);
+ bdrv_graph_wrunlock(NULL);
/* Select fl1 as first child to be active */
s->selected = c_fl1;
+
+ bdrv_graph_rdlock_main_loop();
+
bdrv_child_refresh_perms(top, top->children.lh_first, &error_abort);
assert(c_fl1->perm & BLK_PERM_WRITE);
assert(c_fl1->perm & BLK_PERM_WRITE);
assert(!(c_fl2->perm & BLK_PERM_WRITE));
+ bdrv_graph_rdunlock_main_loop();
bdrv_unref(top);
}
BlockDriverState *base = no_perm_node("base");
BlockDriverState *fl = exclusive_writer_node("fl1");
+ bdrv_graph_wrlock(NULL);
bdrv_attach_child(top, base, "backing", &child_of_bds,
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
&error_abort);
+ bdrv_graph_wrunlock(NULL);
+ aio_context_acquire(qemu_get_aio_context());
bdrv_append(fl, base, &error_abort);
+ aio_context_release(qemu_get_aio_context());
bdrv_unref(fl);
bdrv_unref(top);
}