mirror of https://github.com/xemu-project/xemu.git
block: Make bdrv_load/save_vmstate coroutine_fns
This allows drivers to share code between normal I/O and vmstate accesses. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Fam Zheng <famz@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
b433d9424d
commit
1a8ae82217
80
block/io.c
80
block/io.c
|
@ -1840,6 +1840,62 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
|
||||||
return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
|
return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct BdrvVmstateCo {
|
||||||
|
BlockDriverState *bs;
|
||||||
|
QEMUIOVector *qiov;
|
||||||
|
int64_t pos;
|
||||||
|
bool is_read;
|
||||||
|
int ret;
|
||||||
|
} BdrvVmstateCo;
|
||||||
|
|
||||||
|
static int coroutine_fn
|
||||||
|
bdrv_co_rw_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos,
|
||||||
|
bool is_read)
|
||||||
|
{
|
||||||
|
BlockDriver *drv = bs->drv;
|
||||||
|
|
||||||
|
if (!drv) {
|
||||||
|
return -ENOMEDIUM;
|
||||||
|
} else if (drv->bdrv_load_vmstate) {
|
||||||
|
return is_read ? drv->bdrv_load_vmstate(bs, qiov, pos)
|
||||||
|
: drv->bdrv_save_vmstate(bs, qiov, pos);
|
||||||
|
} else if (bs->file) {
|
||||||
|
return bdrv_co_rw_vmstate(bs->file->bs, qiov, pos, is_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void coroutine_fn bdrv_co_rw_vmstate_entry(void *opaque)
|
||||||
|
{
|
||||||
|
BdrvVmstateCo *co = opaque;
|
||||||
|
co->ret = bdrv_co_rw_vmstate(co->bs, co->qiov, co->pos, co->is_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
bdrv_rw_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos,
|
||||||
|
bool is_read)
|
||||||
|
{
|
||||||
|
if (qemu_in_coroutine()) {
|
||||||
|
return bdrv_co_rw_vmstate(bs, qiov, pos, is_read);
|
||||||
|
} else {
|
||||||
|
BdrvVmstateCo data = {
|
||||||
|
.bs = bs,
|
||||||
|
.qiov = qiov,
|
||||||
|
.pos = pos,
|
||||||
|
.is_read = is_read,
|
||||||
|
.ret = -EINPROGRESS,
|
||||||
|
};
|
||||||
|
Coroutine *co = qemu_coroutine_create(bdrv_co_rw_vmstate_entry);
|
||||||
|
|
||||||
|
qemu_coroutine_enter(co, &data);
|
||||||
|
while (data.ret == -EINPROGRESS) {
|
||||||
|
aio_poll(bdrv_get_aio_context(bs), true);
|
||||||
|
}
|
||||||
|
return data.ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
|
int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
|
||||||
int64_t pos, int size)
|
int64_t pos, int size)
|
||||||
{
|
{
|
||||||
|
@ -1862,17 +1918,7 @@ int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
|
||||||
|
|
||||||
int bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
|
int bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
|
||||||
{
|
{
|
||||||
BlockDriver *drv = bs->drv;
|
return bdrv_rw_vmstate(bs, qiov, pos, false);
|
||||||
|
|
||||||
if (!drv) {
|
|
||||||
return -ENOMEDIUM;
|
|
||||||
} else if (drv->bdrv_save_vmstate) {
|
|
||||||
return drv->bdrv_save_vmstate(bs, qiov, pos);
|
|
||||||
} else if (bs->file) {
|
|
||||||
return bdrv_writev_vmstate(bs->file->bs, qiov, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
|
int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
|
||||||
|
@ -1896,17 +1942,7 @@ int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
|
||||||
|
|
||||||
int bdrv_readv_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
|
int bdrv_readv_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
|
||||||
{
|
{
|
||||||
BlockDriver *drv = bs->drv;
|
return bdrv_rw_vmstate(bs, qiov, pos, true);
|
||||||
|
|
||||||
if (!drv) {
|
|
||||||
return -ENOMEDIUM;
|
|
||||||
} else if (drv->bdrv_load_vmstate) {
|
|
||||||
return drv->bdrv_load_vmstate(bs, qiov, pos);
|
|
||||||
} else if (bs->file) {
|
|
||||||
return bdrv_readv_vmstate(bs->file->bs, qiov, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
|
|
|
@ -224,10 +224,12 @@ struct BlockDriver {
|
||||||
int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
|
int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
|
||||||
ImageInfoSpecific *(*bdrv_get_specific_info)(BlockDriverState *bs);
|
ImageInfoSpecific *(*bdrv_get_specific_info)(BlockDriverState *bs);
|
||||||
|
|
||||||
int (*bdrv_save_vmstate)(BlockDriverState *bs, QEMUIOVector *qiov,
|
int coroutine_fn (*bdrv_save_vmstate)(BlockDriverState *bs,
|
||||||
int64_t pos);
|
QEMUIOVector *qiov,
|
||||||
int (*bdrv_load_vmstate)(BlockDriverState *bs, QEMUIOVector *qiov,
|
int64_t pos);
|
||||||
int64_t pos);
|
int coroutine_fn (*bdrv_load_vmstate)(BlockDriverState *bs,
|
||||||
|
QEMUIOVector *qiov,
|
||||||
|
int64_t pos);
|
||||||
|
|
||||||
int (*bdrv_change_backing_file)(BlockDriverState *bs,
|
int (*bdrv_change_backing_file)(BlockDriverState *bs,
|
||||||
const char *backing_file, const char *backing_fmt);
|
const char *backing_file, const char *backing_fmt);
|
||||||
|
|
Loading…
Reference in New Issue