]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_scrub: don't revisit scanned inodes when reprocessing a stale inode
authorDarrick J. Wong <djwong@kernel.org>
Wed, 18 May 2022 02:53:22 +0000 (22:53 -0400)
committerEric Sandeen <sandeen@sandeen.net>
Wed, 18 May 2022 02:53:22 +0000 (22:53 -0400)
If we decide to restart an inode chunk walk because one of the inodes is
stale, make sure that we don't walk an inode that's been scanned before.
This ensure we always make forward progress.

Found by observing backwards inode scan progress while running xfs/285.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
[sandeen: add comment above forward-progress test]
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
scrub/inodes.c

index 41e5fdc75f79a8fab952927d185f2ed215fd8bed..ffe7eb3344101f94c73730e9caf6e13160583693 100644 (file)
@@ -210,6 +210,7 @@ scan_ag_bulkstat(
        struct scan_inodes      *si = ichunk->si;
        struct xfs_bulkstat     *bs;
        struct xfs_inumbers     *inumbers = &ireq->inumbers[0];
+       uint64_t                last_ino = 0;
        int                     i;
        int                     error;
        int                     stale_count = 0;
@@ -229,8 +230,14 @@ retry:
        /* Iterate all the inodes. */
        bs = &breq->bulkstat[0];
        for (i = 0; !si->aborted && i < inumbers->xi_alloccount; i++, bs++) {
+               uint64_t        scan_ino = bs->bs_ino;
+
+               /* ensure forward progress if we retried */
+               if (scan_ino < last_ino)
+                       continue;
+
                descr_set(&dsc_bulkstat, bs);
-               handle.ha_fid.fid_ino = bs->bs_ino;
+               handle.ha_fid.fid_ino = scan_ino;
                handle.ha_fid.fid_gen = bs->bs_gen;
                error = si->fn(ctx, &handle, bs, si->arg);
                switch (error) {
@@ -260,6 +267,7 @@ _("Changed too many times during scan; giving up."));
                        si->aborted = true;
                        goto out;
                }
+               last_ino = scan_ino;
        }
 
 err: