registry: do fsync() before close() and rename()

This helps prevent filesystem/data inconsistencies in certain
circumstances on certain filesystems (like ext4, xfs, ubifs).
Also see bug #562976.
This commit is contained in:
Tim-Philipp Müller 2009-03-26 14:16:55 +00:00
parent c4e10b9535
commit cc0978bd85
2 changed files with 18 additions and 0 deletions

View file

@ -226,6 +226,10 @@ static gboolean
gst_registry_binary_cache_finish (GstRegistry * registry, gst_registry_binary_cache_finish (GstRegistry * registry,
BinaryRegistryCache * cache, gboolean success) 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) if (close (registry->cache_file) < 0)
goto close_failed; goto close_failed;
@ -240,6 +244,7 @@ gst_registry_binary_cache_finish (GstRegistry * registry,
GST_INFO ("Wrote binary registry cache"); GST_INFO ("Wrote binary registry cache");
return TRUE; return TRUE;
/* ERRORS */
fail_after_close: fail_after_close:
{ {
g_unlink (cache->tmp_location); g_unlink (cache->tmp_location);
@ -247,6 +252,11 @@ fail_after_close:
g_free (cache); g_free (cache);
return FALSE; return FALSE;
} }
fsync_failed:
{
GST_ERROR ("fsync() failed: %s", g_strerror (errno));
goto fail_after_close;
}
close_failed: close_failed:
{ {
GST_ERROR ("close() failed: %s", g_strerror (errno)); GST_ERROR ("close() failed: %s", g_strerror (errno));

View file

@ -919,6 +919,9 @@ gst_registry_xml_write_cache (GstRegistry * registry, const char *location)
if (!gst_registry_save (registry, "</GST-PluginRegistry>\n")) if (!gst_registry_save (registry, "</GST-PluginRegistry>\n"))
goto fail; goto fail;
if (fsync (registry->cache_file) < 0)
goto fsync_failed;
/* check return value of close(), write errors may only get reported here */ /* check return value of close(), write errors may only get reported here */
if (close (registry->cache_file) < 0) if (close (registry->cache_file) < 0)
goto close_failed; goto close_failed;
@ -949,6 +952,11 @@ fail_after_close:
g_free (tmp_location); g_free (tmp_location);
return FALSE; return FALSE;
} }
fsync_failed:
{
GST_ERROR ("fsync() failed: %s", g_strerror (errno));
goto fail_after_close;
}
close_failed: close_failed:
{ {
GST_ERROR ("close() failed: %s", g_strerror (errno)); GST_ERROR ("close() failed: %s", g_strerror (errno));