aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2008-01-10 00:43:26 -0500
committerLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2008-01-11 02:05:04 -0500
commitaea6ad0ce5e215ce99fe9e3edd9268f696862d8f (patch)
treeab7e37bb1a046cabb01479b313493731359c68eb
parentfd0b45dfd1858c6b49d06355a460bcf36d654c06 (diff)
[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. SGI-PV: 975411 SGI-Modid: xfs-linux-melb:xfs-kern:30302a Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 4847eb83fc18..21a1c2b1c5fc 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -261,9 +261,9 @@ xfs_file_readdir(
261#else 261#else
262 262
263struct hack_dirent { 263struct hack_dirent {
264 int namlen;
265 loff_t offset;
266 u64 ino; 264 u64 ino;
265 loff_t offset;
266 int namlen;
267 unsigned int d_type; 267 unsigned int d_type;
268 char name[]; 268 char name[];
269}; 269};
@@ -285,8 +285,10 @@ xfs_hack_filldir(
285{ 285{
286 struct hack_callback *buf = __buf; 286 struct hack_callback *buf = __buf;
287 struct hack_dirent *de = (struct hack_dirent *)(buf->dirent + buf->used); 287 struct hack_dirent *de = (struct hack_dirent *)(buf->dirent + buf->used);
288 unsigned int reclen;
288 289
289 if (buf->used + sizeof(struct hack_dirent) + namlen > buf->len) 290 reclen = ALIGN(sizeof(struct hack_dirent) + namlen, sizeof(u64));
291 if (buf->used + reclen > buf->len)
290 return -EINVAL; 292 return -EINVAL;
291 293
292 de->namlen = namlen; 294 de->namlen = namlen;
@@ -294,7 +296,7 @@ xfs_hack_filldir(
294 de->ino = ino; 296 de->ino = ino;
295 de->d_type = d_type; 297 de->d_type = d_type;
296 memcpy(de->name, name, namlen); 298 memcpy(de->name, name, namlen);
297 buf->used += sizeof(struct hack_dirent) + namlen; 299 buf->used += reclen;
298 return 0; 300 return 0;
299} 301}
300 302
@@ -334,7 +336,8 @@ xfs_file_readdir(
334 offset = filp->f_pos; 336 offset = filp->f_pos;
335 337
336 while (!eof) { 338 while (!eof) {
337 int reclen; 339 unsigned int reclen;
340
338 start_offset = offset; 341 start_offset = offset;
339 342
340 buf.used = 0; 343 buf.used = 0;
@@ -355,7 +358,8 @@ xfs_file_readdir(
355 goto done; 358 goto done;
356 } 359 }
357 360
358 reclen = sizeof(struct hack_dirent) + de->namlen; 361 reclen = ALIGN(sizeof(struct hack_dirent) + de->namlen,
362 sizeof(u64));
359 size -= reclen; 363 size -= reclen;
360 de = (struct hack_dirent *)((char *)de + reclen); 364 de = (struct hack_dirent *)((char *)de + reclen);
361 curr_offset = de->offset /* & 0x7fffffff */; 365 curr_offset = de->offset /* & 0x7fffffff */;