From: Darrick J. Wong Date: Mon, 24 Feb 2025 18:21:42 +0000 (-0800) Subject: xfs_scrub: selectively re-run bulkstat after re-running inumbers X-Git-Tag: v6.14.0~154 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b95546f18e6bfbe477e0bd3c726c9ae8a6c9f2ff;p=thirdparty%2Fxfsprogs-dev.git xfs_scrub: selectively re-run bulkstat after re-running inumbers In the phase 3 inode scan, don't bother retrying the inumbers -> bulkstat conversion unless inumbers returns the same startino and there are allocated inodes. If inumbers returns data for a totally different inobt record, that means the whole inode chunk was freed. Cc: # v5.18.0 Fixes: 245c72a6eeb720 ("xfs_scrub: balance inode chunk scan across CPUs") Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- diff --git a/scrub/inodes.c b/scrub/inodes.c index c32dfb62..8bdfa0b3 100644 --- a/scrub/inodes.c +++ b/scrub/inodes.c @@ -60,6 +60,8 @@ bulkstat_for_inumbers( int i; int error; + assert(inumbers->xi_allocmask != 0); + /* First we try regular bulkstat, for speed. */ breq->hdr.ino = inumbers->xi_startino; breq->hdr.icount = inumbers->xi_alloccount; @@ -246,11 +248,24 @@ retry: case ESTALE: { stale_count++; if (stale_count < 30) { - ireq->hdr.ino = inumbers->xi_startino; + uint64_t old_startino; + + ireq->hdr.ino = old_startino = + inumbers->xi_startino; error = -xfrog_inumbers(&ctx->mnt, ireq); if (error) goto err; - goto retry; + /* + * Retry only if inumbers returns the same + * inobt record as the previous record and + * there are allocated inodes in it. + */ + if (!si->aborted && + ireq->hdr.ocount > 0 && + inumbers->xi_alloccount > 0 && + inumbers->xi_startino == old_startino) + goto retry; + goto out; } str_info(ctx, descr_render(&dsc_bulkstat), _("Changed too many times during scan; giving up."));