From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38252) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b7fmE-0006ER-CS for qemu-devel@nongnu.org; Tue, 31 May 2016 05:15:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b7fm9-0005VC-Kl for qemu-devel@nongnu.org; Tue, 31 May 2016 05:15:54 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:22278 helo=relay.sw.ru) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b7fm9-0005V4-74 for qemu-devel@nongnu.org; Tue, 31 May 2016 05:15:49 -0400 From: "Denis V. Lunev" Date: Tue, 31 May 2016 12:15:21 +0300 Message-Id: <1464686130-12265-3-git-send-email-den@openvz.org> In-Reply-To: <1464686130-12265-1-git-send-email-den@openvz.org> References: <1464686130-12265-1-git-send-email-den@openvz.org> Subject: [Qemu-devel] [PATCH 02/11] block/io: add bdrv_co_write_compressed List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: den@openvz.org, Pavel Butsykin , Jeff Cody , Markus Armbruster , Eric Blake , John Snow , Stefan Hajnoczi , Kevin Wolf From: Pavel Butsykin This patch just adds the interface to the bdrv_co_pwritev_compressed, which is currently not used but will be useful for safe implementation of the bdrv_co_write_compressed callback in format drivers. Signed-off-by: Pavel Butsykin Signed-off-by: Denis V. Lunev CC: Jeff Cody CC: Markus Armbruster CC: Eric Blake CC: John Snow CC: Stefan Hajnoczi CC: Kevin Wolf --- block/io.c | 78 +++++++++++++++++++++++++++++++++++++++++++---- include/block/block_int.h | 5 +++ qemu-img.c | 2 +- 3 files changed, 78 insertions(+), 7 deletions(-) diff --git a/block/io.c b/block/io.c index c5bb6ae..54cd9a4 100644 --- a/block/io.c +++ b/block/io.c @@ -1779,8 +1779,8 @@ int bdrv_is_allocated_above(BlockDriverState *top, return 0; } -int bdrv_pwrite_compressed(BlockDriverState *bs, int64_t offset, - const void *buf, int count) +int coroutine_fn bdrv_co_pwritev_compressed(BlockDriverState *bs, + int64_t offset, unsigned int bytes, QEMUIOVector *qiov) { BlockDriver *drv = bs->drv; int ret; @@ -1788,18 +1788,84 @@ int bdrv_pwrite_compressed(BlockDriverState *bs, int64_t offset, if (!drv) { return -ENOMEDIUM; } - if (!drv->bdrv_write_compressed) { + + if (!drv->bdrv_co_write_compressed) { return -ENOTSUP; } - ret = bdrv_check_byte_request(bs, offset, count); + + ret = bdrv_check_byte_request(bs, offset, bytes); if (ret < 0) { return ret; } assert(QLIST_EMPTY(&bs->dirty_bitmaps)); + assert(qemu_in_coroutine()); + + return drv->bdrv_co_write_compressed(bs, offset >> BDRV_SECTOR_BITS, + bytes >> BDRV_SECTOR_BITS, qiov); +} + +typedef struct BdrvWriteCompressedCo { + BlockDriverState *bs; + int64_t offset; + QEMUIOVector *qiov; + int ret; +} BdrvWriteCompressedCo; + +static void bdrv_write_compressed_co_entry(void *opaque) +{ + BdrvWriteCompressedCo *co = opaque; + + co->ret = bdrv_co_pwritev_compressed(co->bs, co->offset, co->qiov->size, + co->qiov); +} + +int bdrv_pwrite_compressed(BlockDriverState *bs, int64_t offset, + const void *buf, int count) +{ + BdrvWriteCompressedCo data; + QEMUIOVector qiov; + BlockDriver *drv = bs->drv; + struct iovec iov = { + .iov_base = (void *)buf, + .iov_len = count, + }; + qemu_iovec_init_external(&qiov, &iov, 1); - return drv->bdrv_write_compressed(bs, offset >> BDRV_SECTOR_BITS, buf, - count >> BDRV_SECTOR_BITS); + data = (BdrvWriteCompressedCo) { + .bs = bs, + .offset = offset, + .qiov = &qiov, + .ret = -EINPROGRESS, + }; + + if (!drv) { + return -ENOMEDIUM; + } + + if (drv->bdrv_write_compressed) { + int ret = bdrv_check_byte_request(bs, offset, count); + if (ret < 0) { + return ret; + } + assert(QLIST_EMPTY(&bs->dirty_bitmaps)); + return drv->bdrv_write_compressed(bs, offset >> BDRV_SECTOR_BITS, buf, + count >> BDRV_SECTOR_BITS); + } + + if (qemu_in_coroutine()) { + /* Fast-path if already in coroutine context */ + bdrv_write_compressed_co_entry(&data); + } else { + AioContext *aio_context = bdrv_get_aio_context(bs); + + Coroutine *co = qemu_coroutine_create(bdrv_write_compressed_co_entry); + qemu_coroutine_enter(co, &data); + while (data.ret == -EINPROGRESS) { + aio_poll(aio_context, true); + } + } + return data.ret; } int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf, diff --git a/include/block/block_int.h b/include/block/block_int.h index 30a9717..ccba9c9 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -207,6 +207,9 @@ struct BlockDriver { int (*bdrv_write_compressed)(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors); + int coroutine_fn (*bdrv_co_write_compressed)(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); + int (*bdrv_snapshot_create)(BlockDriverState *bs, QEMUSnapshotInfo *sn_info); int (*bdrv_snapshot_goto)(BlockDriverState *bs, @@ -535,6 +538,8 @@ int coroutine_fn bdrv_co_preadv(BlockDriverState *bs, int coroutine_fn bdrv_co_pwritev(BlockDriverState *bs, int64_t offset, unsigned int bytes, QEMUIOVector *qiov, BdrvRequestFlags flags); +int coroutine_fn bdrv_co_pwritev_compressed(BlockDriverState *bs, + int64_t offset, unsigned int bytes, QEMUIOVector *qiov); int get_tmp_filename(char *filename, int size); BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size, diff --git a/qemu-img.c b/qemu-img.c index eb744d4..ab54027 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -2024,7 +2024,7 @@ static int img_convert(int argc, char **argv) const char *preallocation = qemu_opt_get(opts, BLOCK_OPT_PREALLOC); - if (!drv->bdrv_write_compressed) { + if (!drv->bdrv_write_compressed && !drv->bdrv_co_write_compressed) { error_report("Compression not supported for this file format"); ret = -1; goto out; -- 2.1.4