Disk cache flush support. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1949 c046a42c-6fe2-441c-8c8c-71466251a162
diff --git a/block-cow.c b/block-cow.c index eeeab70..6af8b74 100644 --- a/block-cow.c +++ b/block-cow.c
@@ -250,6 +250,12 @@ return 0; } +static void cow_flush(BlockDriverState *bs) +{ + BDRVCowState *s = bs->opaque; + fsync(s->fd); +} + BlockDriver bdrv_cow = { "cow", sizeof(BDRVCowState), @@ -259,6 +265,7 @@ cow_write, cow_close, cow_create, + cow_flush, cow_is_allocated, }; #endif
diff --git a/block-qcow.c b/block-qcow.c index 34026a4..e5b52fb 100644 --- a/block-qcow.c +++ b/block-qcow.c
@@ -693,6 +693,12 @@ return 0; } +static void qcow_flush(BlockDriverState *bs) +{ + BDRVQcowState *s = bs->opaque; + fsync(s->fd); +} + BlockDriver bdrv_qcow = { "qcow", sizeof(BDRVQcowState), @@ -702,6 +708,7 @@ qcow_write, qcow_close, qcow_create, + qcow_flush, qcow_is_allocated, qcow_set_key, qcow_make_empty
diff --git a/block-vmdk.c b/block-vmdk.c index fc87be3..4cc3db8 100644 --- a/block-vmdk.c +++ b/block-vmdk.c
@@ -426,6 +426,12 @@ close(s->fd); } +static void vmdk_flush(BlockDriverState *bs) +{ + BDRVVmdkState *s = bs->opaque; + fsync(s->fd); +} + BlockDriver bdrv_vmdk = { "vmdk", sizeof(BDRVVmdkState), @@ -435,5 +441,6 @@ vmdk_write, vmdk_close, vmdk_create, + vmdk_flush, vmdk_is_allocated, };
diff --git a/block-vvfat.c b/block-vvfat.c index 84d2a08..9dedf91 100644 --- a/block-vvfat.c +++ b/block-vvfat.c
@@ -2772,6 +2772,7 @@ vvfat_read, vvfat_write, vvfat_close, + NULL, /* ??? Not sure if we can do any meaningful flushing. */ NULL, vvfat_is_allocated };
diff --git a/block.c b/block.c index b908167..c25c686 100644 --- a/block.c +++ b/block.c
@@ -615,6 +615,14 @@ return bs->device_name; } +void bdrv_flush(BlockDriverState *bs) +{ + if (bs->drv->bdrv_flush) + bs->drv->bdrv_flush(bs); + if (bs->backing_hd) + bdrv_flush(bs->backing_hd); +} + void bdrv_info(void) { BlockDriverState *bs; @@ -770,6 +778,12 @@ return 0; } +static void raw_flush(BlockDriverState *bs) +{ + BDRVRawState *s = bs->opaque; + fsync(s->fd); +} + BlockDriver bdrv_raw = { "raw", sizeof(BDRVRawState), @@ -779,6 +793,7 @@ raw_write, raw_close, raw_create, + raw_flush, }; void bdrv_init(void)
diff --git a/block_int.h b/block_int.h index e303816..c2a2e30 100644 --- a/block_int.h +++ b/block_int.h
@@ -36,6 +36,7 @@ void (*bdrv_close)(BlockDriverState *bs); int (*bdrv_create)(const char *filename, int64_t total_sectors, const char *backing_file, int flags); + void (*bdrv_flush)(BlockDriverState *bs); int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum); int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
diff --git a/hw/ide.c b/hw/ide.c index ffe0230..debbc0f 100644 --- a/hw/ide.c +++ b/hw/ide.c
@@ -1656,6 +1656,11 @@ break; case WIN_FLUSH_CACHE: case WIN_FLUSH_CACHE_EXT: + if (s->bs) + bdrv_flush(s->bs); + s->status = READY_STAT; + ide_set_irq(s); + break; case WIN_STANDBYNOW1: case WIN_IDLEIMMEDIATE: s->status = READY_STAT;
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 7390805..decab1f 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c
@@ -373,7 +373,7 @@ break; case 0x35: DPRINTF("Syncronise cache (sector %d, count %d)\n", lba, len); - /* ??? Extend block layer and use fsync to implement this. */ + bdrv_flush(s->bdrv); break; case 0x43: {
diff --git a/vl.h b/vl.h index 9442409..2bd49e8 100644 --- a/vl.h +++ b/vl.h
@@ -496,6 +496,8 @@ void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr); int bdrv_commit(BlockDriverState *bs); void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size); +/* Ensure contents are flushed to disk. */ +void bdrv_flush(BlockDriverState *bs); #define BDRV_TYPE_HD 0 #define BDRV_TYPE_CDROM 1