@@ -1683,9 +1683,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,
@@ -1694,9 +1696,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)
@@ -1720,20 +1724,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);
+ bs->drv = NULL;
+ return open_ret;
+ }
+ return ret;
+ }
+
+ return -ENOTSUP;
}
int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
@@ -1741,9 +1762,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,
@@ -1752,9 +1775,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