Message ID | 161017368431.1141483.1015560955108076159.stgit@magnolia (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | xfs: add the ability to flag a fs for repair | expand |
On Fri, Jan 08, 2021 at 10:28:04PM -0800, Darrick J. Wong wrote: > From: Darrick J. Wong <djwong@kernel.org> > > During an inode scan (aka phase 3) when we're scanning the inode btree > to find files to check, make sure that each invocation of inumbers > actually gives us an inobt record with a startino that's at least as > large as what we asked for so that we always make forward progress. Heh, this should have gone in the random fixes series. Sigh... --D > Signed-off-by: Darrick J. Wong <djwong@kernel.org> > --- > scrub/inodes.c | 16 ++++++++++++++++ > 1 file changed, 16 insertions(+) > > > diff --git a/scrub/inodes.c b/scrub/inodes.c > index bdc12df3..4550db83 100644 > --- a/scrub/inodes.c > +++ b/scrub/inodes.c > @@ -119,6 +119,7 @@ scan_ag_inodes( > struct scrub_ctx *ctx = (struct scrub_ctx *)wq->wq_ctx; > struct xfs_bulkstat *bs; > struct xfs_inumbers *inumbers; > + uint64_t nextino = cvt_agino_to_ino(&ctx->mnt, agno, 0); > int i; > int error; > int stale_count = 0; > @@ -153,6 +154,21 @@ scan_ag_inodes( > /* Find the inode chunk & alloc mask */ > error = -xfrog_inumbers(&ctx->mnt, ireq); > while (!error && !si->aborted && ireq->hdr.ocount > 0) { > + /* > + * Make sure that we always make forward progress while we > + * scan the inode btree. > + */ > + if (nextino > inumbers->xi_startino) { > + str_corrupt(ctx, descr, > + _("AG %u inode btree is corrupt near agino %lu, got %lu"), agno, > + cvt_ino_to_agino(&ctx->mnt, nextino), > + cvt_ino_to_agino(&ctx->mnt, > + ireq->inumbers[0].xi_startino)); > + si->aborted = true; > + break; > + } > + nextino = ireq->hdr.ino; > + > /* > * We can have totally empty inode chunks on filesystems where > * there are more than 64 inodes per block. Skip these. >
diff --git a/scrub/inodes.c b/scrub/inodes.c index bdc12df3..4550db83 100644 --- a/scrub/inodes.c +++ b/scrub/inodes.c @@ -119,6 +119,7 @@ scan_ag_inodes( struct scrub_ctx *ctx = (struct scrub_ctx *)wq->wq_ctx; struct xfs_bulkstat *bs; struct xfs_inumbers *inumbers; + uint64_t nextino = cvt_agino_to_ino(&ctx->mnt, agno, 0); int i; int error; int stale_count = 0; @@ -153,6 +154,21 @@ scan_ag_inodes( /* Find the inode chunk & alloc mask */ error = -xfrog_inumbers(&ctx->mnt, ireq); while (!error && !si->aborted && ireq->hdr.ocount > 0) { + /* + * Make sure that we always make forward progress while we + * scan the inode btree. + */ + if (nextino > inumbers->xi_startino) { + str_corrupt(ctx, descr, + _("AG %u inode btree is corrupt near agino %lu, got %lu"), agno, + cvt_ino_to_agino(&ctx->mnt, nextino), + cvt_ino_to_agino(&ctx->mnt, + ireq->inumbers[0].xi_startino)); + si->aborted = true; + break; + } + nextino = ireq->hdr.ino; + /* * We can have totally empty inode chunks on filesystems where * there are more than 64 inodes per block. Skip these.