diff mbox

[1/2,v2] block: flush backing_hd in the right place

Message ID 20100112181306.GA1849@lst.de
State New
Headers show

Commit Message

Christoph Hellwig Jan. 12, 2010, 6:13 p.m. UTC
The backing device is only modified from bdrv_commit.  So instead of
flushing it every time bdrv_flush is called for the front-end device
only flush it after we're written data to it in bdrv_commit.

Also flush the frontend image if we have a make_empty method that
possibly writes to it.

Signed-off-by: Christoph Hellwig <hch@lst.de>

Comments

Kevin Wolf Jan. 13, 2010, 9:50 a.m. UTC | #1
Am 12.01.2010 19:13, schrieb Christoph Hellwig:
> The backing device is only modified from bdrv_commit.  So instead of
> flushing it every time bdrv_flush is called for the front-end device
> only flush it after we're written data to it in bdrv_commit.
> 
> Also flush the frontend image if we have a make_empty method that
> possibly writes to it.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> 
> Index: qemu/block.c
> ===================================================================
> --- qemu.orig/block.c	2010-01-12 19:08:07.363003775 +0100
> +++ qemu/block.c	2010-01-12 19:09:10.836255948 +0100
> @@ -589,6 +589,7 @@ int bdrv_commit(BlockDriverState *bs)
>      BlockDriver *drv = bs->drv;
>      int64_t i, total_sectors;
>      int n, j;
> +    int ret = 0;
>      unsigned char sector[512];
>  
>      if (!drv)
> @@ -620,10 +621,18 @@ int bdrv_commit(BlockDriverState *bs)
>          }
>      }
>  
> -    if (drv->bdrv_make_empty)
> -	return drv->bdrv_make_empty(bs);
> +    if (drv->bdrv_make_empty) {
> +	ret = drv->bdrv_make_empty(bs);
> +        bdrv_flush(bs);
> +    }

Indentation is off here (but it already was before the patch). The logic
looks good to me now.

Kevin
diff mbox

Patch

Index: qemu/block.c
===================================================================
--- qemu.orig/block.c	2010-01-12 19:08:07.363003775 +0100
+++ qemu/block.c	2010-01-12 19:09:10.836255948 +0100
@@ -589,6 +589,7 @@  int bdrv_commit(BlockDriverState *bs)
     BlockDriver *drv = bs->drv;
     int64_t i, total_sectors;
     int n, j;
+    int ret = 0;
     unsigned char sector[512];
 
     if (!drv)
@@ -620,10 +621,18 @@  int bdrv_commit(BlockDriverState *bs)
         }
     }
 
-    if (drv->bdrv_make_empty)
-	return drv->bdrv_make_empty(bs);
+    if (drv->bdrv_make_empty) {
+	ret = drv->bdrv_make_empty(bs);
+        bdrv_flush(bs);
+    }
 
-    return 0;
+    /*
+     * Make sure all data we wrote to the backing device is actually
+     * stable on disk.
+     */
+    if (bs->backing_hd)
+        bdrv_flush(bs->backing_hd);
+    return ret;
 }
 
 static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
@@ -1124,12 +1133,8 @@  const char *bdrv_get_device_name(BlockDr
 
 void bdrv_flush(BlockDriverState *bs)
 {
-    if (!bs->drv)
-        return;
-    if (bs->drv->bdrv_flush)
+    if (bs->drv && bs->drv->bdrv_flush)
         bs->drv->bdrv_flush(bs);
-    if (bs->backing_hd)
-        bdrv_flush(bs->backing_hd);
 }
 
 void bdrv_flush_all(void)
@@ -1806,11 +1811,6 @@  BlockDriverAIOCB *bdrv_aio_flush(BlockDr
 
     if (!drv)
         return NULL;
-
-    /*
-     * Note that unlike bdrv_flush the driver is reponsible for flushing a
-     * backing image if it exists.
-     */
     return drv->bdrv_aio_flush(bs, cb, opaque);
 }