aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorLachlan McIlroy <lachlan@sgi.com>2007-10-11 21:12:20 -0400
committerTim Shimmin <tes@chook.melbourne.sgi.com>2007-10-16 00:21:56 -0400
commitc2cba57e83dd7d2dda4ec425998b536669632c82 (patch)
tree89ae704e5306d9b8eecdf13abba9eb335f2c82f4 /fs/xfs
parent3e5daf05a0c7cce36dc2db41933b14b36d2048dc (diff)
[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')
-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 1edd9afb664b..9972992fd3c3 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -619,21 +619,25 @@ xfs_bulkstat(
619 } 619 }
620 } 620 }
621 } 621 }
622 ino = XFS_AGINO_TO_INO(mp, agno, agino);
623 bno = XFS_AGB_TO_DADDR(mp, agno, agbno);
622 /* 624 /*
623 * Skip if this inode is free. 625 * Skip if this inode is free.
624 */ 626 */
625 if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free) 627 if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free) {
628 lastino = ino;
626 continue; 629 continue;
630 }
627 /* 631 /*
628 * Count used inodes as free so we can tell 632 * Count used inodes as free so we can tell
629 * when the chunk is used up. 633 * when the chunk is used up.
630 */ 634 */
631 irbp->ir_freecount++; 635 irbp->ir_freecount++;
632 ino = XFS_AGINO_TO_INO(mp, agno, agino);
633 bno = XFS_AGB_TO_DADDR(mp, agno, agbno);
634 if (!xfs_bulkstat_use_dinode(mp, flags, bp, 636 if (!xfs_bulkstat_use_dinode(mp, flags, bp,
635 clustidx, &dip)) 637 clustidx, &dip)) {
638 lastino = ino;
636 continue; 639 continue;
640 }
637 /* 641 /*
638 * If we need to do an iget, cannot hold bp. 642 * If we need to do an iget, cannot hold bp.
639 * Drop it, until starting the next cluster. 643 * Drop it, until starting the next cluster.
@@ -694,8 +698,7 @@ xfs_bulkstat(
694 if (end_of_ag) { 698 if (end_of_ag) {
695 agno++; 699 agno++;
696 agino = 0; 700 agino = 0;
697 } else 701 }
698 agino = XFS_INO_TO_AGINO(mp, lastino);
699 } else 702 } else
700 break; 703 break;
701 } 704 }