block: flush backing_hd in the right place
PATCH 1/2 block: flush backing_hd in the right place
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.
block.c +7 -10
@@ -623,6 +623,12 @@ int bdrv_commit(BlockDriverState *bs)if (drv->bdrv_make_empty)return drv->bdrv_make_empty (bs); +/* +* 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 0 ; }
@@ -1124,12 +1130,8 @@ const char *bdrv_get_device_name(BlockDrvoid 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 +1808,6 @@ BlockDriverAIOCB *bdrv_aio_flush(BlockDrif (!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); }
Am 12.01.2010 13:49, schrieb Christoph Hellwig:
Quoted 13 lines
The backing device is only modified from
bdrv_commit. So instead of flushing it every timebdrv_flushis called for the front-end device only flush it after we're written data to it inbdrv_commit.Signed-off-by Christoph Hellwig <[email protected]>Index:
qemu/block.c
===================================================================block.c +0
-0@@ -623,6 +623,12 @@ int bdrv_commit(BlockDriverState *bs)if (drv->bdrv_make_empty)
block.c int bdrv_commit(BlockDriverState *bs) · line 633
Quoted 10 lines
block.c +6
-0return drv->bdrv_make_empty (bs); +/* +* 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 0 ; }
Format drivers with a bdrv_make_empty return before the flush, so it won't work for qcow1. Looks good otherwise.
If it has done a bdrv_make_empty we might also want to flush bs?
Kevin
Quoted 4 lines · Kevin Wolf
Quoted 4 lines
block.c +0
-0@@ -623,6 +623,12 @@ int bdrv_commit(BlockDriverState *bs)if (drv->bdrv_make_empty)return drv->bdrv_make_empty (bs);
Quoted 11 lines
block.c int bdrv_commit(BlockDriverState *bs) · line 633
Quoted 8 lines
block.c +6
-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 0 ; }Format drivers with a
bdrv_make_emptyreturn before the flush, so it won't work for qcow1. Looks good otherwise.
Oh, okay.
Quoted 1 line
If it has done a
bdrv_make_emptywe might also want to flush bs?
Indeed. I'll spin a new version.
PATCH v2 1/2 block: flush backing_hd in the right place
In reply to Christoph HellwigThe 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.
block.c +13 -13
@@ -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(BlockDrvoid 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(BlockDrif (!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); }
Am 12.01.2010 19:13, schrieb Christoph Hellwig:
Quoted 22 lines
The backing device is only modified from
bdrv_commit. So instead of flushing it every timebdrv_flushis called for the front-end device only flush it after we're written data to it inbdrv_commit.Also flush the frontend image if we have a
make_emptymethod that possibly writes to it.Signed-off-by Christoph Hellwig <[email protected]>Index:
qemu/block.c
===================================================================block.c +1
-0@@ -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)
block.c int bdrv_commit(BlockDriverState *bs) · line 627
Quoted 9 lines
block.c +4
-2@@ -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
Anthony Liguori
AppliedQuoted 6 lines · Christoph Hellwig
The backing device is only modified from
bdrv_commit. So instead of flushing it every timebdrv_flushis called for the front-end device only flush it after we're written data to it inbdrv_commit.Signed-off-by Christoph Hellwig<[email protected]>
Applied. Thanks.
Regards,
Anthony Liguori
Quoted 47 lines
Index:
qemu/block.c
===================================================================block.c +7
-10@@ -623,6 +623,12 @@ int bdrv_commit(BlockDriverState *bs)if (drv->bdrv_make_empty)return drv->bdrv_make_empty (bs); +/* +* 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 0 ; }@@ -1124,12 +1130,8 @@ const char *bdrv_get_device_name(BlockDrvoid 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 +1808,6 @@ BlockDriverAIOCB *bdrv_aio_flush(BlockDrif (!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); }
Am 14.01.2010 00:26, schrieb Anthony Liguori:
Quoted 9 lines · Christoph Hellwig
Quoted 6 lines
The backing device is only modified from
bdrv_commit. So instead of flushing it every timebdrv_flushis called for the front-end device only flush it after we're written data to it inbdrv_commit.Signed-off-by Christoph Hellwig<[email protected]>Applied. Thanks.
Anthony, you seem to have missed the v2 patch that considered my review comments. Can you please apply the diff between v1 and v2 on top?
Kevin
PATCH 1/1 block: fix cache flushing in bdrv_commit
Quoted 2 lines · Kevin Wolf
Anthony, you seem to have missed the v2 patch that considered my review comments. Can you please apply the diff between v1 and v2 on top?
Here is the differences in patch form:
---
From: Christoph Hellwig <[email protected]>
Subject: block: fix cache flushing in bdrv_commit
As pointed out by Kevin Wolf the previous patch returned early if we there is a bdrv_make_empty method and it missed a cache flush for the frontend device after the bdev_make_empty call. This patch fixes it up.
block.c +6 -3
@@ -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,8 +621,10 @@ 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); + }/* * Make sure all data we wrote to the backing device is actually
@@ -629,7 +632,7 @@ int bdrv_commit(BlockDriverState *bs)*/ if (bs->backing_hd)bdrv_flush (bs->backing_hd); -return 0 ; +return ret; }/*
Anthony Liguori
AppliedRe: [Qemu-devel] [PATCH] block: fix cache flushing in bdrv_commit
Quoted 11 lines · Christoph Hellwig
Quoted 3 lines · Kevin Wolf
Anthony, you seem to have missed the v2 patch that considered my review comments. Can you please apply the diff between v1 and v2 on top?
Here is the differences in patch form:
---
From: Christoph Hellwig<[email protected]>
Subject: block: fix cache flushing inbdrv_commit
Quoted 7 lines
As pointed out by Kevin Wolf the previous patch returned early if we there is a
bdrv_make_emptymethod and it missed a cache flush for the frontend device after thebdev_make_emptycall. This patch fixes it up.Signed-off-by Christoph Hellwig<[email protected]>
Applied. Thanks.
Regards,
Anthony Liguori
Quoted 38 lines
Index:
qemu/block.c
===================================================================block.c +6
-3@@ -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,8 +621,10 @@ 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); + }/* * Make sure all data we wrote to the backing device is actually @@ -629,7 +632,7 @@ int bdrv_commit(BlockDriverState *bs)*/ if (bs->backing_hd)bdrv_flush (bs->backing_hd); -return 0 ; +return ret; }/*