summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block/cow.c2
-rw-r--r--block/raw-posix.c2
-rw-r--r--cutils.c16
-rw-r--r--qemu-common.h1
4 files changed, 19 insertions, 2 deletions
diff --git a/block/cow.c b/block/cow.c
index 84818f1034..a70854e631 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -258,7 +258,7 @@ static int cow_create(const char *filename, QEMUOptionParameter *options)
static void cow_flush(BlockDriverState *bs)
{
BDRVCowState *s = bs->opaque;
- fsync(s->fd);
+ qemu_fdatasync(s->fd);
}
static QEMUOptionParameter cow_create_options[] = {
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 2125d67a5f..2ebc88f004 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -723,7 +723,7 @@ static int raw_create(const char *filename, QEMUOptionParameter *options)
static void raw_flush(BlockDriverState *bs)
{
BDRVRawState *s = bs->opaque;
- fsync(s->fd);
+ qemu_fdatasync(s->fd);
}
diff --git a/cutils.c b/cutils.c
index ffe5c717e4..7a2234646a 100644
--- a/cutils.c
+++ b/cutils.c
@@ -115,6 +115,22 @@ int qemu_fls(int i)
return 32 - clz32(i);
}
+/*
+ * Make sure data goes on disk, but if possible do not bother to
+ * write out the inode just for timestamp updates.
+ *
+ * Unfortunately even in 2009 many operating systems do not support
+ * fdatasync and have to fall back to fsync.
+ */
+int qemu_fdatasync(int fd)
+{
+#ifdef _POSIX_SYNCHRONIZED_IO
+ return fdatasync(fd);
+#else
+ return fsync(fd);
+#endif
+}
+
/* io vectors */
void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint)
diff --git a/qemu-common.h b/qemu-common.h
index f3cfb683ea..12e7dd0ada 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -114,6 +114,7 @@ int stristart(const char *str, const char *val, const char **ptr);
int qemu_strnlen(const char *s, int max_len);
time_t mktimegm(struct tm *tm);
int qemu_fls(int i);
+int qemu_fdatasync(int fd);
/* path.c */
void init_paths(const char *prefix);