[glib] Only fsync if the existing file is > 0 bytes



commit d20a188b1250ab3cf211d684429127d99378e886
Author: Alexander Larsson <alexl redhat com>
Date:   Tue Aug 11 20:22:51 2009 +0200

    Only fsync if the existing file is > 0 bytes
    
    This means we don't sync in the case where we created an (empty)
    temp file and now replace it with the data.
    
    This fixes (among other things) the performance of trashing files.

 glib/gfileutils.c |   51 ++++++++++++++++++++++++++++-----------------------
 1 files changed, 28 insertions(+), 23 deletions(-)
---
diff --git a/glib/gfileutils.c b/glib/gfileutils.c
index 4f5c669..13f8627 100644
--- a/glib/gfileutils.c
+++ b/glib/gfileutils.c
@@ -961,29 +961,34 @@ write_to_temp_file (const gchar  *contents,
     }
   
 #ifdef HAVE_FSYNC
-  errno = 0;
-  /* If the final destination exists, we want to sync the newly written
-   * file to ensure the data is on disk when we rename over the destination.
-   * otherwise if we get a system crash we can lose both the new and the
-   * old file on some filesystems. (I.E. those that don't guarantee the
-   * data is written to the disk before the metadata.)
-   */
-  if (g_file_test (dest_file, G_FILE_TEST_EXISTS) &&
-      fsync (fileno (file)) != 0)
-    { 
-      save_errno = errno;
-      
-      g_set_error (err,
-		   G_FILE_ERROR,
-		   g_file_error_from_errno (save_errno),
-		   _("Failed to write file '%s': fsync() failed: %s"),
-		   display_name, 
-		   g_strerror (save_errno));
+  {
+    struct stat statbuf;
+
+    errno = 0;
+    /* If the final destination exists and is > 0 bytes, we want to sync the
+     * newly written file to ensure the data is on disk when we rename over
+     * the destination. Otherwise if we get a system crash we can lose both
+     * the new and the old file on some filesystems. (I.E. those that don't
+     * guarantee the data is written to the disk before the metadata.)
+     */
+    if (g_lstat (dest_file, &statbuf) == 0 &&
+	statbuf.st_size > 0 &&
+	fsync (fileno (file)) != 0)
+      {
+	save_errno = errno;
+
+	g_set_error (err,
+		     G_FILE_ERROR,
+		     g_file_error_from_errno (save_errno),
+		     _("Failed to write file '%s': fsync() failed: %s"),
+		     display_name,
+		     g_strerror (save_errno));
 
-      g_unlink (tmp_name);
-      
-      goto out;
-    }
+	g_unlink (tmp_name);
+
+	goto out;
+      }
+  }
 #endif
   
   errno = 0;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]