diff options
author | Michael Cree <mcree@orcon.net.nz> | 2014-04-17 12:35:25 +0200 |
---|---|---|
committer | Ondrej Holy <oholy@redhat.com> | 2014-05-29 16:06:23 +0200 |
commit | d17e4dbfef0b9859b7d8a149b931cf685f9b4e15 (patch) | |
tree | 01cac33784638debd8f500759de4513d7adfeef3 /metadata | |
parent | 5aa709f89433962ea0bbd02401a2f0bb40d66120 (diff) | |
download | gvfs-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.c | 25 |
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) |