include/block/snapshot: global state API + assertions

Snapshots run also under the BQL, so they all are
in the global state API. The aiocontext lock that they hold
is currently an overkill and in future could be removed.

Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Message-Id: <20220303151616.325444-23-eesposit@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Emanuele Giuseppe Esposito 2022-03-03 10:16:07 -05:00 committed by Kevin Wolf
parent c5be7445b7
commit 6b573efec8
3 changed files with 41 additions and 2 deletions

View File

@ -57,6 +57,8 @@ int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
QEMUSnapshotInfo *sn_tab, *sn; QEMUSnapshotInfo *sn_tab, *sn;
int nb_sns, i, ret; int nb_sns, i, ret;
GLOBAL_STATE_CODE();
ret = -ENOENT; ret = -ENOENT;
nb_sns = bdrv_snapshot_list(bs, &sn_tab); nb_sns = bdrv_snapshot_list(bs, &sn_tab);
if (nb_sns < 0) { if (nb_sns < 0) {
@ -105,6 +107,7 @@ bool bdrv_snapshot_find_by_id_and_name(BlockDriverState *bs,
bool ret = false; bool ret = false;
assert(id || name); assert(id || name);
GLOBAL_STATE_CODE();
nb_sns = bdrv_snapshot_list(bs, &sn_tab); nb_sns = bdrv_snapshot_list(bs, &sn_tab);
if (nb_sns < 0) { if (nb_sns < 0) {
@ -200,6 +203,7 @@ static BlockDriverState *bdrv_snapshot_fallback(BlockDriverState *bs)
int bdrv_can_snapshot(BlockDriverState *bs) int bdrv_can_snapshot(BlockDriverState *bs)
{ {
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
GLOBAL_STATE_CODE();
if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) { if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
return 0; return 0;
} }
@ -220,6 +224,9 @@ int bdrv_snapshot_create(BlockDriverState *bs,
{ {
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;
} }
@ -240,6 +247,8 @@ int bdrv_snapshot_goto(BlockDriverState *bs,
BdrvChild **fallback_ptr; BdrvChild **fallback_ptr;
int ret, open_ret; int ret, open_ret;
GLOBAL_STATE_CODE();
if (!drv) { if (!drv) {
error_setg(errp, "Block driver is closed"); error_setg(errp, "Block driver is closed");
return -ENOMEDIUM; return -ENOMEDIUM;
@ -348,6 +357,8 @@ int bdrv_snapshot_delete(BlockDriverState *bs,
BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs); BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs);
int ret; int ret;
GLOBAL_STATE_CODE();
if (!drv) { if (!drv) {
error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, bdrv_get_device_name(bs)); error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, bdrv_get_device_name(bs));
return -ENOMEDIUM; return -ENOMEDIUM;
@ -380,6 +391,8 @@ int bdrv_snapshot_list(BlockDriverState *bs,
{ {
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;
} }
@ -419,6 +432,8 @@ int bdrv_snapshot_load_tmp(BlockDriverState *bs,
{ {
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
GLOBAL_STATE_CODE();
if (!drv) { if (!drv) {
error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, bdrv_get_device_name(bs)); error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, bdrv_get_device_name(bs));
return -ENOMEDIUM; return -ENOMEDIUM;
@ -447,6 +462,8 @@ int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs,
int ret; int ret;
Error *local_err = NULL; Error *local_err = NULL;
GLOBAL_STATE_CODE();
ret = bdrv_snapshot_load_tmp(bs, id_or_name, NULL, &local_err); ret = bdrv_snapshot_load_tmp(bs, id_or_name, NULL, &local_err);
if (ret == -ENOENT || ret == -EINVAL) { if (ret == -ENOENT || ret == -EINVAL) {
error_free(local_err); error_free(local_err);
@ -515,6 +532,8 @@ bool bdrv_all_can_snapshot(bool has_devices, strList *devices,
g_autoptr(GList) bdrvs = NULL; g_autoptr(GList) bdrvs = NULL;
GList *iterbdrvs; GList *iterbdrvs;
GLOBAL_STATE_CODE();
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) { if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
return false; return false;
} }
@ -549,6 +568,8 @@ int bdrv_all_delete_snapshot(const char *name,
g_autoptr(GList) bdrvs = NULL; g_autoptr(GList) bdrvs = NULL;
GList *iterbdrvs; GList *iterbdrvs;
GLOBAL_STATE_CODE();
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) { if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
return -1; return -1;
} }
@ -588,6 +609,8 @@ int bdrv_all_goto_snapshot(const char *name,
g_autoptr(GList) bdrvs = NULL; g_autoptr(GList) bdrvs = NULL;
GList *iterbdrvs; GList *iterbdrvs;
GLOBAL_STATE_CODE();
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) { if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
return -1; return -1;
} }
@ -622,6 +645,8 @@ int bdrv_all_has_snapshot(const char *name,
g_autoptr(GList) bdrvs = NULL; g_autoptr(GList) bdrvs = NULL;
GList *iterbdrvs; GList *iterbdrvs;
GLOBAL_STATE_CODE();
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) { if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
return -1; return -1;
} }
@ -663,6 +688,7 @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
{ {
g_autoptr(GList) bdrvs = NULL; g_autoptr(GList) bdrvs = NULL;
GList *iterbdrvs; GList *iterbdrvs;
GLOBAL_STATE_CODE();
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) { if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
return -1; return -1;
@ -703,6 +729,8 @@ BlockDriverState *bdrv_all_find_vmstate_bs(const char *vmstate_bs,
g_autoptr(GList) bdrvs = NULL; g_autoptr(GList) bdrvs = NULL;
GList *iterbdrvs; GList *iterbdrvs;
GLOBAL_STATE_CODE();
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) { if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
return NULL; return NULL;
} }

View File

@ -45,6 +45,13 @@ typedef struct QEMUSnapshotInfo {
uint64_t icount; /* record/replay step */ uint64_t icount; /* record/replay step */
} QEMUSnapshotInfo; } QEMUSnapshotInfo;
/*
* Global state (GS) API. These functions run under the BQL.
*
* See include/block/block-global-state.h for more information about
* the GS API.
*/
int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info, int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
const char *name); const char *name);
bool bdrv_snapshot_find_by_id_and_name(BlockDriverState *bs, bool bdrv_snapshot_find_by_id_and_name(BlockDriverState *bs,
@ -73,9 +80,11 @@ int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs,
Error **errp); Error **errp);
/* Group operations. All block drivers are involved. /*
* Group operations. All block drivers are involved.
* These functions will properly handle dataplane (take aio_context_acquire * These functions will properly handle dataplane (take aio_context_acquire
* when appropriate for appropriate block drivers */ * when appropriate for appropriate block drivers
*/
bool bdrv_all_can_snapshot(bool has_devices, strList *devices, bool bdrv_all_can_snapshot(bool has_devices, strList *devices,
Error **errp); Error **errp);

View File

@ -2808,6 +2808,8 @@ bool save_snapshot(const char *name, bool overwrite, const char *vmstate,
g_autoptr(GDateTime) now = g_date_time_new_now_local(); g_autoptr(GDateTime) now = g_date_time_new_now_local();
AioContext *aio_context; AioContext *aio_context;
GLOBAL_STATE_CODE();
if (migration_is_blocked(errp)) { if (migration_is_blocked(errp)) {
return false; return false;
} }