From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:42426) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ROv1y-0006kN-Vm for qemu-devel@nongnu.org; Fri, 11 Nov 2011 12:36:48 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ROv1x-0000Ld-Al for qemu-devel@nongnu.org; Fri, 11 Nov 2011 12:36:46 -0500 Received: from mx1.redhat.com ([209.132.183.28]:52070) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ROv1w-0000LX-Qv for qemu-devel@nongnu.org; Fri, 11 Nov 2011 12:36:45 -0500 From: Kevin Wolf Date: Fri, 11 Nov 2011 18:39:27 +0100 Message-Id: <1321033168-8739-16-git-send-email-kwolf@redhat.com> In-Reply-To: <1321033168-8739-1-git-send-email-kwolf@redhat.com> References: <1321033168-8739-1-git-send-email-kwolf@redhat.com> Subject: [Qemu-devel] [PATCH 15/16] block: Introduce bdrv_co_flush_to_os List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: anthony@codemonkey.ws Cc: kwolf@redhat.com, qemu-devel@nongnu.org qcow2 has a writeback metadata cache, so flushing a qcow2 image actually consists of writing back that cache to the protocol and only then flushes the protocol in order to get everything stable on disk. This introduces a separate bdrv_co_flush_to_os to reflect the split. Signed-off-by: Kevin Wolf --- block.c | 13 ++++++++++++- block/qcow2.c | 10 ++++++++-- block_int.h | 7 +++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/block.c b/block.c index 6521eaa..b1a4629 100644 --- a/block.c +++ b/block.c @@ -2789,11 +2789,22 @@ static void coroutine_fn bdrv_flush_co_entry(void *opaque) int coroutine_fn bdrv_co_flush(BlockDriverState *bs) { + int ret; + if (bs->open_flags & BDRV_O_NO_FLUSH) { return 0; } else if (!bs->drv) { return 0; - } else if (bs->drv->bdrv_co_flush_to_disk) { + } + + if (bs->drv->bdrv_co_flush_to_os) { + ret = bs->drv->bdrv_co_flush_to_os(bs); + if (ret < 0) { + return ret; + } + } + + if (bs->drv->bdrv_co_flush_to_disk) { return bs->drv->bdrv_co_flush_to_disk(bs); } else if (bs->drv->bdrv_aio_flush) { BlockDriverAIOCB *acb; diff --git a/block/qcow2.c b/block/qcow2.c index f7f73fe..5c784ee 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1105,7 +1105,7 @@ fail: return ret; } -static int qcow2_co_flush(BlockDriverState *bs) +static int qcow2_co_flush_to_os(BlockDriverState *bs) { BDRVQcowState *s = bs->opaque; int ret; @@ -1124,6 +1124,11 @@ static int qcow2_co_flush(BlockDriverState *bs) } qemu_co_mutex_unlock(&s->lock); + return 0; +} + +static int qcow2_co_flush_to_disk(BlockDriverState *bs) +{ return bdrv_co_flush(bs->file); } @@ -1245,7 +1250,8 @@ static BlockDriver bdrv_qcow2 = { .bdrv_co_readv = qcow2_co_readv, .bdrv_co_writev = qcow2_co_writev, - .bdrv_co_flush_to_disk = qcow2_co_flush, + .bdrv_co_flush_to_os = qcow2_co_flush_to_os, + .bdrv_co_flush_to_disk = qcow2_co_flush_to_disk, .bdrv_co_discard = qcow2_co_discard, .bdrv_truncate = qcow2_truncate, diff --git a/block_int.h b/block_int.h index 5aadc1f..1ec4921 100644 --- a/block_int.h +++ b/block_int.h @@ -93,6 +93,13 @@ struct BlockDriver { */ int coroutine_fn (*bdrv_co_flush_to_disk)(BlockDriverState *bs); + /* + * Flushes all internal caches to the OS. The data may still sit in a + * writeback cache of the host OS, but it will survive a crash of the qemu + * process. + */ + int coroutine_fn (*bdrv_co_flush_to_os)(BlockDriverState *bs); + int (*bdrv_aio_multiwrite)(BlockDriverState *bs, BlockRequest *reqs, int num_reqs); int (*bdrv_merge_requests)(BlockDriverState *bs, BlockRequest* a, -- 1.7.6.4