From ecc33845ca78a6420a86126cc18b765d03ec622f Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Tue, 18 Jan 2011 16:03:14 -0200
Subject: [PATCH 05/24] block: Allow bdrv_flush to return errors

RH-Author: Kevin Wolf <kwolf@redhat.com>
Message-id: <1295366596-3551-5-git-send-email-kwolf@redhat.com>
Patchwork-id: 16503
O-Subject: [RHEL-6.1 qemu-kvm PATCH 4/6] block: Allow bdrv_flush to return errors
Bugzilla: 670539
RH-Acked-by: Juan Quintela <quintela@redhat.com>
RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>
RH-Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com>

Bugzilla: 670539

This changes bdrv_flush to return 0 on success and -errno in case of failure.
It's a requirement for implementing proper error handle in users of bdrv_flush.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit 205ef7961f781496366e0a93a4ec621ad3724bd7)

Conflicts:

	block.c
	block/blkverify.c
	block/cow.c
	block/vmdk.c
---
 block.c           |   21 +++++++++++++++++----
 block.h           |    2 +-
 block/blkdebug.c  |    4 ++--
 block/cow.c       |    4 ++--
 block/qcow.c      |    4 ++--
 block/qcow2.c     |    4 ++--
 block/raw-posix.c |    4 ++--
 block/raw-win32.c |    9 ++++++++-
 block/raw.c       |    4 ++--
 block/vdi.c       |    4 ++--
 block/vmdk.c      |    4 ++--
 block_int.h       |    2 +-
 12 files changed, 43 insertions(+), 23 deletions(-)

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 block.c           |   21 +++++++++++++++++----
 block.h           |    2 +-
 block/blkdebug.c  |    4 ++--
 block/cow.c       |    4 ++--
 block/qcow.c      |    4 ++--
 block/qcow2.c     |    4 ++--
 block/raw-posix.c |    4 ++--
 block/raw-win32.c |    9 ++++++++-
 block/raw.c       |    4 ++--
 block/vdi.c       |    4 ++--
 block/vmdk.c      |    4 ++--
 block_int.h       |    2 +-
 12 files changed, 43 insertions(+), 23 deletions(-)

diff --git a/block.c b/block.c
index bd53985..7541a72 100644
--- a/block.c
+++ b/block.c
@@ -1357,14 +1357,27 @@ const char *bdrv_get_device_name(BlockDriverState *bs)
     return bs->device_name;
 }
 
-void bdrv_flush(BlockDriverState *bs)
+int bdrv_flush(BlockDriverState *bs)
 {
     if (bs->open_flags & BDRV_O_NO_FLUSH) {
-        return;
+        return 0;
+    }
+
+    if (bs->drv && bs->drv->bdrv_flush) {
+        return bs->drv->bdrv_flush(bs);
     }
 
-    if (bs->drv && bs->drv->bdrv_flush)
-        bs->drv->bdrv_flush(bs);
+    /*
+     * Some block drivers always operate in either writethrough or unsafe mode
+     * and don't support bdrv_flush therefore. Usually qemu doesn't know how
+     * the server works (because the behaviour is hardcoded or depends on
+     * server-side configuration), so we can't ensure that everything is safe
+     * on disk. Returning an error doesn't work because that would break guests
+     * even if the server operates in writethrough mode.
+     *
+     * Let's hope the user knows what he's doing.
+     */
+    return 0;
 }
 
 void bdrv_flush_all(void)
diff --git a/block.h b/block.h
index 9b082c0..72e43a3 100644
--- a/block.h
+++ b/block.h
@@ -136,7 +136,7 @@ BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
         BlockDriverCompletionFunc *cb, void *opaque);
 
 /* Ensure contents are flushed to disk.  */
-void bdrv_flush(BlockDriverState *bs);
+int bdrv_flush(BlockDriverState *bs);
 void bdrv_flush_all(void);
 
 int bdrv_has_zero_init(BlockDriverState *bs);
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 7b7f87b..e36cd9e 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -392,9 +392,9 @@ static void blkdebug_close(BlockDriverState *bs)
     }
 }
 
-static void blkdebug_flush(BlockDriverState *bs)
+static int blkdebug_flush(BlockDriverState *bs)
 {
-    bdrv_flush(bs->file);
+    return bdrv_flush(bs->file);
 }
 
 static BlockDriverAIOCB *blkdebug_aio_flush(BlockDriverState *bs,
diff --git a/block/cow.c b/block/cow.c
index fde066e..8e21f02 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -267,10 +267,10 @@ exit:
     return ret;
 }
 
-static void cow_flush(BlockDriverState *bs)
+static int cow_flush(BlockDriverState *bs)
 {
     BDRVCowState *s = bs->opaque;
-    qemu_fdatasync(s->fd);
+    return qemu_fdatasync(s->fd);
 }
 
 static QEMUOptionParameter cow_create_options[] = {
diff --git a/block/qcow.c b/block/qcow.c
index 1c0be6d..309c56e 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -907,9 +907,9 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
     return 0;
 }
 
-static void qcow_flush(BlockDriverState *bs)
+static int qcow_flush(BlockDriverState *bs)
 {
-    bdrv_flush(bs->file);
+    return bdrv_flush(bs->file);
 }
 
 static BlockDriverAIOCB *qcow_aio_flush(BlockDriverState *bs,
diff --git a/block/qcow2.c b/block/qcow2.c
index deea8f8..483607a 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1250,9 +1250,9 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
     return 0;
 }
 
-static void qcow_flush(BlockDriverState *bs)
+static int qcow_flush(BlockDriverState *bs)
 {
-    bdrv_flush(bs->file);
+    return bdrv_flush(bs->file);
 }
 
 static BlockDriverAIOCB *qcow_aio_flush(BlockDriverState *bs,
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 915968a..a38ae91 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -720,10 +720,10 @@ static int raw_create(const char *filename, QEMUOptionParameter *options)
     return result;
 }
 
-static void raw_flush(BlockDriverState *bs)
+static int raw_flush(BlockDriverState *bs)
 {
     BDRVRawState *s = bs->opaque;
-    qemu_fdatasync(s->fd);
+    return qemu_fdatasync(s->fd);
 }
 
 
diff --git a/block/raw-win32.c b/block/raw-win32.c
index 32ce701..5650389 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -154,7 +154,14 @@ static int raw_write(BlockDriverState *bs, int64_t sector_num,
 static void raw_flush(BlockDriverState *bs)
 {
     BDRVRawState *s = bs->opaque;
-    FlushFileBuffers(s->hfile);
+    int ret;
+
+    ret = FlushFileBuffers(s->hfile);
+    if (ret != 0) {
+        return -EIO;
+    }
+
+    return 0;
 }
 
 static void raw_close(BlockDriverState *bs)
diff --git a/block/raw.c b/block/raw.c
index 9108779..1980deb 100644
--- a/block/raw.c
+++ b/block/raw.c
@@ -39,9 +39,9 @@ static void raw_close(BlockDriverState *bs)
 {
 }
 
-static void raw_flush(BlockDriverState *bs)
+static int raw_flush(BlockDriverState *bs)
 {
-    bdrv_flush(bs->file);
+    return bdrv_flush(bs->file);
 }
 
 static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs,
diff --git a/block/vdi.c b/block/vdi.c
index 314457b..1367ec8 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -882,10 +882,10 @@ static void vdi_close(BlockDriverState *bs)
 {
 }
 
-static void vdi_flush(BlockDriverState *bs)
+static int vdi_flush(BlockDriverState *bs)
 {
     logout("\n");
-    bdrv_flush(bs->file);
+    return bdrv_flush(bs->file);
 }
 
 
diff --git a/block/vmdk.c b/block/vmdk.c
index 5ef4375..b92efdb 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -884,10 +884,10 @@ static void vmdk_close(BlockDriverState *bs)
     bdrv_delete(s->hd);
 }
 
-static void vmdk_flush(BlockDriverState *bs)
+static int vmdk_flush(BlockDriverState *bs)
 {
     BDRVVmdkState *s = bs->opaque;
-    bdrv_flush(s->hd);
+    return bdrv_flush(s->hd);
 }
 
 
diff --git a/block_int.h b/block_int.h
index 77ae5b2..e5873ae 100644
--- a/block_int.h
+++ b/block_int.h
@@ -58,7 +58,7 @@ struct BlockDriver {
                       const uint8_t *buf, int nb_sectors);
     void (*bdrv_close)(BlockDriverState *bs);
     int (*bdrv_create)(const char *filename, QEMUOptionParameter *options);
-    void (*bdrv_flush)(BlockDriverState *bs);
+    int (*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);
-- 
1.7.4.rc1.16.gd2f15e

