diff --git a/block.c b/block.c index b1ef85c8da9178f66baf34a651321311c5f43276..cacf11bd99cf73bca926a85146f50f534062e31d 100644 --- a/block.c +++ b/block.c @@ -1631,9 +1631,11 @@ int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf, BlockDriver *drv = bs->drv; if (!drv) return -ENOMEDIUM; - if (!drv->bdrv_save_vmstate) - return -ENOTSUP; - return drv->bdrv_save_vmstate(bs, buf, pos, size); + if (drv->bdrv_save_vmstate) + return drv->bdrv_save_vmstate(bs, buf, pos, size); + if (bs->file) + return bdrv_save_vmstate(bs->file, buf, pos, size); + return -ENOTSUP; } int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf, @@ -1642,9 +1644,11 @@ int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf, BlockDriver *drv = bs->drv; if (!drv) return -ENOMEDIUM; - if (!drv->bdrv_load_vmstate) - return -ENOTSUP; - return drv->bdrv_load_vmstate(bs, buf, pos, size); + if (drv->bdrv_load_vmstate) + return drv->bdrv_load_vmstate(bs, buf, pos, size); + if (bs->file) + return bdrv_load_vmstate(bs->file, buf, pos, size); + return -ENOTSUP; } void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event) @@ -1668,20 +1672,37 @@ int bdrv_snapshot_create(BlockDriverState *bs, BlockDriver *drv = bs->drv; if (!drv) return -ENOMEDIUM; - if (!drv->bdrv_snapshot_create) - return -ENOTSUP; - return drv->bdrv_snapshot_create(bs, sn_info); + if (drv->bdrv_snapshot_create) + return drv->bdrv_snapshot_create(bs, sn_info); + if (bs->file) + return bdrv_snapshot_create(bs->file, sn_info); + return -ENOTSUP; } int bdrv_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) { BlockDriver *drv = bs->drv; + int ret, open_ret; + if (!drv) return -ENOMEDIUM; - if (!drv->bdrv_snapshot_goto) - return -ENOTSUP; - return drv->bdrv_snapshot_goto(bs, snapshot_id); + if (drv->bdrv_snapshot_goto) + return drv->bdrv_snapshot_goto(bs, snapshot_id); + + if (bs->file) { + drv->bdrv_close(bs); + ret = bdrv_snapshot_goto(bs->file, snapshot_id); + open_ret = drv->bdrv_open(bs, bs->open_flags); + if (open_ret < 0) { + bdrv_delete(bs->file); + bs->drv = NULL; + return open_ret; + } + return ret; + } + + return -ENOTSUP; } int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) @@ -1689,9 +1710,11 @@ int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) BlockDriver *drv = bs->drv; if (!drv) return -ENOMEDIUM; - if (!drv->bdrv_snapshot_delete) - return -ENOTSUP; - return drv->bdrv_snapshot_delete(bs, snapshot_id); + if (drv->bdrv_snapshot_delete) + return drv->bdrv_snapshot_delete(bs, snapshot_id); + if (bs->file) + return bdrv_snapshot_delete(bs->file, snapshot_id); + return -ENOTSUP; } int bdrv_snapshot_list(BlockDriverState *bs, @@ -1700,9 +1723,11 @@ int bdrv_snapshot_list(BlockDriverState *bs, BlockDriver *drv = bs->drv; if (!drv) return -ENOMEDIUM; - if (!drv->bdrv_snapshot_list) - return -ENOTSUP; - return drv->bdrv_snapshot_list(bs, psn_info); + if (drv->bdrv_snapshot_list) + return drv->bdrv_snapshot_list(bs, psn_info); + if (bs->file) + return bdrv_snapshot_list(bs->file, psn_info); + return -ENOTSUP; } #define NB_SUFFIXES 4