xfs
[Top] [All Lists]

review: fix infinite loop in bulkstat

To: xfs-dev <xfs-dev@xxxxxxx>, xfs-oss <xfs@xxxxxxxxxxx>
Subject: review: fix infinite loop in bulkstat
From: Lachlan McIlroy <lachlan@xxxxxxx>
Date: Thu, 04 Oct 2007 15:20:12 +1000
Reply-to: lachlan@xxxxxxx
Sender: xfs-bounce@xxxxxxxxxxx
User-agent: Thunderbird 2.0.0.4 (X11/20070604)
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 wont re-examine the
same uninteresting inodes.
--- fs/xfs/xfs_itable.c_1.155   2007-10-03 13:05:22.000000000 +1000
+++ fs/xfs/xfs_itable.c 2007-10-04 12:16:46.000000000 +1000
@@ -622,8 +622,10 @@ xfs_bulkstat(
                                /*
                                 * 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.
@@ -632,8 +634,10 @@ xfs_bulkstat(
                                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;
        }
<Prev in Thread] Current Thread [Next in Thread>