Merge remote-tracking branch 'gvdb/master'
[platform/upstream/glib.git] / glib / gfileutils.c
index bfd6bb6..da6cacd 100644 (file)
@@ -19,8 +19,7 @@
  */
 
 #include "config.h"
-
-#include "glib.h"
+#include "glibconfig.h"
 
 #include <sys/stat.h>
 #ifdef HAVE_UNISTD_H
 #define O_BINARY 0
 #endif
 
+#include "gfileutils.h"
+
 #include "gstdio.h"
 #include "glibintl.h"
 
+#ifdef HAVE_LINUX_MAGIC_H /* for btrfs check */
+#include <linux/magic.h>
+#include <sys/vfs.h>
+#endif
 
 /**
  * g_mkdir_with_parents:
@@ -962,6 +967,20 @@ write_to_temp_file (const gchar  *contents,
       
       goto out;
     }
+
+#ifdef BTRFS_SUPER_MAGIC
+  {
+    struct statfs buf;
+
+    /* On Linux, on btrfs, skip the fsync since rename-over-existing is
+     * guaranteed to be atomic and this is the only case in which we
+     * would fsync() anyway.
+     */
+
+    if (fstatfs (fd, &buf) == 0 && buf.f_type == BTRFS_SUPER_MAGIC)
+      goto no_fsync;
+  }
+#endif
   
 #ifdef HAVE_FSYNC
   {
@@ -993,6 +1012,7 @@ write_to_temp_file (const gchar  *contents,
       }
   }
 #endif
+ no_fsync:
   
   errno = 0;
   if (fclose (file) == EOF)
@@ -1056,6 +1076,9 @@ write_to_temp_file (const gchar  *contents,
  * it returns %FALSE and sets @error. The error domain is #G_FILE_ERROR.
  * Possible error codes are those in the #GFileError enumeration.
  *
+ * Note that the name for the temporary file is constructed by appending up
+ * to 7 characters to @filename.
+ *
  * Return value: %TRUE on success, %FALSE if an error occurred
  *
  * Since: 2.8