From patchwork Thu Jan 20 17:10:12 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 79731 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id ACD4FB713A for ; Fri, 21 Jan 2011 04:18:12 +1100 (EST) Received: from localhost ([127.0.0.1]:49229 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Pfy8j-0006o2-Va for incoming@patchwork.ozlabs.org; Thu, 20 Jan 2011 12:17:42 -0500 Received: from [140.186.70.92] (port=33800 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Pfy0b-0004Kw-To for qemu-devel@nongnu.org; Thu, 20 Jan 2011 12:09:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Pfy0Z-00030J-6p for qemu-devel@nongnu.org; Thu, 20 Jan 2011 12:09:16 -0500 Received: from mx1.redhat.com ([209.132.183.28]:27989) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Pfy0Y-00030E-W6 for qemu-devel@nongnu.org; Thu, 20 Jan 2011 12:09:15 -0500 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id p0KH8sES005400 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 20 Jan 2011 12:08:54 -0500 Received: from dhcp-5-188.str.redhat.com (vpn1-5-247.ams2.redhat.com [10.36.5.247]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p0KH8fIh026822; Thu, 20 Jan 2011 12:08:52 -0500 From: Kevin Wolf To: qemu-devel@nongnu.org Date: Thu, 20 Jan 2011 18:10:12 +0100 Message-Id: <1295543412-24012-4-git-send-email-kwolf@redhat.com> In-Reply-To: <1295543412-24012-1-git-send-email-kwolf@redhat.com> References: <1295543412-24012-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Cc: kwolf@redhat.com, stefanha@gmail.com Subject: [Qemu-devel] [PATCH v4 3/3] qcow2: Batch flushes for COW X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org qcow2 calls bdrv_flush() after performing COW in order to ensure that the L2 table change is never written before the copy is safe on disk. Now that the L2 table is cached, we can wait with flushing until we write out the next L2 table. Signed-off-by: Kevin Wolf --- block/qcow2-cache.c | 20 +++++++++++++++++--- block/qcow2-cluster.c | 2 +- block/qcow2.h | 1 + 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c index 5f1740b..8f2955b 100644 --- a/block/qcow2-cache.c +++ b/block/qcow2-cache.c @@ -38,6 +38,7 @@ struct Qcow2Cache { int size; Qcow2CachedTable* entries; struct Qcow2Cache* depends; + bool depends_on_flush; bool writethrough; }; @@ -85,13 +86,15 @@ static int qcow2_cache_flush_dependency(BlockDriverState *bs, Qcow2Cache *c) } c->depends = NULL; + c->depends_on_flush = false; + return 0; } static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i) { BDRVQcowState *s = bs->opaque; - int ret; + int ret = 0; if (!c->entries[i].dirty || !c->entries[i].offset) { return 0; @@ -99,11 +102,17 @@ static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i) if (c->depends) { ret = qcow2_cache_flush_dependency(bs, c); - if (ret < 0) { - return ret; + } else if (c->depends_on_flush) { + ret = bdrv_flush(bs->file); + if (ret >= 0) { + c->depends_on_flush = false; } } + if (ret < 0) { + return ret; + } + if (c == s->refcount_block_cache) { BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_UPDATE_PART); } else if (c == s->l2_table_cache) { @@ -167,6 +176,11 @@ int qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cache *c, return 0; } +void qcow2_cache_depends_on_flush(Qcow2Cache *c) +{ + c->depends_on_flush = true; +} + static int qcow2_cache_find_entry_to_replace(Qcow2Cache *c) { int i; diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 7fa4fa1..716562f 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -637,7 +637,7 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m) * handled. */ if (cow) { - bdrv_flush(bs->file); + qcow2_cache_depends_on_flush(s->l2_table_cache); } qcow2_cache_set_dependency(bs, s->l2_table_cache, s->refcount_block_cache); diff --git a/block/qcow2.h b/block/qcow2.h index 11cbce3..6d80120 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -229,6 +229,7 @@ void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table); int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c); int qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cache *c, Qcow2Cache *dependency); +void qcow2_cache_depends_on_flush(Qcow2Cache *c); int qcow2_cache_get(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset, void **table);