From: "Darrick J. Wong" <djwong@kernel.org>
To: Christoph Hellwig <hch@lst.de>
Cc: cem@kernel.org, stable@vger.kernel.org, linux-xfs@vger.kernel.org
Subject: Re: [PATCH 6/6] xfs: don't livelock in scrub on a circular unlinked list
Date: Thu, 16 Jul 2026 14:47:20 -0700 [thread overview]
Message-ID: <20260716214720.GR7380@frogsfrogsfrogs> (raw)
In-Reply-To: <20260716082421.GH12330@lst.de>
On Thu, Jul 16, 2026 at 10:24:21AM +0200, Christoph Hellwig wrote:
> On Wed, Jul 15, 2026 at 11:07:40PM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <djwong@kernel.org>
> >
> > LOLLM points out that online fsck can livelock if an unlinked inode list
> > contains a loop. Use a bitmap to detect cycles.
>
> Didn't we recently have some AI generated patch for the same thing?
Yes.
> Either way, this does actually look reasonable. But also complex
> enough that I really want a test case that creates an image with
> such a corruption to test this case before we merge the kernel code
> as this is something that basically requires a maliciously crafted
> image, and we trade new otherwise untested code for a theoretical
> bug.
I'll try to work on that one today.
> > +static int
> > +xchk_iunlink_bucket(
> > + struct xfs_scrub *sc,
> > + unsigned int bucket,
> > + xfs_agino_t agino)
>
> Maybe add a comment what this function tests?
/*
* Walk the incore unlinked list for a particular AGI bucket to construct
* the unlinked inode bitmap for later reconstruction of the unlinked list.
* Returns 1 if we should keep checking, 0 to stop checking, or a negative
* errno.
*/
>
> > +{
> > + struct xagino_bitmap seen;
> > + struct xfs_inode *ip;
> > + int ret = 0;
> > +
> > + xagino_bitmap_init(&seen);
> > +
> > + while (agino != NULLAGINO) {
> > + unsigned int len = 1;
> > +
> > + if (agino % XFS_AGI_UNLINKED_BUCKETS != bucket) {
> > + xchk_block_set_corrupt(sc, sc->sa.agi_bp);
> > + goto bad;
> > + }
>
> Handle entries that should not be here, makes sense.
>
> > +
> > + if (xagino_bitmap_test(&seen, agino, &len)) {
> > + xchk_block_set_corrupt(sc, sc->sa.agi_bp);
> > + goto bad;
> > + }
>
> Check that we don't have duplicates, makes sense.
>
> > + ip = xfs_iunlink_lookup(sc->sa.pag, agino);
> > + if (!ip) {
> > + xchk_block_set_corrupt(sc, sc->sa.agi_bp);
> > + goto bad;
> > + }
> > +
> > + if (!xfs_inode_on_unlinked_list(ip)) {
> > + xchk_block_set_corrupt(sc, sc->sa.agi_bp);
> > + goto bad;
> > + }
>
> The that that the inode actually is on the unlinked list, makes
> sense.
>
> > for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) {
> > - xfs_agino_t agino = be32_to_cpu(agi->agi_unlinked[i]);
> > + int ret;
> >
> > - while (agino != NULLAGINO) {
> > - if (agino % XFS_AGI_UNLINKED_BUCKETS != i) {
> > - xchk_block_set_corrupt(sc, sc->sa.agi_bp);
> > - return;
> > - }
>
> Ahh, and this is mostly existing code...
>
> Maybe split the reactoring into a separate helper into a prep patch?
Ok will do.
--D
prev parent reply other threads:[~2026-07-16 21:47 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-16 6:06 [PATCHSET] xfs: LLM-inspired bug fixes, part 3 Darrick J. Wong
2026-07-16 6:06 ` [PATCH 1/6] xfs: check cowextsize in xrep_inode_cowextsize Darrick J. Wong
2026-07-16 8:18 ` Christoph Hellwig
2026-07-16 6:06 ` [PATCH 2/6] xfs: fix transaction block reservation in xrep_rtbitmap Darrick J. Wong
2026-07-16 8:18 ` Christoph Hellwig
2026-07-16 6:06 ` [PATCH 3/6] xfs: rtsummary scrub should treat rtbitmap corruption errors as an xref error Darrick J. Wong
2026-07-16 8:19 ` Christoph Hellwig
2026-07-16 6:07 ` [PATCH 4/6] xfs: zero i_nlink before repair puts inode on unlinked list Darrick J. Wong
2026-07-16 8:19 ` Christoph Hellwig
2026-07-16 6:07 ` [PATCH 5/6] xfs: mark nonzero sb_gquotino as corrupt on metadir filesystems Darrick J. Wong
2026-07-16 8:19 ` Christoph Hellwig
2026-07-16 6:07 ` [PATCH 6/6] xfs: don't livelock in scrub on a circular unlinked list Darrick J. Wong
2026-07-16 8:24 ` Christoph Hellwig
2026-07-16 21:47 ` Darrick J. Wong [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260716214720.GR7380@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=cem@kernel.org \
--cc=hch@lst.de \
--cc=linux-xfs@vger.kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.