From patchwork Sat May 14 12:45:49 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Denis V. Lunev" X-Patchwork-Id: 622232 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3r6RNs48XDz9t87 for ; Sat, 14 May 2016 22:48:45 +1000 (AEST) Received: from localhost ([::1]:37636 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b1Yzq-0001TG-O0 for incoming@patchwork.ozlabs.org; Sat, 14 May 2016 08:48:42 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44128) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b1Yxa-00050u-KJ for qemu-devel@nongnu.org; Sat, 14 May 2016 08:46:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b1YxU-0006rP-QP for qemu-devel@nongnu.org; Sat, 14 May 2016 08:46:21 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:40372 helo=relay.sw.ru) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b1YxU-0006qx-CW for qemu-devel@nongnu.org; Sat, 14 May 2016 08:46:16 -0400 Received: from irbis.sw.ru ([10.24.38.119]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id u4ECjviW001269; Sat, 14 May 2016 15:46:01 +0300 (MSK) From: "Denis V. Lunev" To: qemu-devel@nongnu.org Date: Sat, 14 May 2016 15:45:49 +0300 Message-Id: <1463229957-14253-2-git-send-email-den@openvz.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1463229957-14253-1-git-send-email-den@openvz.org> References: <1463229957-14253-1-git-send-email-den@openvz.org> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH 01/10] block/io: add bdrv_co_write_compressed X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Pavel Butsykin , Jeff Cody , Markus Armbruster , Stefan Hajnoczi , den@openvz.org, John Snow Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Butsykin This patch just adds the interface to the bdrv_co_write_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 | 71 ++++++++++++++++++++++++++++++++++++++++++++--- include/block/block.h | 2 ++ include/block/block_int.h | 3 ++ qemu-img.c | 2 +- 4 files changed, 73 insertions(+), 5 deletions(-) diff --git a/block/io.c b/block/io.c index cd6d71a..88af10c 100644 --- a/block/io.c +++ b/block/io.c @@ -1828,8 +1828,8 @@ int bdrv_is_allocated_above(BlockDriverState *top, return 0; } -int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, - const uint8_t *buf, int nb_sectors) +int bdrv_co_write_compressed(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov) { BlockDriver *drv = bs->drv; int ret; @@ -1837,7 +1837,7 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, if (!drv) { return -ENOMEDIUM; } - if (!drv->bdrv_write_compressed) { + if (!drv->bdrv_co_write_compressed) { return -ENOTSUP; } ret = bdrv_check_request(bs, sector_num, nb_sectors); @@ -1846,8 +1846,71 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, } assert(QLIST_EMPTY(&bs->dirty_bitmaps)); + assert(qemu_in_coroutine()); + + return drv->bdrv_co_write_compressed(bs, sector_num, nb_sectors, qiov); +} + +typedef struct BdrvWriteCompressedCo { + BlockDriverState *bs; + int64_t sector_num; + const uint8_t *buf; + int nb_sectors; + int ret; +} BdrvWriteCompressedCo; + +static void bdrv_write_compressed_co_entry(void *opaque) +{ + BdrvWriteCompressedCo *co = opaque; + QEMUIOVector qiov; + struct iovec iov = { + .iov_base = (uint8_t *)co->buf, + .iov_len = co->nb_sectors << BDRV_SECTOR_BITS, + }; + qemu_iovec_init_external(&qiov, &iov, 1); + + co->ret = bdrv_co_write_compressed(co->bs, co->sector_num, + co->nb_sectors, &qiov); +} + +int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, + const uint8_t *buf, int nb_sectors) +{ + BlockDriver *drv = bs->drv; + BdrvWriteCompressedCo data = { + .bs = bs, + .sector_num = sector_num, + .buf = buf, + .nb_sectors = nb_sectors, + .ret = -EINPROGRESS, + }; + + if (!drv) { + return -ENOMEDIUM; + } + + if (drv->bdrv_write_compressed) { + int ret = bdrv_check_request(bs, sector_num, nb_sectors); + if (ret < 0) { + return ret; + } + assert(QLIST_EMPTY(&bs->dirty_bitmaps)); + return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors); + } - return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors); + 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.h b/include/block/block.h index b210832..ae67fd8 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -423,6 +423,8 @@ const char *bdrv_get_device_or_node_name(const BlockDriverState *bs); int bdrv_get_flags(BlockDriverState *bs); int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors); +int bdrv_co_write_compressed(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov); int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi); ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs); void bdrv_round_to_clusters(BlockDriverState *bs, diff --git a/include/block/block_int.h b/include/block/block_int.h index a029c20..3c93ddb 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -208,6 +208,9 @@ struct BlockDriver { int (*bdrv_write_compressed)(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors); + int (*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, diff --git a/qemu-img.c b/qemu-img.c index 4792366..0d38eac 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -2022,7 +2022,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;