[gvfs] metadata: fix misaligned accesses to 64bit data



commit d17e4dbfef0b9859b7d8a149b931cf685f9b4e15
Author: Michael Cree <mcree orcon net nz>
Date:   Thu Apr 17 12:35:25 2014 +0200

    metadata: fix misaligned accesses to 64bit data
    
    Unfortunately the journal entries are only aligned to 32 bit boundaries
    but on some 64-bit RISC architectures (e.g. Alpha) this is insufficient
    to guarantee correct alignment of 64-bit accesses. This is not a show
    stopper but does cause inefficient traps to the kernel and pollution of
    kernel logs.  Rather than fix the alignment we provide a helper function,
    dependent on features specific to gcc, to correctly access a 64-bit datum
    that may be misaligned.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=726456

 metadata/metatree.c |   25 +++++++++++++++++++++++--
 1 files changed, 23 insertions(+), 2 deletions(-)
---
diff --git a/metadata/metatree.c b/metadata/metatree.c
index a6b3183..43766c8 100644
--- a/metadata/metatree.c
+++ b/metadata/metatree.c
@@ -132,6 +132,27 @@ struct _MetaTree {
   MetaJournal *journal;
 };
 
+/* Unfortunately the journal entries are only aligned to 32 bit boundaries
+ * but on some 64-bit RISC architectures (e.g. Alpha) this is insufficient
+ * to guarantee correct alignment of 64-bit accesses. This is not a show
+ * stopper but does cause inefficient traps to the kernel and pollution of
+ * kernel logs.  Rather than fix the alignment we provide a helper function,
+ * dependent on features specific to gcc, to correctly access a 64-bit datum
+ * that may be misaligned.
+ *
+ * See https://bugzilla.gnome.org/show_bug.cgi?id=726456
+ */
+#if defined(__GNUC__) && (defined(__alpha__) || defined(__mips__) || defined(__sparc__))
+struct una_u64 { guint64 x __attribute__((packed)); };
+static inline guint64 ldq_u(guint64 *p)
+{
+  const struct una_u64 *ptr = (const struct una_u64 *) p;
+  return ptr->x;
+}
+#else
+#define ldq_u(x) (*(x))
+#endif
+
 static void         meta_tree_refresh_locked   (MetaTree    *tree,
                                                gboolean     force_reread);
 static MetaJournal *meta_journal_open          (MetaTree    *tree,
@@ -1230,7 +1251,7 @@ meta_journal_iterate (MetaJournal *journal,
           break;
         }
 
-      mtime = GUINT64_FROM_BE (entry->mtime);
+      mtime = GUINT64_FROM_BE (ldq_u (&(entry->mtime)));
       journal_path = &entry->path[0];
 
       if (journal_entry_is_key_type (entry) &&
@@ -2214,7 +2235,7 @@ apply_journal_to_builder (MetaTree *tree,
   entry = journal->first_entry;
   while (entry < journal->last_entry)
     {
-      mtime = GUINT64_FROM_BE (entry->mtime);
+      mtime = GUINT64_FROM_BE (ldq_u (&(entry->mtime)));
       journal_path = &entry->path[0];
 
       switch (entry->entry_type)


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