Disk cache flush support.
authorpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 4 Jun 2006 11:39:07 +0000 (11:39 +0000)
committerpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 4 Jun 2006 11:39:07 +0000 (11:39 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1949 c046a42c-6fe2-441c-8c8c-71466251a162

block-cow.c
block-qcow.c
block-vmdk.c
block-vvfat.c
block.c
block_int.h
hw/ide.c
hw/scsi-disk.c
vl.h

index eeeab70..6af8b74 100644 (file)
@@ -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
index 34026a4..e5b52fb 100644 (file)
@@ -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
index fc87be3..4cc3db8 100644 (file)
@@ -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,
 };
index 84d2a08..9dedf91 100644 (file)
@@ -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 b908167..c25c686 100644 (file)
--- 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)
index e303816..c2a2e30 100644 (file)
@@ -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);
index ffe0230..debbc0f 100644 (file)
--- 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;
index 7390805..decab1f 100644 (file)
@@ -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 9442409..2bd49e8 100644 (file)
--- 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