From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:53699) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UDFct-0000pa-Dw for qemu-devel@nongnu.org; Wed, 06 Mar 2013 09:47:34 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UDFcm-0002NM-8J for qemu-devel@nongnu.org; Wed, 06 Mar 2013 09:47:27 -0500 Received: from mx1.redhat.com ([209.132.183.28]:61337) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UDFcl-0002NF-V7 for qemu-devel@nongnu.org; Wed, 06 Mar 2013 09:47:20 -0500 From: Jeff Cody Date: Wed, 6 Mar 2013 09:47:13 -0500 Message-Id: In-Reply-To: References: Subject: [Qemu-devel] [PATCH 1/7] block: only force IO completion in .bdrv_truncate if we are shrinking List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kwolf@redhat.com, sw@weilnetz.de, pl@dlhnet.de, stefanha@redhat.com, pbonzini@redhat.com Commit 9a665b2b made bdrv_truncate() call bdrv_drain_all(), but this breaks QCOW images, as well other future image formats (such as VHDX) that may call bdrv_truncate(bs->file) from within a read/write operation. For example, QCOW will cause an assert, due to tracked_requests not being empty (since the read/write that called bdrv_truncate() is still in progress). This modifies the check to only force the bdrv_drain_all() call if the BDS to be truncated is not growable, or if we are shrinking the BDS. Otherwise, if we are just growing the file, allow it to happen without forcing a call to bdrv_drain_all(). Signed-off-by: Jeff Cody --- block.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/block.c b/block.c index 124a9eb..dce844c 100644 --- a/block.c +++ b/block.c @@ -2450,8 +2450,14 @@ int bdrv_truncate(BlockDriverState *bs, int64_t offset) if (bdrv_in_use(bs)) return -EBUSY; - /* There better not be any in-flight IOs when we truncate the device. */ - bdrv_drain_all(); + /* Don't force a drain if we are just growing the file - otherwise, + * using bdrv_truncate() from within a block driver in a read/write + * operation will cause an assert, because bdrv_drain_all() will assert if + * a tracked_request is still in progress. */ + if (!bs->growable || offset < bdrv_getlength(bs)) { + /* There better not be any in-flight IOs when we truncate the device. */ + bdrv_drain_all(); + } ret = drv->bdrv_truncate(bs, offset); if (ret == 0) { -- 1.8.1.4