mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'for-upstream' of https://repo.or.cz/qemu/kevin into staging
Block layer patches
- Clean up coroutine versions of bdrv_{is_allocated,block_status}*
- Graph locking part 5 (protect children/parent links)
# -----BEGIN PGP SIGNATURE-----
#
# iQJFBAABCAAvFiEE3D3rFZqa+V09dFb+fwmycsiPL9YFAmUoHL8RHGt3b2xmQHJl
# ZGhhdC5jb20ACgkQfwmycsiPL9b4uRAAjryVAaA5jXZ3mdGB80nhGtARZlIaIVO/
# tlXk065q2Cj+98f+fBPCPWvmEz28vJwBhJUsFwpHzLZrxecBpwZp0MPAkFBNkouq
# +AiO9xyTAqccEp/dnIys4Bun9Rp0Jq9lk9y29zzEmQuK5uCB56lpx2cDn/JkzSQt
# ZFtnxxTwi3MDTNvXATub8Ia/1suui0zvESS7J/NBxQNI3cFaQszp1vMwlRIoPiWo
# 15YZFPZZQ2pvu6/1nL1Vl9OLbPAVcEGJpjHZv0XhudYOwRiDvjYnwfPL7BuwYEsU
# Dos4mZZd/KMU695s7OzlVYi1q4ATKUTUxyyylVhXZrFBXSE5ntnfoHTKHEruTyPb
# G31h5mribSTWjdvY5HewHbSSPjByAWsSQg9yzcHybhORiqGQCpcGQ8zuW7oNKMPV
# JicWdoRVY4U4hR0nRdDxz9zdpQ8QYok/ginBxFaOzrCfClUB7ZOBxwRMclIghuRH
# FV+ZJk0ylVOz2tbfNxUa3KhUgTPd8jgCHFI7xak5EBRtTJiJjE03Xag1Fdxy5/D5
# tRsBBW4sOFygAhjN/xyeaRv9L8rAv3x/akriFjPUbOMLkPcJpe/DTWsP8+5LaZF8
# GkQvjsg5UvmfcJ3LFtecXxfYH4UWhDmyAjF+BswiRqafDDi2CCUmdwDnzEPbwuWO
# x1y7cgxe9SE=
# =4d/s
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 12 Oct 2023 12:20:15 EDT
# gpg: using RSA key DC3DEB159A9AF95D3D7456FE7F09B272C88F2FD6
# gpg: issuer "kwolf@redhat.com"
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full]
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6
* tag 'for-upstream' of https://repo.or.cz/qemu/kevin: (26 commits)
block: Add assertion for bdrv_graph_wrlock()
block: Protect bs->children with graph_lock
block: Protect bs->parents with graph_lock
block: Mark bdrv_get_specific_info() and callers GRAPH_RDLOCK
block: Mark bdrv_apply_auto_read_only() and callers GRAPH_RDLOCK
block: Mark bdrv_op_is_blocked() and callers GRAPH_RDLOCK
qcow2: Mark check_constraints_on_bitmap() GRAPH_RDLOCK
qcow2: Mark qcow2_inactivate() and callers GRAPH_RDLOCK
qcow2: Mark qcow2_signal_corruption() and callers GRAPH_RDLOCK
block: Mark bdrv_amend_options() and callers GRAPH_RDLOCK
block: Mark bdrv_get_parent_name() and callers GRAPH_RDLOCK
block: Mark bdrv_primary_child() and callers GRAPH_RDLOCK
block: Mark bdrv_refresh_filename() and callers GRAPH_RDLOCK
block: Mark bdrv_get_xdbg_block_graph() and callers GRAPH_RDLOCK
block: Take graph rdlock in parts of reopen
block: Mark bdrv_snapshot_fallback() and callers GRAPH_RDLOCK
block: Mark bdrv_parent_cb_resize() and callers GRAPH_RDLOCK
block: Mark drain related functions GRAPH_RDLOCK
block: Mark bdrv_first_blk() and bdrv_is_root_node() GRAPH_RDLOCK
block: Take graph rdlock in bdrv_inactivate_all()
...
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
@@ -279,8 +279,9 @@ bool bdrv_is_read_only(BlockDriverState *bs)
|
||||
return !(bs->open_flags & BDRV_O_RDWR);
|
||||
}
|
||||
|
||||
static int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
|
||||
bool ignore_allow_rdw, Error **errp)
|
||||
static int GRAPH_RDLOCK
|
||||
bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
|
||||
bool ignore_allow_rdw, Error **errp)
|
||||
{
|
||||
IO_CODE();
|
||||
|
||||
@@ -371,8 +372,9 @@ char *bdrv_get_full_backing_filename_from_filename(const char *backed,
|
||||
* setting @errp. In all other cases, NULL will only be returned with
|
||||
* @errp set.
|
||||
*/
|
||||
static char *bdrv_make_absolute_filename(BlockDriverState *relative_to,
|
||||
const char *filename, Error **errp)
|
||||
static char * GRAPH_RDLOCK
|
||||
bdrv_make_absolute_filename(BlockDriverState *relative_to,
|
||||
const char *filename, Error **errp)
|
||||
{
|
||||
char *dir, *full_name;
|
||||
|
||||
@@ -1192,19 +1194,19 @@ static char *bdrv_child_get_parent_desc(BdrvChild *c)
|
||||
return g_strdup_printf("node '%s'", bdrv_get_node_name(parent));
|
||||
}
|
||||
|
||||
static void bdrv_child_cb_drained_begin(BdrvChild *child)
|
||||
static void GRAPH_RDLOCK bdrv_child_cb_drained_begin(BdrvChild *child)
|
||||
{
|
||||
BlockDriverState *bs = child->opaque;
|
||||
bdrv_do_drained_begin_quiesce(bs, NULL);
|
||||
}
|
||||
|
||||
static bool bdrv_child_cb_drained_poll(BdrvChild *child)
|
||||
static bool GRAPH_RDLOCK bdrv_child_cb_drained_poll(BdrvChild *child)
|
||||
{
|
||||
BlockDriverState *bs = child->opaque;
|
||||
return bdrv_drain_poll(bs, NULL, false);
|
||||
}
|
||||
|
||||
static void bdrv_child_cb_drained_end(BdrvChild *child)
|
||||
static void GRAPH_RDLOCK bdrv_child_cb_drained_end(BdrvChild *child)
|
||||
{
|
||||
BlockDriverState *bs = child->opaque;
|
||||
bdrv_drained_end(bs);
|
||||
@@ -1250,7 +1252,7 @@ static void bdrv_temp_snapshot_options(int *child_flags, QDict *child_options,
|
||||
*child_flags &= ~BDRV_O_NATIVE_AIO;
|
||||
}
|
||||
|
||||
static void bdrv_backing_attach(BdrvChild *c)
|
||||
static void GRAPH_WRLOCK bdrv_backing_attach(BdrvChild *c)
|
||||
{
|
||||
BlockDriverState *parent = c->opaque;
|
||||
BlockDriverState *backing_hd = c->bs;
|
||||
@@ -1874,7 +1876,10 @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
|
||||
}
|
||||
|
||||
if (file != NULL) {
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
bdrv_refresh_filename(blk_bs(file));
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
|
||||
filename = blk_bs(file)->filename;
|
||||
} else {
|
||||
/*
|
||||
@@ -1901,7 +1906,9 @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
|
||||
|
||||
if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv, ro)) {
|
||||
if (!ro && bdrv_is_whitelisted(drv, true)) {
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
ret = bdrv_apply_auto_read_only(bs, NULL, NULL);
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
} else {
|
||||
ret = -ENOTSUP;
|
||||
}
|
||||
@@ -2966,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);
|
||||
@@ -3644,7 +3653,10 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
|
||||
implicit_backing = !strcmp(bs->auto_backing_file, bs->backing_file);
|
||||
}
|
||||
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
backing_filename = bdrv_get_full_backing_filename(bs, &local_err);
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
|
||||
if (local_err) {
|
||||
ret = -EINVAL;
|
||||
error_propagate(errp, local_err);
|
||||
@@ -3675,7 +3687,9 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
|
||||
}
|
||||
|
||||
if (implicit_backing) {
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
bdrv_refresh_filename(backing_hd);
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
pstrcpy(bs->auto_backing_file, sizeof(bs->auto_backing_file),
|
||||
backing_hd->filename);
|
||||
}
|
||||
@@ -4314,8 +4328,8 @@ static int bdrv_reset_options_allowed(BlockDriverState *bs,
|
||||
/*
|
||||
* Returns true if @child can be reached recursively from @bs
|
||||
*/
|
||||
static bool bdrv_recurse_has_child(BlockDriverState *bs,
|
||||
BlockDriverState *child)
|
||||
static bool GRAPH_RDLOCK
|
||||
bdrv_recurse_has_child(BlockDriverState *bs, BlockDriverState *child)
|
||||
{
|
||||
BdrvChild *c;
|
||||
|
||||
@@ -4356,15 +4370,12 @@ static bool bdrv_recurse_has_child(BlockDriverState *bs,
|
||||
*
|
||||
* To be called with bs->aio_context locked.
|
||||
*/
|
||||
static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
|
||||
BlockDriverState *bs,
|
||||
QDict *options,
|
||||
const BdrvChildClass *klass,
|
||||
BdrvChildRole role,
|
||||
bool parent_is_format,
|
||||
QDict *parent_options,
|
||||
int parent_flags,
|
||||
bool keep_old_opts)
|
||||
static BlockReopenQueue * GRAPH_RDLOCK
|
||||
bdrv_reopen_queue_child(BlockReopenQueue *bs_queue, BlockDriverState *bs,
|
||||
QDict *options, const BdrvChildClass *klass,
|
||||
BdrvChildRole role, bool parent_is_format,
|
||||
QDict *parent_options, int parent_flags,
|
||||
bool keep_old_opts)
|
||||
{
|
||||
assert(bs != NULL);
|
||||
|
||||
@@ -4376,6 +4387,11 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
|
||||
/*
|
||||
* Strictly speaking, draining is illegal under GRAPH_RDLOCK. We know that
|
||||
* we've been called with bdrv_graph_rdlock_main_loop(), though, so it's ok
|
||||
* in practice.
|
||||
*/
|
||||
bdrv_drained_begin(bs);
|
||||
|
||||
if (bs_queue == NULL) {
|
||||
@@ -4517,6 +4533,7 @@ BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
|
||||
QDict *options, bool keep_old_opts)
|
||||
{
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
return bdrv_reopen_queue_child(bs_queue, bs, options, NULL, 0, false,
|
||||
NULL, 0, keep_old_opts);
|
||||
@@ -4736,9 +4753,10 @@ int bdrv_reopen_set_read_only(BlockDriverState *bs, bool read_only,
|
||||
* Callers must make sure that their AioContext locking is still correct after
|
||||
* this.
|
||||
*/
|
||||
static int bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state,
|
||||
bool is_backing, Transaction *tran,
|
||||
Error **errp)
|
||||
static int GRAPH_UNLOCKED
|
||||
bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state,
|
||||
bool is_backing, Transaction *tran,
|
||||
Error **errp)
|
||||
{
|
||||
BlockDriverState *bs = reopen_state->bs;
|
||||
BlockDriverState *new_child_bs;
|
||||
@@ -4748,6 +4766,7 @@ static int bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state,
|
||||
QObject *value;
|
||||
const char *str;
|
||||
AioContext *ctx, *old_ctx;
|
||||
bool has_child;
|
||||
int ret;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
@@ -4767,7 +4786,13 @@ static int bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state,
|
||||
new_child_bs = bdrv_lookup_bs(NULL, str, errp);
|
||||
if (new_child_bs == NULL) {
|
||||
return -EINVAL;
|
||||
} else if (bdrv_recurse_has_child(new_child_bs, bs)) {
|
||||
}
|
||||
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
has_child = bdrv_recurse_has_child(new_child_bs, bs);
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
|
||||
if (has_child) {
|
||||
error_setg(errp, "Making '%s' a %s child of '%s' would create a "
|
||||
"cycle", str, child_name, bs->node_name);
|
||||
return -EINVAL;
|
||||
@@ -4866,9 +4891,9 @@ static int bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state,
|
||||
* After calling this function, the transaction @change_child_tran may only be
|
||||
* completed while holding a writer lock for the graph.
|
||||
*/
|
||||
static int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
|
||||
BlockReopenQueue *queue,
|
||||
Transaction *change_child_tran, Error **errp)
|
||||
static int GRAPH_UNLOCKED
|
||||
bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
|
||||
Transaction *change_child_tran, Error **errp)
|
||||
{
|
||||
int ret = -1;
|
||||
int old_flags;
|
||||
@@ -4930,7 +4955,10 @@ static int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
|
||||
* to r/w. Attempting to set to r/w may fail if either BDRV_O_ALLOW_RDWR is
|
||||
* not set, or if the BDS still has copy_on_read enabled */
|
||||
read_only = !(reopen_state->flags & BDRV_O_RDWR);
|
||||
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
ret = bdrv_can_set_read_only(reopen_state->bs, read_only, true, &local_err);
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
goto error;
|
||||
@@ -4953,7 +4981,9 @@ static int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
|
||||
if (local_err != NULL) {
|
||||
error_propagate(errp, local_err);
|
||||
} else {
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
bdrv_refresh_filename(reopen_state->bs);
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
error_setg(errp, "failed while preparing to reopen image '%s'",
|
||||
reopen_state->bs->filename);
|
||||
}
|
||||
@@ -4962,9 +4992,11 @@ static int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
|
||||
} else {
|
||||
/* It is currently mandatory to have a bdrv_reopen_prepare()
|
||||
* handler for each supported drv. */
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
error_setg(errp, "Block format '%s' used by node '%s' "
|
||||
"does not support reopening files", drv->format_name,
|
||||
bdrv_get_device_or_node_name(reopen_state->bs));
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
ret = -1;
|
||||
goto error;
|
||||
}
|
||||
@@ -5010,6 +5042,8 @@ static int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
|
||||
if (qdict_size(reopen_state->options)) {
|
||||
const QDictEntry *entry = qdict_first(reopen_state->options);
|
||||
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
do {
|
||||
QObject *new = entry->value;
|
||||
QObject *old = qdict_get(reopen_state->bs->options, entry->key);
|
||||
@@ -5083,7 +5117,7 @@ error:
|
||||
* makes them final by swapping the staging BlockDriverState contents into
|
||||
* the active BlockDriverState contents.
|
||||
*/
|
||||
static void bdrv_reopen_commit(BDRVReopenState *reopen_state)
|
||||
static void GRAPH_UNLOCKED bdrv_reopen_commit(BDRVReopenState *reopen_state)
|
||||
{
|
||||
BlockDriver *drv;
|
||||
BlockDriverState *bs;
|
||||
@@ -5100,6 +5134,8 @@ static void bdrv_reopen_commit(BDRVReopenState *reopen_state)
|
||||
drv->bdrv_reopen_commit(reopen_state);
|
||||
}
|
||||
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
/* set BDS specific flags now */
|
||||
qobject_unref(bs->explicit_options);
|
||||
qobject_unref(bs->options);
|
||||
@@ -5121,9 +5157,7 @@ static void bdrv_reopen_commit(BDRVReopenState *reopen_state)
|
||||
qdict_del(bs->explicit_options, "backing");
|
||||
qdict_del(bs->options, "backing");
|
||||
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
bdrv_refresh_limits(bs, NULL, NULL);
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
bdrv_refresh_total_sectors(bs, bs->total_sectors);
|
||||
}
|
||||
|
||||
@@ -5131,7 +5165,7 @@ static void bdrv_reopen_commit(BDRVReopenState *reopen_state)
|
||||
* Abort the reopen, and delete and free the staged changes in
|
||||
* reopen_state
|
||||
*/
|
||||
static void bdrv_reopen_abort(BDRVReopenState *reopen_state)
|
||||
static void GRAPH_UNLOCKED bdrv_reopen_abort(BDRVReopenState *reopen_state)
|
||||
{
|
||||
BlockDriver *drv;
|
||||
|
||||
@@ -5918,6 +5952,7 @@ int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
|
||||
|
||||
bdrv_ref(top);
|
||||
bdrv_drained_begin(base);
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
|
||||
if (!top->drv || !base->drv) {
|
||||
goto exit;
|
||||
@@ -5942,11 +5977,9 @@ int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
|
||||
backing_file_str = base->filename;
|
||||
}
|
||||
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
QLIST_FOREACH(c, &top->parents, next_parent) {
|
||||
updated_children = g_slist_prepend(updated_children, c);
|
||||
}
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
|
||||
/*
|
||||
* It seems correct to pass detach_subchain=true here, but it triggers
|
||||
@@ -5992,6 +6025,7 @@ int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
|
||||
|
||||
ret = 0;
|
||||
exit:
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
bdrv_drained_end(base);
|
||||
bdrv_unref(top);
|
||||
return ret;
|
||||
@@ -6282,6 +6316,7 @@ BlockDeviceInfoList *bdrv_named_nodes_list(bool flat,
|
||||
BlockDriverState *bs;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
list = NULL;
|
||||
QTAILQ_FOREACH(bs, &graph_bdrv_states, node_list) {
|
||||
@@ -6667,7 +6702,8 @@ void coroutine_fn bdrv_co_debug_event(BlockDriverState *bs, BlkdebugEvent event)
|
||||
bs->drv->bdrv_co_debug_event(bs, event);
|
||||
}
|
||||
|
||||
static BlockDriverState *bdrv_find_debug_node(BlockDriverState *bs)
|
||||
static BlockDriverState * GRAPH_RDLOCK
|
||||
bdrv_find_debug_node(BlockDriverState *bs)
|
||||
{
|
||||
GLOBAL_STATE_CODE();
|
||||
while (bs && bs->drv && !bs->drv->bdrv_debug_breakpoint) {
|
||||
@@ -6686,6 +6722,8 @@ int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
|
||||
const char *tag)
|
||||
{
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
bs = bdrv_find_debug_node(bs);
|
||||
if (bs) {
|
||||
return bs->drv->bdrv_debug_breakpoint(bs, event, tag);
|
||||
@@ -6697,6 +6735,8 @@ int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
|
||||
int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag)
|
||||
{
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
bs = bdrv_find_debug_node(bs);
|
||||
if (bs) {
|
||||
return bs->drv->bdrv_debug_remove_breakpoint(bs, tag);
|
||||
@@ -6708,6 +6748,8 @@ int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag)
|
||||
int bdrv_debug_resume(BlockDriverState *bs, const char *tag)
|
||||
{
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
while (bs && (!bs->drv || !bs->drv->bdrv_debug_resume)) {
|
||||
bs = bdrv_primary_bs(bs);
|
||||
}
|
||||
@@ -6722,6 +6764,8 @@ int bdrv_debug_resume(BlockDriverState *bs, const char *tag)
|
||||
bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag)
|
||||
{
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
while (bs && bs->drv && !bs->drv->bdrv_debug_is_suspended) {
|
||||
bs = bdrv_primary_bs(bs);
|
||||
}
|
||||
@@ -6750,6 +6794,7 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
|
||||
BlockDriverState *bs_below;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
if (!bs || !bs->drv || !backing_file) {
|
||||
return NULL;
|
||||
@@ -6961,6 +7006,7 @@ void bdrv_activate_all(Error **errp)
|
||||
BdrvNextIterator it;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
|
||||
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||
@@ -6976,7 +7022,8 @@ void bdrv_activate_all(Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
static bool bdrv_has_bds_parent(BlockDriverState *bs, bool only_active)
|
||||
static bool GRAPH_RDLOCK
|
||||
bdrv_has_bds_parent(BlockDriverState *bs, bool only_active)
|
||||
{
|
||||
BdrvChild *parent;
|
||||
GLOBAL_STATE_CODE();
|
||||
@@ -6993,14 +7040,13 @@ static bool bdrv_has_bds_parent(BlockDriverState *bs, bool only_active)
|
||||
return false;
|
||||
}
|
||||
|
||||
static int bdrv_inactivate_recurse(BlockDriverState *bs)
|
||||
static int GRAPH_RDLOCK bdrv_inactivate_recurse(BlockDriverState *bs)
|
||||
{
|
||||
BdrvChild *child, *parent;
|
||||
int ret;
|
||||
uint64_t cumulative_perms, cumulative_shared_perms;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
if (!bs->drv) {
|
||||
return -ENOMEDIUM;
|
||||
@@ -7066,6 +7112,7 @@ int bdrv_inactivate_all(void)
|
||||
GSList *aio_ctxs = NULL, *ctx;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
|
||||
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||
@@ -7205,6 +7252,7 @@ bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp)
|
||||
{
|
||||
BdrvOpBlocker *blocker;
|
||||
GLOBAL_STATE_CODE();
|
||||
|
||||
assert((int) op >= 0 && op < BLOCK_OP_TYPE_MAX);
|
||||
if (!QLIST_EMPTY(&bs->op_blockers[op])) {
|
||||
blocker = QLIST_FIRST(&bs->op_blockers[op]);
|
||||
|
||||
@@ -374,6 +374,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
|
||||
assert(bs);
|
||||
assert(target);
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
/* QMP interface protects us from these cases */
|
||||
assert(sync_mode != MIRROR_SYNC_MODE_INCREMENTAL);
|
||||
|
||||
@@ -780,11 +780,12 @@ BlockDriverState *blk_bs(BlockBackend *blk)
|
||||
return blk->root ? blk->root->bs : NULL;
|
||||
}
|
||||
|
||||
static BlockBackend *bdrv_first_blk(BlockDriverState *bs)
|
||||
static BlockBackend * GRAPH_RDLOCK bdrv_first_blk(BlockDriverState *bs)
|
||||
{
|
||||
BdrvChild *child;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
assert_bdrv_graph_readable();
|
||||
|
||||
QLIST_FOREACH(child, &bs->parents, next_parent) {
|
||||
if (child->klass == &child_root) {
|
||||
@@ -812,6 +813,8 @@ bool bdrv_is_root_node(BlockDriverState *bs)
|
||||
BdrvChild *c;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
assert_bdrv_graph_readable();
|
||||
|
||||
QLIST_FOREACH(c, &bs->parents, next_parent) {
|
||||
if (c->klass != &child_root) {
|
||||
return false;
|
||||
@@ -2259,6 +2262,7 @@ void blk_activate(BlockBackend *blk, Error **errp)
|
||||
if (qemu_in_coroutine()) {
|
||||
bdrv_co_activate(bs, errp);
|
||||
} else {
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
bdrv_activate(bs, errp);
|
||||
}
|
||||
}
|
||||
@@ -2384,6 +2388,7 @@ bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp)
|
||||
{
|
||||
BlockDriverState *bs = blk_bs(blk);
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
if (!bs) {
|
||||
return false;
|
||||
@@ -2901,6 +2906,8 @@ const BdrvChild *blk_root(BlockBackend *blk)
|
||||
int blk_make_empty(BlockBackend *blk, Error **errp)
|
||||
{
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
if (!blk_is_available(blk)) {
|
||||
error_setg(errp, "No medium inserted");
|
||||
return -ENOMEDIUM;
|
||||
|
||||
@@ -106,7 +106,9 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
int ret;
|
||||
|
||||
/* No write support yet */
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
ret = bdrv_apply_auto_read_only(bs, NULL, errp);
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -67,7 +67,9 @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
uint32_t offsets_size, max_compressed_block_size = 1, i;
|
||||
int ret;
|
||||
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
ret = bdrv_apply_auto_read_only(bs, NULL, errp);
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -434,6 +434,7 @@ int bdrv_commit(BlockDriverState *bs)
|
||||
Error *local_err = NULL;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
if (!drv)
|
||||
return -ENOMEDIUM;
|
||||
|
||||
@@ -305,7 +305,7 @@ cbw_co_snapshot_block_status(BlockDriverState *bs,
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
ret = bdrv_block_status(child->bs, offset, cur_bytes, pnum, map, file);
|
||||
ret = bdrv_co_block_status(child->bs, offset, cur_bytes, pnum, map, file);
|
||||
if (child == s->target) {
|
||||
/*
|
||||
* We refer to s->target only for areas that we've written to it.
|
||||
|
||||
@@ -146,11 +146,11 @@ cor_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||
local_flags = flags;
|
||||
|
||||
/* In case of failure, try to copy-on-read anyway */
|
||||
ret = bdrv_is_allocated(bs->file->bs, offset, bytes, &n);
|
||||
ret = bdrv_co_is_allocated(bs->file->bs, offset, bytes, &n);
|
||||
if (ret <= 0) {
|
||||
ret = bdrv_is_allocated_above(bdrv_backing_chain_next(bs->file->bs),
|
||||
state->bottom_bs, true, offset,
|
||||
n, &n);
|
||||
ret = bdrv_co_is_allocated_above(bdrv_backing_chain_next(bs->file->bs),
|
||||
state->bottom_bs, true, offset,
|
||||
n, &n);
|
||||
if (ret > 0 || ret < 0) {
|
||||
local_flags |= BDRV_REQ_COPY_ON_READ;
|
||||
}
|
||||
|
||||
+1
-3
@@ -828,7 +828,7 @@ block_crypto_amend_options_generic_luks(BlockDriverState *bs,
|
||||
errp);
|
||||
}
|
||||
|
||||
static int
|
||||
static int GRAPH_RDLOCK
|
||||
block_crypto_amend_options_luks(BlockDriverState *bs,
|
||||
QemuOpts *opts,
|
||||
BlockDriverAmendStatusCB *status_cb,
|
||||
@@ -841,8 +841,6 @@ block_crypto_amend_options_luks(BlockDriverState *bs,
|
||||
QCryptoBlockAmendOptions *amend_options = NULL;
|
||||
int ret = -EINVAL;
|
||||
|
||||
assume_graph_lock(); /* FIXME */
|
||||
|
||||
assert(crypto);
|
||||
assert(crypto->block);
|
||||
|
||||
|
||||
@@ -696,8 +696,10 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
const char *protocol_delimiter;
|
||||
int ret;
|
||||
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
ret = bdrv_apply_auto_read_only(bs, "curl driver does not support writes",
|
||||
errp);
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -452,7 +452,9 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
int64_t offset;
|
||||
int ret;
|
||||
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
ret = bdrv_apply_auto_read_only(bs, NULL, errp);
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -83,6 +83,8 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
|
||||
uint64_t perm;
|
||||
int ret;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
|
||||
if (!id_wellformed(export->id)) {
|
||||
error_setg(errp, "Invalid block export id");
|
||||
return NULL;
|
||||
@@ -145,7 +147,9 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
|
||||
* access since the export could be available before migration handover.
|
||||
* ctx was acquired in the caller.
|
||||
*/
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
bdrv_activate(bs, NULL);
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
|
||||
perm = BLK_PERM_CONSISTENT_READ;
|
||||
if (export->writable) {
|
||||
|
||||
@@ -863,11 +863,13 @@ static int qemu_gluster_open(BlockDriverState *bs, QDict *options,
|
||||
if (ret == -EACCES || ret == -EROFS) {
|
||||
/* Try to degrade to read-only, but if it doesn't work, still use the
|
||||
* normal error message. */
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
if (bdrv_apply_auto_read_only(bs, NULL, NULL) == 0) {
|
||||
open_flags = (open_flags & ~O_RDWR) | O_RDONLY;
|
||||
s->fd = glfs_open(s->glfs, gconf->path, open_flags);
|
||||
ret = s->fd ? 0 : -errno;
|
||||
}
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
}
|
||||
|
||||
s->supports_seek_data = qemu_gluster_test_seek(s->fd);
|
||||
|
||||
+2
-1
@@ -106,12 +106,13 @@ static uint32_t reader_count(void)
|
||||
return rd;
|
||||
}
|
||||
|
||||
void bdrv_graph_wrlock(BlockDriverState *bs)
|
||||
void no_coroutine_fn bdrv_graph_wrlock(BlockDriverState *bs)
|
||||
{
|
||||
AioContext *ctx = NULL;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
assert(!qatomic_read(&has_writer));
|
||||
assert(!qemu_in_coroutine());
|
||||
|
||||
/*
|
||||
* Release only non-mainloop AioContext. The mainloop often relies on the
|
||||
|
||||
+64
-79
@@ -42,13 +42,18 @@
|
||||
/* Maximum bounce buffer for copy-on-read and write zeroes, in bytes */
|
||||
#define MAX_BOUNCE_BUFFER (32768 << BDRV_SECTOR_BITS)
|
||||
|
||||
static void bdrv_parent_cb_resize(BlockDriverState *bs);
|
||||
static void coroutine_fn GRAPH_RDLOCK
|
||||
bdrv_parent_cb_resize(BlockDriverState *bs);
|
||||
|
||||
static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
|
||||
int64_t offset, int64_t bytes, BdrvRequestFlags flags);
|
||||
|
||||
static void bdrv_parent_drained_begin(BlockDriverState *bs, BdrvChild *ignore)
|
||||
static void GRAPH_RDLOCK
|
||||
bdrv_parent_drained_begin(BlockDriverState *bs, BdrvChild *ignore)
|
||||
{
|
||||
BdrvChild *c, *next;
|
||||
IO_OR_GS_CODE();
|
||||
assert_bdrv_graph_readable();
|
||||
|
||||
QLIST_FOREACH_SAFE(c, &bs->parents, next_parent, next) {
|
||||
if (c == ignore) {
|
||||
@@ -70,9 +75,12 @@ void bdrv_parent_drained_end_single(BdrvChild *c)
|
||||
}
|
||||
}
|
||||
|
||||
static void bdrv_parent_drained_end(BlockDriverState *bs, BdrvChild *ignore)
|
||||
static void GRAPH_RDLOCK
|
||||
bdrv_parent_drained_end(BlockDriverState *bs, BdrvChild *ignore)
|
||||
{
|
||||
BdrvChild *c;
|
||||
IO_OR_GS_CODE();
|
||||
assert_bdrv_graph_readable();
|
||||
|
||||
QLIST_FOREACH(c, &bs->parents, next_parent) {
|
||||
if (c == ignore) {
|
||||
@@ -84,17 +92,22 @@ static void bdrv_parent_drained_end(BlockDriverState *bs, BdrvChild *ignore)
|
||||
|
||||
bool bdrv_parent_drained_poll_single(BdrvChild *c)
|
||||
{
|
||||
IO_OR_GS_CODE();
|
||||
|
||||
if (c->klass->drained_poll) {
|
||||
return c->klass->drained_poll(c);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool bdrv_parent_drained_poll(BlockDriverState *bs, BdrvChild *ignore,
|
||||
bool ignore_bds_parents)
|
||||
static bool GRAPH_RDLOCK
|
||||
bdrv_parent_drained_poll(BlockDriverState *bs, BdrvChild *ignore,
|
||||
bool ignore_bds_parents)
|
||||
{
|
||||
BdrvChild *c, *next;
|
||||
bool busy = false;
|
||||
IO_OR_GS_CODE();
|
||||
assert_bdrv_graph_readable();
|
||||
|
||||
QLIST_FOREACH_SAFE(c, &bs->parents, next_parent, next) {
|
||||
if (c == ignore || (ignore_bds_parents && c->klass->parent_is_bds)) {
|
||||
@@ -114,6 +127,7 @@ void bdrv_parent_drained_begin_single(BdrvChild *c)
|
||||
c->quiesced_parent = true;
|
||||
|
||||
if (c->klass->drained_begin) {
|
||||
/* called with rdlock taken, but it doesn't really need it. */
|
||||
c->klass->drained_begin(c);
|
||||
}
|
||||
}
|
||||
@@ -263,6 +277,9 @@ bool bdrv_drain_poll(BlockDriverState *bs, BdrvChild *ignore_parent,
|
||||
static bool bdrv_drain_poll_top_level(BlockDriverState *bs,
|
||||
BdrvChild *ignore_parent)
|
||||
{
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
return bdrv_drain_poll(bs, ignore_parent, false);
|
||||
}
|
||||
|
||||
@@ -362,6 +379,7 @@ static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent,
|
||||
|
||||
/* Stop things in parent-to-child order */
|
||||
if (qatomic_fetch_inc(&bs->quiesce_counter) == 0) {
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
bdrv_parent_drained_begin(bs, parent);
|
||||
if (bs->drv && bs->drv->bdrv_drain_begin) {
|
||||
bs->drv->bdrv_drain_begin(bs);
|
||||
@@ -408,12 +426,16 @@ static void bdrv_do_drained_end(BlockDriverState *bs, BdrvChild *parent)
|
||||
bdrv_co_yield_to_drain(bs, false, parent, false);
|
||||
return;
|
||||
}
|
||||
|
||||
/* At this point, we should be always running in the main loop. */
|
||||
GLOBAL_STATE_CODE();
|
||||
assert(bs->quiesce_counter > 0);
|
||||
GLOBAL_STATE_CODE();
|
||||
|
||||
/* Re-enable things in child-to-parent order */
|
||||
old_quiesce_counter = qatomic_fetch_dec(&bs->quiesce_counter);
|
||||
if (old_quiesce_counter == 1) {
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
if (bs->drv && bs->drv->bdrv_drain_end) {
|
||||
bs->drv->bdrv_drain_end(bs);
|
||||
}
|
||||
@@ -437,6 +459,8 @@ void bdrv_drain(BlockDriverState *bs)
|
||||
static void bdrv_drain_assert_idle(BlockDriverState *bs)
|
||||
{
|
||||
BdrvChild *child, *next;
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
assert(qatomic_read(&bs->in_flight) == 0);
|
||||
QLIST_FOREACH_SAFE(child, &bs->children, next, next) {
|
||||
@@ -450,7 +474,9 @@ static bool bdrv_drain_all_poll(void)
|
||||
{
|
||||
BlockDriverState *bs = NULL;
|
||||
bool result = false;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
/* bdrv_drain_poll() can't make changes to the graph and we are holding the
|
||||
* main AioContext lock, so iterating bdrv_next_all_states() is safe. */
|
||||
@@ -1223,8 +1249,8 @@ bdrv_co_do_copy_on_readv(BdrvChild *child, int64_t offset, int64_t bytes,
|
||||
ret = 1; /* "already allocated", so nothing will be copied */
|
||||
pnum = MIN(align_bytes, max_transfer);
|
||||
} else {
|
||||
ret = bdrv_is_allocated(bs, align_offset,
|
||||
MIN(align_bytes, max_transfer), &pnum);
|
||||
ret = bdrv_co_is_allocated(bs, align_offset,
|
||||
MIN(align_bytes, max_transfer), &pnum);
|
||||
if (ret < 0) {
|
||||
/*
|
||||
* Safe to treat errors in querying allocation as if
|
||||
@@ -1371,7 +1397,7 @@ bdrv_aligned_preadv(BdrvChild *child, BdrvTrackedRequest *req,
|
||||
/* The flag BDRV_REQ_COPY_ON_READ has reached its addressee */
|
||||
flags &= ~BDRV_REQ_COPY_ON_READ;
|
||||
|
||||
ret = bdrv_is_allocated(bs, offset, bytes, &pnum);
|
||||
ret = bdrv_co_is_allocated(bs, offset, bytes, &pnum);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
@@ -2003,7 +2029,7 @@ bdrv_co_write_req_prepare(BdrvChild *child, int64_t offset, int64_t bytes,
|
||||
}
|
||||
}
|
||||
|
||||
static inline void coroutine_fn
|
||||
static inline void coroutine_fn GRAPH_RDLOCK
|
||||
bdrv_co_write_req_finish(BdrvChild *child, int64_t offset, int64_t bytes,
|
||||
BdrvTrackedRequest *req, int ret)
|
||||
{
|
||||
@@ -2330,6 +2356,7 @@ int bdrv_flush_all(void)
|
||||
int result = 0;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
/*
|
||||
* bdrv queue is managed by record/replay,
|
||||
@@ -2383,9 +2410,9 @@ int bdrv_flush_all(void)
|
||||
* set to the host mapping and BDS corresponding to the guest offset.
|
||||
*/
|
||||
static int coroutine_fn GRAPH_RDLOCK
|
||||
bdrv_co_block_status(BlockDriverState *bs, bool want_zero,
|
||||
int64_t offset, int64_t bytes,
|
||||
int64_t *pnum, int64_t *map, BlockDriverState **file)
|
||||
bdrv_co_do_block_status(BlockDriverState *bs, bool want_zero,
|
||||
int64_t offset, int64_t bytes,
|
||||
int64_t *pnum, int64_t *map, BlockDriverState **file)
|
||||
{
|
||||
int64_t total_size;
|
||||
int64_t n; /* bytes */
|
||||
@@ -2544,8 +2571,8 @@ bdrv_co_block_status(BlockDriverState *bs, bool want_zero,
|
||||
|
||||
if (ret & BDRV_BLOCK_RAW) {
|
||||
assert(ret & BDRV_BLOCK_OFFSET_VALID && local_file);
|
||||
ret = bdrv_co_block_status(local_file, want_zero, local_map,
|
||||
*pnum, pnum, &local_map, &local_file);
|
||||
ret = bdrv_co_do_block_status(local_file, want_zero, local_map,
|
||||
*pnum, pnum, &local_map, &local_file);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -2572,8 +2599,8 @@ bdrv_co_block_status(BlockDriverState *bs, bool want_zero,
|
||||
int64_t file_pnum;
|
||||
int ret2;
|
||||
|
||||
ret2 = bdrv_co_block_status(local_file, want_zero, local_map,
|
||||
*pnum, &file_pnum, NULL, NULL);
|
||||
ret2 = bdrv_co_do_block_status(local_file, want_zero, local_map,
|
||||
*pnum, &file_pnum, NULL, NULL);
|
||||
if (ret2 >= 0) {
|
||||
/* Ignore errors. This is just providing extra information, it
|
||||
* is useful but not necessary.
|
||||
@@ -2640,7 +2667,8 @@ bdrv_co_common_block_status_above(BlockDriverState *bs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = bdrv_co_block_status(bs, want_zero, offset, bytes, pnum, map, file);
|
||||
ret = bdrv_co_do_block_status(bs, want_zero, offset, bytes, pnum,
|
||||
map, file);
|
||||
++*depth;
|
||||
if (ret < 0 || *pnum == 0 || ret & BDRV_BLOCK_ALLOCATED || bs == base) {
|
||||
return ret;
|
||||
@@ -2656,8 +2684,8 @@ bdrv_co_common_block_status_above(BlockDriverState *bs,
|
||||
for (p = bdrv_filter_or_cow_bs(bs); include_base || p != base;
|
||||
p = bdrv_filter_or_cow_bs(p))
|
||||
{
|
||||
ret = bdrv_co_block_status(p, want_zero, offset, bytes, pnum, map,
|
||||
file);
|
||||
ret = bdrv_co_do_block_status(p, want_zero, offset, bytes, pnum,
|
||||
map, file);
|
||||
++*depth;
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
@@ -2723,21 +2751,13 @@ int coroutine_fn bdrv_co_block_status_above(BlockDriverState *bs,
|
||||
bytes, pnum, map, file, NULL);
|
||||
}
|
||||
|
||||
int bdrv_block_status_above(BlockDriverState *bs, BlockDriverState *base,
|
||||
int64_t offset, int64_t bytes, int64_t *pnum,
|
||||
int64_t *map, BlockDriverState **file)
|
||||
int coroutine_fn bdrv_co_block_status(BlockDriverState *bs, int64_t offset,
|
||||
int64_t bytes, int64_t *pnum,
|
||||
int64_t *map, BlockDriverState **file)
|
||||
{
|
||||
IO_CODE();
|
||||
return bdrv_common_block_status_above(bs, base, false, true, offset, bytes,
|
||||
pnum, map, file, NULL);
|
||||
}
|
||||
|
||||
int bdrv_block_status(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||
int64_t *pnum, int64_t *map, BlockDriverState **file)
|
||||
{
|
||||
IO_CODE();
|
||||
return bdrv_block_status_above(bs, bdrv_filter_or_cow_bs(bs),
|
||||
offset, bytes, pnum, map, file);
|
||||
return bdrv_co_block_status_above(bs, bdrv_filter_or_cow_bs(bs),
|
||||
offset, bytes, pnum, map, file);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2784,45 +2804,6 @@ int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t offset,
|
||||
return !!(ret & BDRV_BLOCK_ALLOCATED);
|
||||
}
|
||||
|
||||
int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||
int64_t *pnum)
|
||||
{
|
||||
int ret;
|
||||
int64_t dummy;
|
||||
IO_CODE();
|
||||
|
||||
ret = bdrv_common_block_status_above(bs, bs, true, false, offset,
|
||||
bytes, pnum ? pnum : &dummy, NULL,
|
||||
NULL, NULL);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
return !!(ret & BDRV_BLOCK_ALLOCATED);
|
||||
}
|
||||
|
||||
/* See bdrv_is_allocated_above for documentation */
|
||||
int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top,
|
||||
BlockDriverState *base,
|
||||
bool include_base, int64_t offset,
|
||||
int64_t bytes, int64_t *pnum)
|
||||
{
|
||||
int depth;
|
||||
int ret;
|
||||
IO_CODE();
|
||||
|
||||
ret = bdrv_co_common_block_status_above(top, base, include_base, false,
|
||||
offset, bytes, pnum, NULL, NULL,
|
||||
&depth);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret & BDRV_BLOCK_ALLOCATED) {
|
||||
return depth;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given an image chain: ... -> [BASE] -> [INTER1] -> [INTER2] -> [TOP]
|
||||
*
|
||||
@@ -2840,18 +2821,18 @@ int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top,
|
||||
* words, the result is not necessarily the maximum possible range);
|
||||
* but 'pnum' will only be 0 when end of file is reached.
|
||||
*/
|
||||
int bdrv_is_allocated_above(BlockDriverState *top,
|
||||
BlockDriverState *base,
|
||||
bool include_base, int64_t offset,
|
||||
int64_t bytes, int64_t *pnum)
|
||||
int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *bs,
|
||||
BlockDriverState *base,
|
||||
bool include_base, int64_t offset,
|
||||
int64_t bytes, int64_t *pnum)
|
||||
{
|
||||
int depth;
|
||||
int ret;
|
||||
IO_CODE();
|
||||
|
||||
ret = bdrv_common_block_status_above(top, base, include_base, false,
|
||||
offset, bytes, pnum, NULL, NULL,
|
||||
&depth);
|
||||
ret = bdrv_co_common_block_status_above(bs, base, include_base, false,
|
||||
offset, bytes, pnum, NULL, NULL,
|
||||
&depth);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -3551,9 +3532,13 @@ int coroutine_fn bdrv_co_copy_range(BdrvChild *src, int64_t src_offset,
|
||||
bytes, read_flags, write_flags);
|
||||
}
|
||||
|
||||
static void bdrv_parent_cb_resize(BlockDriverState *bs)
|
||||
static void coroutine_fn GRAPH_RDLOCK
|
||||
bdrv_parent_cb_resize(BlockDriverState *bs)
|
||||
{
|
||||
BdrvChild *c;
|
||||
|
||||
assert_bdrv_graph_readable();
|
||||
|
||||
QLIST_FOREACH(c, &bs->parents, next_parent) {
|
||||
if (c->klass->resize) {
|
||||
c->klass->resize(c);
|
||||
|
||||
@@ -1925,7 +1925,9 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
/* Check the write protect flag of the LUN if we want to write */
|
||||
if (iscsilun->type == TYPE_DISK && (flags & BDRV_O_RDWR) &&
|
||||
iscsilun->write_protected) {
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
ret = bdrv_apply_auto_read_only(bs, "LUN is write protected", errp);
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
+5
-5
@@ -559,9 +559,9 @@ static void coroutine_fn mirror_iteration(MirrorBlockJob *s)
|
||||
|
||||
assert(!(offset % s->granularity));
|
||||
WITH_GRAPH_RDLOCK_GUARD() {
|
||||
ret = bdrv_block_status_above(source, NULL, offset,
|
||||
nb_chunks * s->granularity,
|
||||
&io_bytes, NULL, NULL);
|
||||
ret = bdrv_co_block_status_above(source, NULL, offset,
|
||||
nb_chunks * s->granularity,
|
||||
&io_bytes, NULL, NULL);
|
||||
}
|
||||
if (ret < 0) {
|
||||
io_bytes = MIN(nb_chunks * s->granularity, max_io_bytes);
|
||||
@@ -879,8 +879,8 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
|
||||
}
|
||||
|
||||
WITH_GRAPH_RDLOCK_GUARD() {
|
||||
ret = bdrv_is_allocated_above(bs, s->base_overlay, true, offset,
|
||||
bytes, &count);
|
||||
ret = bdrv_co_is_allocated_above(bs, s->base_overlay, true, offset,
|
||||
bytes, &count);
|
||||
}
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
|
||||
@@ -144,6 +144,9 @@ void hmp_drive_del(Monitor *mon, const QDict *qdict)
|
||||
AioContext *aio_context;
|
||||
Error *local_err = NULL;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
bs = bdrv_find_node(id);
|
||||
if (bs) {
|
||||
qmp_blockdev_del(id, &local_err);
|
||||
@@ -896,6 +899,8 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
|
||||
SnapshotEntry *snapshot_entry;
|
||||
Error *err = NULL;
|
||||
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
bs = bdrv_all_find_vmstate_bs(NULL, false, NULL, &err);
|
||||
if (!bs) {
|
||||
error_report_err(err);
|
||||
|
||||
+2
-1
@@ -275,7 +275,8 @@ static bool nbd_client_will_reconnect(BDRVNBDState *s)
|
||||
* Return failure if the server's advertised options are incompatible with the
|
||||
* client's needs.
|
||||
*/
|
||||
static int nbd_handle_updated_info(BlockDriverState *bs, Error **errp)
|
||||
static int coroutine_fn GRAPH_RDLOCK
|
||||
nbd_handle_updated_info(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
|
||||
int ret;
|
||||
|
||||
+1
-1
@@ -843,7 +843,7 @@ static void nfs_refresh_filename(BlockDriverState *bs)
|
||||
}
|
||||
}
|
||||
|
||||
static char *nfs_dirname(BlockDriverState *bs, Error **errp)
|
||||
static char * GRAPH_RDLOCK nfs_dirname(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
NFSClient *client = bs->opaque;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user