mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-14 21:52:18 -06:00
block: Mark bdrv_snapshot_fallback() and callers GRAPH_RDLOCK
This adds GRAPH_RDLOCK annotations to declare that callers of bdrv_snapshot_fallback() 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> Message-ID: <20230929145157.45443-8-kwolf@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
7859c45a46
commit
a32e781838
5 changed files with 67 additions and 24 deletions
|
@ -155,11 +155,15 @@ bool bdrv_snapshot_find_by_id_and_name(BlockDriverState *bs,
|
||||||
* back if the given BDS does not support snapshots.
|
* back if the given BDS does not support snapshots.
|
||||||
* Return NULL if there is no BDS to (safely) fall back to.
|
* Return NULL if there is no BDS to (safely) fall back to.
|
||||||
*/
|
*/
|
||||||
static BdrvChild *bdrv_snapshot_fallback_child(BlockDriverState *bs)
|
static BdrvChild * GRAPH_RDLOCK
|
||||||
|
bdrv_snapshot_fallback_child(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BdrvChild *fallback = bdrv_primary_child(bs);
|
BdrvChild *fallback = bdrv_primary_child(bs);
|
||||||
BdrvChild *child;
|
BdrvChild *child;
|
||||||
|
|
||||||
|
GLOBAL_STATE_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
/* We allow fallback only to primary child */
|
/* We allow fallback only to primary child */
|
||||||
if (!fallback) {
|
if (!fallback) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -182,8 +186,10 @@ static BdrvChild *bdrv_snapshot_fallback_child(BlockDriverState *bs)
|
||||||
return fallback;
|
return fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BlockDriverState *bdrv_snapshot_fallback(BlockDriverState *bs)
|
static BlockDriverState * GRAPH_RDLOCK
|
||||||
|
bdrv_snapshot_fallback(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
|
GLOBAL_STATE_CODE();
|
||||||
return child_bs(bdrv_snapshot_fallback_child(bs));
|
return child_bs(bdrv_snapshot_fallback_child(bs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +260,10 @@ int bdrv_snapshot_goto(BlockDriverState *bs,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bdrv_graph_rdlock_main_loop();
|
||||||
fallback = bdrv_snapshot_fallback_child(bs);
|
fallback = bdrv_snapshot_fallback_child(bs);
|
||||||
|
bdrv_graph_rdunlock_main_loop();
|
||||||
|
|
||||||
if (fallback) {
|
if (fallback) {
|
||||||
QDict *options;
|
QDict *options;
|
||||||
QDict *file_options;
|
QDict *file_options;
|
||||||
|
@ -374,10 +383,12 @@ int bdrv_snapshot_delete(BlockDriverState *bs,
|
||||||
int bdrv_snapshot_list(BlockDriverState *bs,
|
int bdrv_snapshot_list(BlockDriverState *bs,
|
||||||
QEMUSnapshotInfo **psn_info)
|
QEMUSnapshotInfo **psn_info)
|
||||||
{
|
{
|
||||||
|
GLOBAL_STATE_CODE();
|
||||||
|
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||||
|
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs);
|
BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs);
|
||||||
|
|
||||||
GLOBAL_STATE_CODE();
|
|
||||||
if (!drv) {
|
if (!drv) {
|
||||||
return -ENOMEDIUM;
|
return -ENOMEDIUM;
|
||||||
}
|
}
|
||||||
|
@ -498,6 +509,9 @@ bdrv_all_get_snapshot_devices(bool has_devices, strList *devices,
|
||||||
|
|
||||||
static bool GRAPH_RDLOCK bdrv_all_snapshots_includes_bs(BlockDriverState *bs)
|
static bool GRAPH_RDLOCK bdrv_all_snapshots_includes_bs(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
|
GLOBAL_STATE_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
|
if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -595,11 +609,15 @@ int bdrv_all_goto_snapshot(const char *name,
|
||||||
{
|
{
|
||||||
g_autoptr(GList) bdrvs = NULL;
|
g_autoptr(GList) bdrvs = NULL;
|
||||||
GList *iterbdrvs;
|
GList *iterbdrvs;
|
||||||
|
int ret;
|
||||||
|
|
||||||
GLOBAL_STATE_CODE();
|
GLOBAL_STATE_CODE();
|
||||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
|
||||||
|
|
||||||
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
|
bdrv_graph_rdlock_main_loop();
|
||||||
|
ret = bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp);
|
||||||
|
bdrv_graph_rdunlock_main_loop();
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,9 +626,14 @@ int bdrv_all_goto_snapshot(const char *name,
|
||||||
BlockDriverState *bs = iterbdrvs->data;
|
BlockDriverState *bs = iterbdrvs->data;
|
||||||
AioContext *ctx = bdrv_get_aio_context(bs);
|
AioContext *ctx = bdrv_get_aio_context(bs);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
bool all_snapshots_includes_bs;
|
||||||
|
|
||||||
aio_context_acquire(ctx);
|
aio_context_acquire(ctx);
|
||||||
if (devices || bdrv_all_snapshots_includes_bs(bs)) {
|
bdrv_graph_rdlock_main_loop();
|
||||||
|
all_snapshots_includes_bs = bdrv_all_snapshots_includes_bs(bs);
|
||||||
|
bdrv_graph_rdunlock_main_loop();
|
||||||
|
|
||||||
|
if (devices || all_snapshots_includes_bs) {
|
||||||
ret = bdrv_snapshot_goto(bs, name, errp);
|
ret = bdrv_snapshot_goto(bs, name, errp);
|
||||||
}
|
}
|
||||||
aio_context_release(ctx);
|
aio_context_release(ctx);
|
||||||
|
|
|
@ -1138,6 +1138,9 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
|
||||||
SnapshotInfo *info = NULL;
|
SnapshotInfo *info = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
GLOBAL_STATE_CODE();
|
||||||
|
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||||
|
|
||||||
bs = qmp_get_root_bs(device, errp);
|
bs = qmp_get_root_bs(device, errp);
|
||||||
if (!bs) {
|
if (!bs) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1223,6 +1226,9 @@ static void internal_snapshot_action(BlockdevSnapshotInternal *internal,
|
||||||
AioContext *aio_context;
|
AioContext *aio_context;
|
||||||
int ret1;
|
int ret1;
|
||||||
|
|
||||||
|
GLOBAL_STATE_CODE();
|
||||||
|
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||||
|
|
||||||
tran_add(tran, &internal_snapshot_drv, state);
|
tran_add(tran, &internal_snapshot_drv, state);
|
||||||
|
|
||||||
device = internal->device;
|
device = internal->device;
|
||||||
|
@ -1311,6 +1317,9 @@ static void internal_snapshot_abort(void *opaque)
|
||||||
AioContext *aio_context;
|
AioContext *aio_context;
|
||||||
Error *local_error = NULL;
|
Error *local_error = NULL;
|
||||||
|
|
||||||
|
GLOBAL_STATE_CODE();
|
||||||
|
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||||
|
|
||||||
if (!state->created) {
|
if (!state->created) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -313,14 +313,16 @@ struct BlockDriver {
|
||||||
|
|
||||||
int GRAPH_RDLOCK_PTR (*bdrv_inactivate)(BlockDriverState *bs);
|
int GRAPH_RDLOCK_PTR (*bdrv_inactivate)(BlockDriverState *bs);
|
||||||
|
|
||||||
int (*bdrv_snapshot_create)(BlockDriverState *bs,
|
int GRAPH_RDLOCK_PTR (*bdrv_snapshot_create)(
|
||||||
QEMUSnapshotInfo *sn_info);
|
BlockDriverState *bs, QEMUSnapshotInfo *sn_info);
|
||||||
int (*bdrv_snapshot_goto)(BlockDriverState *bs,
|
|
||||||
const char *snapshot_id);
|
int GRAPH_UNLOCKED_PTR (*bdrv_snapshot_goto)(
|
||||||
int (*bdrv_snapshot_delete)(BlockDriverState *bs,
|
BlockDriverState *bs, const char *snapshot_id);
|
||||||
const char *snapshot_id,
|
|
||||||
const char *name,
|
int GRAPH_RDLOCK_PTR (*bdrv_snapshot_delete)(
|
||||||
|
BlockDriverState *bs, const char *snapshot_id, const char *name,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
|
||||||
int (*bdrv_snapshot_list)(BlockDriverState *bs,
|
int (*bdrv_snapshot_list)(BlockDriverState *bs,
|
||||||
QEMUSnapshotInfo **psn_info);
|
QEMUSnapshotInfo **psn_info);
|
||||||
int (*bdrv_snapshot_load_tmp)(BlockDriverState *bs,
|
int (*bdrv_snapshot_load_tmp)(BlockDriverState *bs,
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#ifndef SNAPSHOT_H
|
#ifndef SNAPSHOT_H
|
||||||
#define SNAPSHOT_H
|
#define SNAPSHOT_H
|
||||||
|
|
||||||
|
#include "block/graph-lock.h"
|
||||||
#include "qapi/qapi-builtin-types.h"
|
#include "qapi/qapi-builtin-types.h"
|
||||||
|
|
||||||
#define SNAPSHOT_OPT_BASE "snapshot."
|
#define SNAPSHOT_OPT_BASE "snapshot."
|
||||||
|
@ -59,16 +60,19 @@ bool bdrv_snapshot_find_by_id_and_name(BlockDriverState *bs,
|
||||||
const char *name,
|
const char *name,
|
||||||
QEMUSnapshotInfo *sn_info,
|
QEMUSnapshotInfo *sn_info,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
int bdrv_can_snapshot(BlockDriverState *bs);
|
|
||||||
int bdrv_snapshot_create(BlockDriverState *bs,
|
int GRAPH_RDLOCK bdrv_can_snapshot(BlockDriverState *bs);
|
||||||
QEMUSnapshotInfo *sn_info);
|
|
||||||
int bdrv_snapshot_goto(BlockDriverState *bs,
|
int GRAPH_RDLOCK
|
||||||
const char *snapshot_id,
|
bdrv_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info);
|
||||||
Error **errp);
|
|
||||||
int bdrv_snapshot_delete(BlockDriverState *bs,
|
int GRAPH_UNLOCKED
|
||||||
const char *snapshot_id,
|
bdrv_snapshot_goto(BlockDriverState *bs, const char *snapshot_id, Error **errp);
|
||||||
const char *name,
|
|
||||||
Error **errp);
|
int GRAPH_RDLOCK
|
||||||
|
bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id,
|
||||||
|
const char *name, Error **errp);
|
||||||
|
|
||||||
int bdrv_snapshot_list(BlockDriverState *bs,
|
int bdrv_snapshot_list(BlockDriverState *bs,
|
||||||
QEMUSnapshotInfo **psn_info);
|
QEMUSnapshotInfo **psn_info);
|
||||||
int bdrv_snapshot_load_tmp(BlockDriverState *bs,
|
int bdrv_snapshot_load_tmp(BlockDriverState *bs,
|
||||||
|
|
|
@ -3470,7 +3470,10 @@ static int img_snapshot(int argc, char **argv)
|
||||||
sn.date_sec = rt / G_USEC_PER_SEC;
|
sn.date_sec = rt / G_USEC_PER_SEC;
|
||||||
sn.date_nsec = (rt % G_USEC_PER_SEC) * 1000;
|
sn.date_nsec = (rt % G_USEC_PER_SEC) * 1000;
|
||||||
|
|
||||||
|
bdrv_graph_rdlock_main_loop();
|
||||||
ret = bdrv_snapshot_create(bs, &sn);
|
ret = bdrv_snapshot_create(bs, &sn);
|
||||||
|
bdrv_graph_rdunlock_main_loop();
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
error_report("Could not create snapshot '%s': %s",
|
error_report("Could not create snapshot '%s': %s",
|
||||||
snapshot_name, strerror(-ret));
|
snapshot_name, strerror(-ret));
|
||||||
|
@ -3486,6 +3489,7 @@ static int img_snapshot(int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SNAPSHOT_DELETE:
|
case SNAPSHOT_DELETE:
|
||||||
|
bdrv_graph_rdlock_main_loop();
|
||||||
ret = bdrv_snapshot_find(bs, &sn, snapshot_name);
|
ret = bdrv_snapshot_find(bs, &sn, snapshot_name);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_report("Could not delete snapshot '%s': snapshot not "
|
error_report("Could not delete snapshot '%s': snapshot not "
|
||||||
|
@ -3499,6 +3503,7 @@ static int img_snapshot(int argc, char **argv)
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bdrv_graph_rdunlock_main_loop();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue