qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 1/7] block: only force IO completion in .bdrv_trunca


From: Jeff Cody
Subject: [Qemu-devel] [PATCH 1/7] block: only force IO completion in .bdrv_truncate if we are shrinking
Date: Wed, 6 Mar 2013 09:47:13 -0500

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 <address@hidden>
---
 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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]