aboutsummaryrefslogtreecommitdiff
path: root/migration/channel-block.c
diff options
context:
space:
mode:
Diffstat (limited to 'migration/channel-block.c')
-rw-r--r--migration/channel-block.c48
1 files changed, 46 insertions, 2 deletions
diff --git a/migration/channel-block.c b/migration/channel-block.c
index fff8d87..9cf383d 100644
--- a/migration/channel-block.c
+++ b/migration/channel-block.c
@@ -30,6 +30,7 @@ qio_channel_block_new(BlockDriverState *bs)
QIOChannelBlock *ioc;
ioc = QIO_CHANNEL_BLOCK(object_new(TYPE_QIO_CHANNEL_BLOCK));
+ qio_channel_set_feature(QIO_CHANNEL(ioc), QIO_CHANNEL_FEATURE_SEEKABLE);
bdrv_ref(bs);
ioc->bs = bs;
@@ -96,6 +97,47 @@ qio_channel_block_writev(QIOChannel *ioc,
return qiov.size;
}
+static ssize_t
+qio_channel_block_preadv(QIOChannel *ioc,
+ const struct iovec *iov,
+ size_t niov,
+ off_t offset,
+ Error **errp)
+{
+ QIOChannelBlock *bioc = QIO_CHANNEL_BLOCK(ioc);
+ QEMUIOVector qiov;
+ int ret;
+
+ qemu_iovec_init_external(&qiov, (struct iovec *)iov, niov);
+ ret = bdrv_readv_vmstate(bioc->bs, &qiov, offset);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "bdrv_readv_vmstate failed");
+ return -1;
+ }
+
+ return qiov.size;
+}
+
+static ssize_t
+qio_channel_block_pwritev(QIOChannel *ioc,
+ const struct iovec *iov,
+ size_t niov,
+ off_t offset,
+ Error **errp)
+{
+ QIOChannelBlock *bioc = QIO_CHANNEL_BLOCK(ioc);
+ QEMUIOVector qiov;
+ int ret;
+
+ qemu_iovec_init_external(&qiov, (struct iovec *)iov, niov);
+ ret = bdrv_writev_vmstate(bioc->bs, &qiov, offset);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "bdrv_writev_vmstate failed");
+ return -1;
+ }
+
+ return qiov.size;
+}
static int
qio_channel_block_set_blocking(QIOChannel *ioc,
@@ -123,7 +165,7 @@ qio_channel_block_seek(QIOChannel *ioc,
bioc->offset = offset;
break;
case SEEK_CUR:
- bioc->offset += whence;
+ bioc->offset += offset;
break;
case SEEK_END:
error_setg(errp, "Size of VMstate region is unknown");
@@ -170,13 +212,15 @@ qio_channel_block_set_aio_fd_handler(QIOChannel *ioc,
static void
qio_channel_block_class_init(ObjectClass *klass,
- void *class_data G_GNUC_UNUSED)
+ const void *class_data G_GNUC_UNUSED)
{
QIOChannelClass *ioc_klass = QIO_CHANNEL_CLASS(klass);
ioc_klass->io_writev = qio_channel_block_writev;
ioc_klass->io_readv = qio_channel_block_readv;
ioc_klass->io_set_blocking = qio_channel_block_set_blocking;
+ ioc_klass->io_preadv = qio_channel_block_preadv;
+ ioc_klass->io_pwritev = qio_channel_block_pwritev;
ioc_klass->io_seek = qio_channel_block_seek;
ioc_klass->io_close = qio_channel_block_close;
ioc_klass->io_set_aio_fd_handler = qio_channel_block_set_aio_fd_handler;