aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_itable.c
diff options
context:
space:
mode:
authorLachlan McIlroy <lachlan@sgi.com>2007-10-12 11:12:20 +1000
committerTim Shimmin <tes@chook.melbourne.sgi.com>2007-10-16 14:21:56 +1000
commitc2cba57e83dd7d2dda4ec425998b536669632c82 (patch)
tree89ae704e5306d9b8eecdf13abba9eb335f2c82f4 /fs/xfs/xfs_itable.c
parent3e5daf05a0c7cce36dc2db41933b14b36d2048dc (diff)
downloadkernel_samsung_smdk4412-c2cba57e83dd7d2dda4ec425998b536669632c82.zip
kernel_samsung_smdk4412-c2cba57e83dd7d2dda4ec425998b536669632c82.tar.gz
kernel_samsung_smdk4412-c2cba57e83dd7d2dda4ec425998b536669632c82.tar.bz2
[XFS] This fix prevents bulkstat from spinning in an infinite loop.
Here 'agino' increments through the inodes in an allocation group. At the end of the innermost 'for' loop it will hold the value of the next inode to look at (ie the first inode in the next cluster/chunk). Assigning 'lastino' to 'agino' resets it to the last inode in the last inode cluster we just looked at. This causes us to look up the very same cluster and examine all the inodes all over again, and again, and again... We also want to set 'lastino' for the cases when we're not interested in the inode so that the next call to bulkstat won't re-examine the same uninteresting inodes. SGI-PV: 971064 SGI-Modid: xfs-linux-melb:xfs-kern:29840a Signed-off-by: Lachlan McIlroy <lachlan@sgi.com> Signed-off-by: David Chinner <dgc@sgi.com> Signed-off-by: Tim Shimmin <tes@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_itable.c')
-rw-r--r--fs/xfs/xfs_itable.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 1edd9af..9972992 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -619,21 +619,25 @@ xfs_bulkstat(
}
}
}
+ ino = XFS_AGINO_TO_INO(mp, agno, agino);
+ bno = XFS_AGB_TO_DADDR(mp, agno, agbno);
/*
* Skip if this inode is free.
*/
- if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free)
+ if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free) {
+ lastino = ino;
continue;
+ }
/*
* Count used inodes as free so we can tell
* when the chunk is used up.
*/
irbp->ir_freecount++;
- ino = XFS_AGINO_TO_INO(mp, agno, agino);
- bno = XFS_AGB_TO_DADDR(mp, agno, agbno);
if (!xfs_bulkstat_use_dinode(mp, flags, bp,
- clustidx, &dip))
+ clustidx, &dip)) {
+ lastino = ino;
continue;
+ }
/*
* If we need to do an iget, cannot hold bp.
* Drop it, until starting the next cluster.
@@ -694,8 +698,7 @@ xfs_bulkstat(
if (end_of_ag) {
agno++;
agino = 0;
- } else
- agino = XFS_INO_TO_AGINO(mp, lastino);
+ }
} else
break;
}