summaryrefslogtreecommitdiff
path: root/block/qcow.c
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2016-05-31 14:42:08 +0200
committerKevin Wolf <kwolf@redhat.com>2016-07-05 16:46:27 +0200
commit18d51c4bac9d96302035de0faa11e3df98358f45 (patch)
tree729e91be407f51a7f9765e4c366b2d9fea6a4a6c /block/qcow.c
parentfbcbbf4e80a57298c605f4a2b486280d70c69d00 (diff)
downloadqemu-18d51c4bac9d96302035de0faa11e3df98358f45.tar.gz
block: Convert bdrv_write() to BdrvChild
Signed-off-by: Kevin Wolf <kwolf@redhat.com> Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'block/qcow.c')
-rw-r--r--block/qcow.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/block/qcow.c b/block/qcow.c
index 0db43f899d..674595ea54 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -913,6 +913,49 @@ static int qcow_make_empty(BlockDriverState *bs)
return 0;
}
+typedef struct QcowWriteCo {
+ BlockDriverState *bs;
+ int64_t sector_num;
+ const uint8_t *buf;
+ int nb_sectors;
+ int ret;
+} QcowWriteCo;
+
+static void qcow_write_co_entry(void *opaque)
+{
+ QcowWriteCo *co = opaque;
+ QEMUIOVector qiov;
+
+ struct iovec iov = (struct iovec) {
+ .iov_base = (uint8_t*) co->buf,
+ .iov_len = co->nb_sectors * BDRV_SECTOR_SIZE,
+ };
+ qemu_iovec_init_external(&qiov, &iov, 1);
+
+ co->ret = qcow_co_writev(co->bs, co->sector_num, co->nb_sectors, &qiov);
+}
+
+/* Wrapper for non-coroutine contexts */
+static int qcow_write(BlockDriverState *bs, int64_t sector_num,
+ const uint8_t *buf, int nb_sectors)
+{
+ Coroutine *co;
+ AioContext *aio_context = bdrv_get_aio_context(bs);
+ QcowWriteCo data = {
+ .bs = bs,
+ .sector_num = sector_num,
+ .buf = buf,
+ .nb_sectors = nb_sectors,
+ .ret = -EINPROGRESS,
+ };
+ co = qemu_coroutine_create(qcow_write_co_entry);
+ qemu_coroutine_enter(co, &data);
+ while (data.ret == -EINPROGRESS) {
+ aio_poll(aio_context, true);
+ }
+ return data.ret;
+}
+
/* XXX: put compressed sectors first, then all the cluster aligned
tables to avoid losing bytes in alignment */
static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
@@ -969,7 +1012,7 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
/* could not compress: write normal cluster */
- ret = bdrv_write(bs, sector_num, buf, s->cluster_sectors);
+ ret = qcow_write(bs, sector_num, buf, s->cluster_sectors);
if (ret < 0) {
goto fail;
}