On Thu, May 09, 2013 at 02:24:20PM +0800, Dong Xu Wang wrote: > On Thu, Apr 18, 2013 at 6:03 PM, Stefan Hajnoczi <stefa...@gmail.com> wrote: > > On Wed, Apr 10, 2013 at 04:11:52PM +0800, Dong Xu Wang wrote: > >> +static coroutine_fn int add_cow_co_flush(BlockDriverState *bs) > >> +{ > >> + BDRVAddCowState *s = bs->opaque; > >> + int ret; > >> + > >> + qemu_co_mutex_lock(&s->lock); > >> + if (s->bitmap_cache) { > >> + ret = block_cache_flush(bs, s->bitmap_cache); > >> + if (ret < 0) { > >> + return ret; > >> + } > >> + } > >> + ret = bdrv_flush(s->image_hd); > > > > This is the wrong way around. We must flush image_hd first so that > > valid data is on disk. Then we can flush bitmap_cache to mark the > > clusters allocated. > > > > Beyond explicit flushes you also need to make sure that image_hd is > > flushed *before* bitmap_cache tables are written out (e.g. cache > > eviction when the cache becomes full). It seems this code is missing. > > > Hi Stefan, how can I make sure image_hd "flush" operation completed before > I write bitmap_cache tables? Is there any functions I can use?
You could extend the block cache like this: block_cache_add_dependency_func(BlockCache *c, int (*dependency_fn)(BlockCache *c, void *opaque), void *opaque); Then add-cow would register a custom dependency function that flushes image_hd. A hackier way of achieving the same thing is to instantiate an image_hd_cache and set a dependency from the bitmap_cache on the image_hd_cache. The image_hd_cache actually has no cache entries, but it uses image_hd and will flush it. Stefan