diff --git a/block.c b/block.c index 86910b046c..d0158877d6 100644 --- a/block.c +++ b/block.c @@ -2839,6 +2839,22 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs) } } +void bdrv_invalidate_cache(BlockDriverState *bs) +{ + if (bs->drv && bs->drv->bdrv_invalidate_cache) { + bs->drv->bdrv_invalidate_cache(bs); + } +} + +void bdrv_invalidate_cache_all(void) +{ + BlockDriverState *bs; + + QTAILQ_FOREACH(bs, &bdrv_states, list) { + bdrv_invalidate_cache(bs); + } +} + int bdrv_flush(BlockDriverState *bs) { Coroutine *co; diff --git a/block.h b/block.h index 051a25d8d6..a826059897 100644 --- a/block.h +++ b/block.h @@ -197,6 +197,10 @@ BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs, unsigned long int req, void *buf, BlockDriverCompletionFunc *cb, void *opaque); +/* Invalidate any cached metadata used by image formats */ +void bdrv_invalidate_cache(BlockDriverState *bs); +void bdrv_invalidate_cache_all(void); + /* Ensure contents are flushed to disk. */ int bdrv_flush(BlockDriverState *bs); int coroutine_fn bdrv_co_flush(BlockDriverState *bs); diff --git a/block_int.h b/block_int.h index 1ec4921cc6..77c0187c3d 100644 --- a/block_int.h +++ b/block_int.h @@ -87,6 +87,11 @@ struct BlockDriver { int coroutine_fn (*bdrv_co_discard)(BlockDriverState *bs, int64_t sector_num, int nb_sectors); + /* + * Invalidate any cached meta-data. + */ + void (*bdrv_invalidate_cache)(BlockDriverState *bs); + /* * Flushes all data that was already written to the OS all the way down to * the disk (for example raw-posix calls fsync()). diff --git a/migration.c b/migration.c index 6764d3a44c..8280d7189a 100644 --- a/migration.c +++ b/migration.c @@ -89,6 +89,9 @@ void process_incoming_migration(QEMUFile *f) qemu_announce_self(); DPRINTF("successfully loaded vm state\n"); + /* Make sure all file formats flush their mutable metadata */ + bdrv_invalidate_cache_all(); + if (autostart) { vm_start(); } else {