registry: do fsync() before close() and rename()
authorTim-Philipp Müller <tim.muller@collabora.co.uk>
Thu, 26 Mar 2009 14:16:55 +0000 (14:16 +0000)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Thu, 26 Mar 2009 14:51:49 +0000 (14:51 +0000)
This helps prevent filesystem/data inconsistencies in certain
circumstances on certain filesystems (like ext4, xfs, ubifs).
Also see bug #562976.

gst/gstregistrybinary.c
gst/gstregistryxml.c

index 4849c0b..af98e4b 100644 (file)
@@ -226,6 +226,10 @@ static gboolean
 gst_registry_binary_cache_finish (GstRegistry * registry,
     BinaryRegistryCache * cache, gboolean success)
 {
+  /* only fsync if we're actually going to use and rename the file below */
+  if (success && fsync (registry->cache_file) < 0)
+    goto fsync_failed;
+
   if (close (registry->cache_file) < 0)
     goto close_failed;
 
@@ -240,6 +244,7 @@ gst_registry_binary_cache_finish (GstRegistry * registry,
   GST_INFO ("Wrote binary registry cache");
   return TRUE;
 
+/* ERRORS */
 fail_after_close:
   {
     g_unlink (cache->tmp_location);
@@ -247,6 +252,11 @@ fail_after_close:
     g_free (cache);
     return FALSE;
   }
+fsync_failed:
+  {
+    GST_ERROR ("fsync() failed: %s", g_strerror (errno));
+    goto fail_after_close;
+  }
 close_failed:
   {
     GST_ERROR ("close() failed: %s", g_strerror (errno));
index f402b77..9623cf9 100644 (file)
@@ -919,6 +919,9 @@ gst_registry_xml_write_cache (GstRegistry * registry, const char *location)
   if (!gst_registry_save (registry, "</GST-PluginRegistry>\n"))
     goto fail;
 
+  if (fsync (registry->cache_file) < 0)
+    goto fsync_failed;
+
   /* check return value of close(), write errors may only get reported here */
   if (close (registry->cache_file) < 0)
     goto close_failed;
@@ -949,6 +952,11 @@ fail_after_close:
     g_free (tmp_location);
     return FALSE;
   }
+fsync_failed:
+  {
+    GST_ERROR ("fsync() failed: %s", g_strerror (errno));
+    goto fail_after_close;
+  }
 close_failed:
   {
     GST_ERROR ("close() failed: %s", g_strerror (errno));