aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block-cow.c7
-rw-r--r--block-qcow.c7
-rw-r--r--block-vmdk.c7
-rw-r--r--block-vvfat.c1
-rw-r--r--block.c15
-rw-r--r--block_int.h1
-rw-r--r--hw/ide.c5
-rw-r--r--hw/scsi-disk.c2
-rw-r--r--vl.h2
9 files changed, 46 insertions, 1 deletions
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