Package: gvfs Version: 1.6.3-2 Severity: normal Tags: upstream patch The gvfs metatree code has misaligned accesses to 64 bit data. On the Alpha architecture this causes traps to the kernel to complete the memory access (i.e. very inefficient) and pollutes the kernel logs with messages. While not a show stopper it is nevertheless annoying, particularly as the gvfs library is linked in a number of other packages (such as nautilus and evince) and they are all generating unaligned trap messages in the kernel log.
I attach a patch that "fixes" the problem by providing a means to tell the compiler (provided it is gcc) that the access is misaligned at the specific points in the code, thus the compiler generates code that can access the datum without causing unaligned traps to the kernel. The patch is really just to illustrate where the problem occurs -- a better approach is probably to fix the "Journal Entry" in the code to contain the 64 bit data (the field "mtime" in the structure) on 64 bit boundaries. I noted a comment in the code that said the mtime field must be 32 bit aligned but didn't give any reasons why, so I decided not to risk modifying the alignment. -- System Information: Debian Release: squeeze/sid APT prefers unstable APT policy: (500, 'unstable') Architecture: alpha Kernel: Linux 2.6.35.4-dp264-p+ Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages gvfs depends on: ii libc6.1 2.11.2-5 Embedded GNU C Library: Shared lib ii libdbus-1-3 1.2.24-3 simple interprocess messaging syst ii libexpat1 2.0.1-7 XML parsing C library - runtime li ii libgconf2-4 2.28.1-3 GNOME configuration database syste ii libgdu0 2.30.1-2 GObject based Disk Utility Library ii libglib2.0-0 2.24.1-1 The GLib library of C routines ii libgnome-keyring0 2.30.1-1 GNOME keyring services library ii libudev0 161-1 libudev shared library ii x11-utils 7.5+4 X11 utilities Versions of packages gvfs recommends: ii dbus 1.2.24-3 simple interprocess messaging syst ii policykit-1-gnome 0.96-2 GNOME authentication agent for Pol Versions of packages gvfs suggests: ii gvfs-backends 1.6.3-2 userspace virtual filesystem - bac -- no debconf information
--- gvfs-1.6.3/metadata/metatree.c 2010-02-21 14:53:30.000000000 +1300 +++ gvfs-1.6.3-mod/metadata/metatree.c 2010-09-06 22:18:48.000000000 +1200 @@ -170,6 +170,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. This causes no loss of inefficiency on + architectures where alignment is not an issue provided we are compiled + with compiler optimisation turned on. */ +#ifdef __GNUC__ +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); static MetaJournal *meta_journal_open (MetaTree *tree, const char *filename, @@ -1303,7 +1324,7 @@ meta_journal_iterate (MetaJournal *journ sizep = (guint32 *)entry; entry = (MetaJournalEntry *)((char *)entry - GUINT32_FROM_BE (*(sizep-1))); - 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) && @@ -2287,7 +2308,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)