summaryrefslogtreecommitdiff
path: root/metadata
diff options
context:
space:
mode:
Diffstat (limited to 'metadata')
-rw-r--r--metadata/meta-get-tree.c6
-rw-r--r--metadata/metatree.c89
-rw-r--r--metadata/metatree.h2
3 files changed, 76 insertions, 21 deletions
diff --git a/metadata/meta-get-tree.c b/metadata/meta-get-tree.c
index 1af626da..23ce9e42 100644
--- a/metadata/meta-get-tree.c
+++ b/metadata/meta-get-tree.c
@@ -46,7 +46,11 @@ main (int argc,
tree_path = NULL;
tree = meta_lookup_cache_lookup_path (cache, argv[i], statbuf.st_dev,
FALSE, &tree_path);
- g_print ("tree: %s (exists: %d), tree path: %s\n", meta_tree_get_filename (tree), meta_tree_exists (tree), tree_path);
+ if (tree)
+ g_print ("tree: %s (exists: %d), tree path: %s\n", meta_tree_get_filename (tree), meta_tree_exists (tree), tree_path);
+ else
+ g_print ("tree lookup failed\n");
+
if (pause)
{
char buffer[1000];
diff --git a/metadata/metatree.c b/metadata/metatree.c
index 7b59c4a5..8875ae26 100644
--- a/metadata/metatree.c
+++ b/metadata/metatree.c
@@ -153,7 +153,7 @@ static inline guint64 ldq_u(guint64 *p)
#define ldq_u(x) (*(x))
#endif
-static void meta_tree_refresh_locked (MetaTree *tree,
+static gboolean meta_tree_refresh_locked (MetaTree *tree,
gboolean force_reread);
static MetaJournal *meta_journal_open (MetaTree *tree,
const char *filename,
@@ -368,6 +368,7 @@ meta_tree_init (MetaTree *tree)
guint32 *attributes;
gboolean retried;
int i;
+ int errsv;
retried = FALSE;
retry:
@@ -375,6 +376,8 @@ meta_tree_init (MetaTree *tree)
fd = safe_open (tree, tree->filename, O_RDONLY);
if (fd == -1)
{
+ errsv = errno;
+
if (tree->for_write && !retried)
{
MetaBuilder *builder;
@@ -393,13 +396,30 @@ meta_tree_init (MetaTree *tree)
}
meta_builder_free (builder);
}
+ else if (tree->for_write || errsv != ENOENT)
+ {
+ g_warning ("can't init metadata tree %s: open: %s", tree->filename, g_strerror (errsv));
+ }
tree->fd = -1;
+
+ /* If we're opening for reading and the file does not exist, it is not
+ * an error. The file will be created later. */
+ return !tree->for_write && errsv == ENOENT;
+ }
+
+ if (fstat (fd, &statbuf) != 0)
+ {
+ errsv = errno;
+ g_warning ("can't init metadata tree %s: fstat: %s", tree->filename, g_strerror (errsv));
+
+ close (fd);
return FALSE;
}
- if (fstat (fd, &statbuf) != 0 ||
- statbuf.st_size < sizeof (MetaFileHeader))
+ if (statbuf.st_size < sizeof (MetaFileHeader))
{
+ g_warning ("can't init metadata tree %s: wrong size", tree->filename);
+
close (fd);
return FALSE;
}
@@ -407,6 +427,9 @@ meta_tree_init (MetaTree *tree)
data = mmap (NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (data == MAP_FAILED)
{
+ errsv = errno;
+ g_warning ("can't init metadata tree %s: mmap: %s", tree->filename, g_strerror (errsv));
+
close (fd);
return FALSE;
}
@@ -418,18 +441,30 @@ meta_tree_init (MetaTree *tree)
tree->header = (MetaFileHeader *)data;
if (memcmp (tree->header->magic, MAGIC, MAGIC_LEN) != 0)
- goto err;
+ {
+ g_warning ("can't init metadata tree %s: wrong magic", tree->filename);
+ goto err;
+ }
if (tree->header->major != MAJOR_VERSION)
- goto err;
+ {
+ g_warning ("can't init metadata tree %s: wrong version", tree->filename);
+ goto err;
+ }
tree->root = verify_block_pointer (tree, tree->header->root, sizeof (MetaFileDirEnt));
if (tree->root == NULL)
- goto err;
+ {
+ g_warning ("can't init metadata tree %s: wrong pointer", tree->filename);
+ goto err;
+ }
attributes = verify_array_block (tree, tree->header->attributes, sizeof (guint32));
if (attributes == NULL)
- goto err;
+ {
+ g_warning ("can't init metadata tree %s: wrong block", tree->filename);
+ goto err;
+ }
tree->num_attributes = GUINT32_FROM_BE (*attributes);
attributes++;
@@ -438,7 +473,10 @@ meta_tree_init (MetaTree *tree)
{
tree->attributes[i] = verify_string (tree, attributes[i]);
if (tree->attributes[i] == NULL)
- goto err;
+ {
+ g_warning ("can't init metadata tree %s: wrong attribute", tree->filename);
+ goto err;
+ }
}
tree->tag = GUINT32_FROM_BE (tree->header->random_tag);
@@ -451,9 +489,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, FALSE);
-
- return TRUE;
+ return meta_tree_refresh_locked (tree, FALSE);
err:
meta_tree_clear (tree);
@@ -465,6 +501,7 @@ meta_tree_open (const char *filename,
gboolean for_write)
{
MetaTree *tree;
+ gboolean res;
g_assert (sizeof (MetaFileHeader) == 32);
g_assert (sizeof (MetaFileDirEnt) == 16);
@@ -476,7 +513,13 @@ meta_tree_open (const char *filename,
tree->for_write = for_write;
tree->fd = -1;
- meta_tree_init (tree);
+ res = meta_tree_init (tree);
+ if (!res)
+ {
+ /* do not return uninitialized tree to avoid corruptions */
+ meta_tree_unref (tree);
+ tree = NULL;
+ }
return tree;
}
@@ -523,8 +566,11 @@ meta_tree_lookup_by_name (const char *name,
meta_tree_ref (tree);
G_UNLOCK (cached_trees);
- meta_tree_refresh (tree);
- return tree;
+ if (meta_tree_refresh (tree))
+ return tree;
+
+ meta_tree_unref (tree);
+ tree = NULL;
}
filename = g_build_filename (g_get_user_data_dir (), "gvfs-metadata", name, NULL);
@@ -604,7 +650,7 @@ meta_tree_has_new_journal_entries (MetaTree *tree)
/* Must be called with a write lock held */
-static void
+static gboolean
meta_tree_refresh_locked (MetaTree *tree, gboolean force_reread)
{
/* Needs to recheck since we dropped read lock */
@@ -612,16 +658,19 @@ meta_tree_refresh_locked (MetaTree *tree, gboolean force_reread)
{
if (tree->header)
meta_tree_clear (tree);
- meta_tree_init (tree);
+ return meta_tree_init (tree);
}
else if (meta_tree_has_new_journal_entries (tree))
meta_journal_validate_more (tree->journal);
+
+ return TRUE;
}
-void
+gboolean
meta_tree_refresh (MetaTree *tree)
{
gboolean needs_refresh;
+ gboolean res = TRUE;
g_rw_lock_reader_lock (&metatree_lock);
needs_refresh =
@@ -632,9 +681,11 @@ meta_tree_refresh (MetaTree *tree)
if (needs_refresh)
{
g_rw_lock_writer_lock (&metatree_lock);
- meta_tree_refresh_locked (tree, FALSE);
+ res = meta_tree_refresh_locked (tree, FALSE);
g_rw_lock_writer_unlock (&metatree_lock);
}
+
+ return res;
}
struct FindName {
@@ -2320,7 +2371,7 @@ meta_tree_flush_locked (MetaTree *tree)
meta_tree_get_filename (tree));
if (res)
/* Force re-read since we wrote a new file */
- meta_tree_refresh_locked (tree, TRUE);
+ res = meta_tree_refresh_locked (tree, TRUE);
meta_builder_free (builder);
diff --git a/metadata/metatree.h b/metadata/metatree.h
index f24b4e9b..d469b98e 100644
--- a/metadata/metatree.h
+++ b/metadata/metatree.h
@@ -63,7 +63,7 @@ MetaTree * meta_tree_lookup_by_name (const char *name,
gboolean for_write);
MetaTree * meta_tree_ref (MetaTree *tree);
void meta_tree_unref (MetaTree *tree);
-void meta_tree_refresh (MetaTree *tree);
+gboolean meta_tree_refresh (MetaTree *tree);
const char *meta_tree_get_filename (MetaTree *tree);
gboolean meta_tree_exists (MetaTree *tree);
gboolean meta_tree_is_on_nfs (MetaTree *tree);