xfs
[Top] [All Lists]

[PATCH] xfs: fix unaligned access in readdir

To: jailbird@xxxxxxxxxxxxxxxx
Subject: [PATCH] xfs: fix unaligned access in readdir
From: Christoph Hellwig <hch@xxxxxx>
Date: Wed, 26 Dec 2007 16:48:57 +0100
Cc: xfs@xxxxxxxxxxx
Sender: xfs-bounce@xxxxxxxxxxx
User-agent: Mutt/1.3.28i
This patch should fix the issue seen on Alpha with unaligned accesses
in the new readdir code.   By aligning each dirent to sizeof(u64) we'll
avoid unaligned accesses.  To make doubly sure we're not hitting
problems also rearrange struct hack_dirent to avoid holes.


Signed-off-by: Christoph Hellwig <hch@xxxxxx>

Index: linux-2.6-xfs/fs/xfs/linux-2.6/xfs_file.c
===================================================================
--- linux-2.6-xfs.orig/fs/xfs/linux-2.6/xfs_file.c      2007-12-26 
15:35:33.000000000 +0100
+++ linux-2.6-xfs/fs/xfs/linux-2.6/xfs_file.c   2007-12-26 15:40:14.000000000 
+0100
@@ -262,9 +262,9 @@ xfs_file_readdir(
 #else
 
 struct hack_dirent {
-       int             namlen;
-       loff_t          offset;
        u64             ino;
+       loff_t          offset;
+       int             namlen;
        unsigned int    d_type;
        char            name[];
 };
@@ -286,8 +286,10 @@ xfs_hack_filldir(
 {
        struct hack_callback *buf = __buf;
        struct hack_dirent *de = (struct hack_dirent *)(buf->dirent + 
buf->used);
+       unsigned int reclen;
 
-       if (buf->used + sizeof(struct hack_dirent) + namlen > buf->len)
+       reclen = ALIGN(sizeof(struct hack_dirent) + namlen, sizeof(u64));
+       if (buf->used + reclen > buf->len)
                return -EINVAL;
 
        de->namlen = namlen;
@@ -295,7 +297,7 @@ xfs_hack_filldir(
        de->ino = ino;
        de->d_type = d_type;
        memcpy(de->name, name, namlen);
-       buf->used += sizeof(struct hack_dirent) + namlen;
+       buf->used += reclen;
        return 0;
 }
 
@@ -335,7 +337,8 @@ xfs_file_readdir(
                offset = filp->f_pos;
 
        while (!eof) {
-               int reclen;
+               unsigned int reclen;
+
                start_offset = offset;
 
                buf.used = 0;
@@ -356,7 +359,8 @@ xfs_file_readdir(
                                goto done;
                        }
 
-                       reclen = sizeof(struct hack_dirent) + de->namlen;
+                       reclen = ALIGN(sizeof(struct hack_dirent) + de->namlen,
+                                      sizeof(u64));
                        size -= reclen;
                        de = (struct hack_dirent *)((char *)de + reclen);
                        curr_offset = de->offset /* & 0x7fffffff */;


<Prev in Thread] Current Thread [Next in Thread>