[gvfs/gnome-3-8] metadata: Force tree re-read after successful flush
- From: Tomas Bzatek <tbzatek src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs/gnome-3-8] metadata: Force tree re-read after successful flush
- Date: Tue, 14 May 2013 16:14:55 +0000 (UTC)
commit 39f7b6ffd306943005413deb25bee6a56cb5e6f9
Author: Tomas Bzatek <tbzatek redhat com>
Date: Mon May 13 17:39:26 2013 +0200
metadata: Force tree re-read after successful flush
Once we flush the journal and write new tree file we need to re-read
it to refresh internal data structures (and mmap data from the right
file). We originally left this work on meta_tree_refresh_locked() and
meta_tree_needs_rereading() respectively where we checked the rotated
bit.
In detail, metabuilder wrote a new temp tree file, then explicitly opened
the current (old) one, wrote the rotated bit and atomically replaced the
temp file. Then the metadata daemon having mmapped the old file detected
the rotated bit and scheduled journal and tree file reopen+reread.
However in concurrent environment like NFS homedir where multiple metadata
daemons are handling the same database we may run in a race and not getting
the rotated bit detected properly.
This led to an infinite loop between meta_journal_add_entry() -
meta_tree_flush_locked() - meta_tree_refresh_locked() - meta_journal_add_entry()
since we had full journal, didn't detect the rotation and since the files
were already unlinked, there was no force to break that loop. This patch
forces tree file re-read after successful flush to prevent this issue.
https://bugzilla.gnome.org/show_bug.cgi?id=637095
(cherry picked from commit 6b12c3d7b33c87a7fea228106f39ecf2a3e0f310)
metadata/metatree.c | 14 ++++++++------
1 files changed, 8 insertions(+), 6 deletions(-)
---
diff --git a/metadata/metatree.c b/metadata/metatree.c
index 3bcf9a6..015300e 100644
--- a/metadata/metatree.c
+++ b/metadata/metatree.c
@@ -169,7 +169,8 @@ struct _MetaTree {
MetaJournal *journal;
};
-static void meta_tree_refresh_locked (MetaTree *tree);
+static void meta_tree_refresh_locked (MetaTree *tree,
+ gboolean force_reread);
static MetaJournal *meta_journal_open (MetaTree *tree,
const char *filename,
gboolean for_write,
@@ -510,7 +511,7 @@ meta_tree_init (MetaTree *tree)
journal. However we can detect this case by looking at the tree and see
if its been rotated, we do this to ensure we have an uptodate tree+journal
combo. */
- meta_tree_refresh_locked (tree);
+ meta_tree_refresh_locked (tree, FALSE);
return TRUE;
@@ -658,10 +659,10 @@ meta_tree_has_new_journal_entries (MetaTree *tree)
/* Must be called with a write lock held */
static void
-meta_tree_refresh_locked (MetaTree *tree)
+meta_tree_refresh_locked (MetaTree *tree, gboolean force_reread)
{
/* Needs to recheck since we dropped read lock */
- if (meta_tree_needs_rereading (tree))
+ if (force_reread || meta_tree_needs_rereading (tree))
{
if (tree->header)
meta_tree_clear (tree);
@@ -685,7 +686,7 @@ meta_tree_refresh (MetaTree *tree)
if (needs_refresh)
{
g_rw_lock_writer_lock (&metatree_lock);
- meta_tree_refresh_locked (tree);
+ meta_tree_refresh_locked (tree, FALSE);
g_rw_lock_writer_unlock (&metatree_lock);
}
}
@@ -2363,7 +2364,8 @@ meta_tree_flush_locked (MetaTree *tree)
res = meta_builder_write (builder,
meta_tree_get_filename (tree));
if (res)
- meta_tree_refresh_locked (tree);
+ /* Force re-read since we wrote a new file */
+ meta_tree_refresh_locked (tree, TRUE);
meta_builder_free (builder);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]