summaryrefslogtreecommitdiff
path: root/metadata
diff options
context:
space:
mode:
authorMichael Cree <mcree@orcon.net.nz>2014-04-17 12:35:25 +0200
committerOndrej Holy <oholy@redhat.com>2014-05-29 16:06:23 +0200
commitd17e4dbfef0b9859b7d8a149b931cf685f9b4e15 (patch)
tree01cac33784638debd8f500759de4513d7adfeef3 /metadata
parent5aa709f89433962ea0bbd02401a2f0bb40d66120 (diff)
downloadgvfs-d17e4dbfef0b9859b7d8a149b931cf685f9b4e15.tar.gz
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
Diffstat (limited to 'metadata')
-rw-r--r--metadata/metatree.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/metadata/metatree.c b/metadata/metatree.c
index a6b3183b..43766c83 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)