]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
repair: check ino alignment value to avoid mod by zero
authorBrian Foster <bfoster@redhat.com>
Thu, 5 Feb 2015 23:32:32 +0000 (10:32 +1100)
committerDave Chinner <david@fromorbit.com>
Thu, 5 Feb 2015 23:32:32 +0000 (10:32 +1100)
xfs_repair checks inode records for valid alignment according to the
alignment specified in the superblock. It currently performs the
alignment check whenever fs_aligned_inodes is set, which is determined
based on whether the fs supports the field.

Support for the field does not guarantee its value is non-zero, however.
For example, a large block size fs on a large page size arch (e.g.,
ppc64):

mkfs.xfs -f -m crc=1,finobt=1 -b size=64k <dev>

... can lead to incorrect badly aligned inode record messages from
xfs_repair and other problems.

Update the inobt and finobt checks to verify that alignment is a
non-zero value before attempting to use it to divide (mod) by zero.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
repair/scan.c

index 142d8d783f41058e94ea80d03b8dc315fa028b07..ce8d7f5f83b73f06d260681ed9da82943475cfbe 100644 (file)
@@ -770,7 +770,8 @@ scan_single_ino_chunk(
            (inodes_per_block <= XFS_INODES_PER_CHUNK && off !=  0) ||
            (inodes_per_block > XFS_INODES_PER_CHUNK &&
             off % XFS_INODES_PER_CHUNK != 0) ||
-           (fs_aligned_inodes && agbno % fs_ino_alignment != 0))  {
+           (fs_aligned_inodes && fs_ino_alignment &&
+            agbno % fs_ino_alignment != 0))  {
                do_warn(
        _("badly aligned inode rec (starting inode = %" PRIu64 ")\n"),
                        lino);
@@ -929,7 +930,8 @@ scan_single_finobt_chunk(
            (inodes_per_block <= XFS_INODES_PER_CHUNK && off !=  0) ||
            (inodes_per_block > XFS_INODES_PER_CHUNK &&
             off % XFS_INODES_PER_CHUNK != 0) ||
-           (fs_aligned_inodes && agbno % fs_ino_alignment != 0)) {
+           (fs_aligned_inodes && fs_ino_alignment &&
+            agbno % fs_ino_alignment != 0)) {
                do_warn(
        _("badly aligned finobt inode rec (starting inode = %" PRIu64 ")\n"),
                        lino);