[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>

authored by Christoph Hellwig and committed by Lachlan McIlroy aea6ad0c fd0b45df

+10 -6
+10 -6
fs/xfs/linux-2.6/xfs_file.c
··· 261 261 #else 262 262 263 263 struct hack_dirent { 264 - int namlen; 265 - loff_t offset; 266 264 u64 ino; 265 + loff_t offset; 266 + int namlen; 267 267 unsigned int d_type; 268 268 char name[]; 269 269 }; ··· 285 285 { 286 286 struct hack_callback *buf = __buf; 287 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 292 return -EINVAL; 291 293 292 294 de->namlen = namlen; ··· 296 294 de->ino = ino; 297 295 de->d_type = d_type; 298 296 memcpy(de->name, name, namlen); 299 - buf->used += sizeof(struct hack_dirent) + namlen; 297 + buf->used += reclen; 300 298 return 0; 301 299 } 302 300 ··· 336 334 offset = filp->f_pos; 337 335 338 336 while (!eof) { 339 - int reclen; 337 + unsigned int reclen; 338 + 340 339 start_offset = offset; 341 340 342 341 buf.used = 0; ··· 358 355 goto done; 359 356 } 360 357 361 - reclen = sizeof(struct hack_dirent) + de->namlen; 358 + reclen = ALIGN(sizeof(struct hack_dirent) + de->namlen, 359 + sizeof(u64)); 362 360 size -= reclen; 363 361 de = (struct hack_dirent *)((char *)de + reclen); 364 362 curr_offset = de->offset /* & 0x7fffffff */;