From 7a6cba611d09f8eccdfc90d5ad3eb03762e60ce9 Mon Sep 17 00:00:00 2001 From: pbrook Date: Sun, 4 Jun 2006 11:39:07 +0000 Subject: [PATCH] Disk cache flush support. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1949 c046a42c-6fe2-441c-8c8c-71466251a162 --- block-cow.c | 7 +++++++ block-qcow.c | 7 +++++++ block-vmdk.c | 7 +++++++ block-vvfat.c | 1 + block.c | 15 +++++++++++++++ block_int.h | 1 + hw/ide.c | 5 +++++ hw/scsi-disk.c | 2 +- vl.h | 2 ++ 9 files changed, 46 insertions(+), 1 deletion(-) diff --git a/block-cow.c b/block-cow.c index eeeab7068b..6af8b74975 100644 --- a/block-cow.c +++ b/block-cow.c @@ -250,6 +250,12 @@ static int cow_create(const char *filename, int64_t image_sectors, 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 @@ BlockDriver bdrv_cow = { cow_write, cow_close, cow_create, + cow_flush, cow_is_allocated, }; #endif diff --git a/block-qcow.c b/block-qcow.c index 34026a4f2c..e5b52fb861 100644 --- a/block-qcow.c +++ b/block-qcow.c @@ -693,6 +693,12 @@ int qcow_compress_cluster(BlockDriverState *bs, int64_t sector_num, 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 @@ BlockDriver bdrv_qcow = { 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 fc87be353b..4cc3db84a1 100644 --- a/block-vmdk.c +++ b/block-vmdk.c @@ -426,6 +426,12 @@ static void vmdk_close(BlockDriverState *bs) 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 @@ BlockDriver bdrv_vmdk = { vmdk_write, vmdk_close, vmdk_create, + vmdk_flush, vmdk_is_allocated, }; diff --git a/block-vvfat.c b/block-vvfat.c index 84d2a08ad7..9dedf9115f 100644 --- a/block-vvfat.c +++ b/block-vvfat.c @@ -2772,6 +2772,7 @@ BlockDriver bdrv_vvfat = { 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 b908167186..c25c6869a6 100644 --- a/block.c +++ b/block.c @@ -615,6 +615,14 @@ const char *bdrv_get_device_name(BlockDriverState *bs) 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 @@ static int raw_create(const char *filename, int64_t total_size, 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 @@ BlockDriver bdrv_raw = { raw_write, raw_close, raw_create, + raw_flush, }; void bdrv_init(void) diff --git a/block_int.h b/block_int.h index e3038160e6..c2a2e30a9f 100644 --- a/block_int.h +++ b/block_int.h @@ -36,6 +36,7 @@ struct BlockDriver { 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 ffe0230d8a..debbc0f418 100644 --- a/hw/ide.c +++ b/hw/ide.c @@ -1656,6 +1656,11 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) 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 7390805d24..decab1f42b 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -373,7 +373,7 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun) 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 9442409571..2bd49e8ddc 100644 --- a/vl.h +++ b/vl.h @@ -496,6 +496,8 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num, 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 -- 2.11.4.GIT