Skip to contentSkip to conversation

xfs: fix unaligned access in readdir

PATCH In review Christoph Hellwig 2 participants 3 messages Dec 26, 2007 – Jan 7, 2008 XFS filesystem

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 xfs: fix unaligned access in readdir

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.

fs/xfs/linux-2.6/xfs_file.c +10 -6
Index: linux-2.6-xfs/fs/xfs/linux-2.6/xfs_file.c
===================================================================
@@ -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 */;
#1 lore raw

This patch does indeed fix the problem.

Thanks!

-Dustin

Quoted 66 lines · Christoph Hellwig

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.

Index: linux-2.6-xfs/fs/xfs/linux-2.6/xfs_file.c
===================================================================

fs/xfs/linux-2.6/xfs_file.c +10 -6
@@ -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 */;
#2 lore raw
In reply to Christoph Hellwig
Quoted 4 lines · Christoph Hellwig

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.

If anyone in Melbourne is getting back from Holidays it would be nice if we could get this patch into 2.6.24-final still..