From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: Dave Chinner <david@fromorbit.com>
Cc: linux-xfs@vger.kernel.org
Subject: Re: [PATCH 11/25] xfs: scrub the AGI
Date: Tue, 3 Oct 2017 21:25:01 -0700 [thread overview]
Message-ID: <20171004042501.GO6503@magnolia> (raw)
In-Reply-To: <20171004014347.GX3666@dastard>
On Wed, Oct 04, 2017 at 12:43:47PM +1100, Dave Chinner wrote:
> On Tue, Oct 03, 2017 at 01:41:59PM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <darrick.wong@oracle.com>
> >
> > Add a forgotten check to the AGI verifier, then wire up the scrub
> > infrastructure to check the AGI contents.
> >
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > ---
> > fs/xfs/libxfs/xfs_fs.h | 3 +-
> > fs/xfs/scrub/agheader.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++
> > fs/xfs/scrub/common.c | 6 ++-
> > fs/xfs/scrub/scrub.c | 4 ++
> > fs/xfs/scrub/scrub.h | 1 +
> > 5 files changed, 99 insertions(+), 3 deletions(-)
> >
> >
> > diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
> > index aeb2a66..1e326dd 100644
> > --- a/fs/xfs/libxfs/xfs_fs.h
> > +++ b/fs/xfs/libxfs/xfs_fs.h
> > @@ -487,9 +487,10 @@ struct xfs_scrub_metadata {
> > #define XFS_SCRUB_TYPE_SB 1 /* superblock */
> > #define XFS_SCRUB_TYPE_AGF 2 /* AG free header */
> > #define XFS_SCRUB_TYPE_AGFL 3 /* AG free list */
> > +#define XFS_SCRUB_TYPE_AGI 4 /* AG inode header */
> >
> > /* Number of scrub subcommands. */
> > -#define XFS_SCRUB_TYPE_NR 4
> > +#define XFS_SCRUB_TYPE_NR 5
> >
> > /* i: Repair this metadata. */
> > #define XFS_SCRUB_IFLAG_REPAIR (1 << 0)
> > diff --git a/fs/xfs/scrub/agheader.c b/fs/xfs/scrub/agheader.c
> > index 7fe6630..3d269c2 100644
> > --- a/fs/xfs/scrub/agheader.c
> > +++ b/fs/xfs/scrub/agheader.c
> > @@ -535,3 +535,91 @@ xfs_scrub_agfl(
> > out:
> > return error;
> > }
> > +
> > +/* AGI */
> > +
> > +/* Scrub the AGI. */
> > +int
> > +xfs_scrub_agi(
> > + struct xfs_scrub_context *sc)
> > +{
> > + struct xfs_mount *mp = sc->mp;
> > + struct xfs_agi *agi;
> > + xfs_daddr_t daddr;
> > + xfs_daddr_t eofs;
> > + xfs_agnumber_t agno;
> > + xfs_agblock_t agbno;
> > + xfs_agblock_t eoag;
> > + xfs_agino_t agino;
> > + xfs_agino_t first_agino;
> > + xfs_agino_t last_agino;
> > + int i;
> > + int level;
> > + int error = 0;
> > +
> > + agno = sc->sm->sm_agno;
> > + error = xfs_scrub_load_ag_headers(sc, agno, XFS_SCRUB_TYPE_AGI);
> > + if (!xfs_scrub_op_ok(sc, agno, XFS_AGI_BLOCK(sc->mp), &error))
> > + goto out;
> > +
> > + agi = XFS_BUF_TO_AGI(sc->sa.agi_bp);
> > + eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
> > +
> > + /* Check the AG length */
> > + eoag = be32_to_cpu(agi->agi_length);
> > + if (eoag != xfs_scrub_ag_blocks(mp, agno))
> > + xfs_scrub_block_set_corrupt(sc, sc->sa.agi_bp);
>
> Should we be cross checking that the AGI and AGF both have
> the same length here?
Isn't that what this does? Albeit indirectly?
xfs_scrub_ag_blocks returns sb_agcount for every AG except the last one.
For the last AG it returns (sb_dblocks - (all blocks in the other AGs))
which should be the same as agf->agf_length, right?
> > +
> > + /* Check btree roots and levels */
> > + agbno = be32_to_cpu(agi->agi_root);
> > + daddr = XFS_AGB_TO_DADDR(mp, agno, agbno);
> > + if (agbno <= XFS_AGI_BLOCK(mp) || agbno >= mp->m_sb.sb_agblocks ||
> > + agbno >= eoag || daddr >= eofs)
> > + xfs_scrub_block_set_corrupt(sc, sc->sa.agi_bp);
>
> xfs_verify_agbno(), again :P
>
> > +
> > + level = be32_to_cpu(agi->agi_level);
> > + if (level <= 0 || level > XFS_BTREE_MAXLEVELS)
> > + xfs_scrub_block_set_corrupt(sc, sc->sa.agi_bp);
> > +
> > + if (xfs_sb_version_hasfinobt(&mp->m_sb)) {
> > + agbno = be32_to_cpu(agi->agi_free_root);
> > + daddr = XFS_AGB_TO_DADDR(mp, agno, agbno);
> > + if (agbno <= XFS_AGI_BLOCK(mp) ||
> > + agbno >= mp->m_sb.sb_agblocks ||
> > + agbno >= eoag ||
> > + daddr >= eofs)
>
> Broken records are us....
>
> > + xfs_scrub_block_set_corrupt(sc, sc->sa.agi_bp);
> > +
> > + level = be32_to_cpu(agi->agi_free_level);
> > + if (level <= 0 || level > XFS_BTREE_MAXLEVELS)
> > + xfs_scrub_block_set_corrupt(sc, sc->sa.agi_bp);
> > + }
> > +
> > + /* Check inode counters */
> > + first_agino = XFS_OFFBNO_TO_AGINO(mp, XFS_AGI_BLOCK(mp) + 1, 0);
>
> Don't think this is right. AGFL, not AGI....
Yes.
> > + last_agino = XFS_OFFBNO_TO_AGINO(mp, eoag + 1, 0) - 1;
>
> Not sure this is right, either, because inode chunks won't be
> allocated over the end of the AG. hence if the eoag is not chunk
> aligned, there will be up to (chunk size - 1) blocks inodes won't be
> allocated in...
Yes.
> > + agino = be32_to_cpu(agi->agi_count);
> > + if (agino > last_agino - first_agino + 1 ||
> > + agino < be32_to_cpu(agi->agi_freecount))
> > + xfs_scrub_block_set_corrupt(sc, sc->sa.agi_bp);
>
> Please don't use agino as a count of inodes - this confused me
> very much because I was wondering how these checks were in any way
> realted to valid AG inode numbers....
<nod> Sorry about that, will fix.
> > +
> > + /* Check inode pointers */
> > + agino = be32_to_cpu(agi->agi_newino);
> > + if (agino != NULLAGINO && (agino < first_agino || agino > last_agino))
> > + xfs_scrub_block_set_corrupt(sc, sc->sa.agi_bp);
> > + agino = be32_to_cpu(agi->agi_dirino);
> > + if (agino != NULLAGINO && (agino < first_agino || agino > last_agino))
> > + xfs_scrub_block_set_corrupt(sc, sc->sa.agi_bp);
>
> Perhaps we also need a xfs_verify_agino() helper here.
>
> > + /* Check unlinked inode buckets */
> > + for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) {
> > + agino = be32_to_cpu(agi->agi_unlinked[i]);
> > + if (agino == NULLAGINO)
> > + continue;
> > + if (agino < first_agino || agino > last_agino)
> > + xfs_scrub_block_set_corrupt(sc, sc->sa.agi_bp);
>
> This is effectively the same check as above:
>
> if (agino != NULLAGINO && (agino < first_agino || agino > last_agino))
>
> so all these checks could use the same helper to make it easier
> to read.
<nod> Will do. Thank you for the review so far!
--D
>
> Cheers,
>
> Dave.
> --
> Dave Chinner
> david@fromorbit.com
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2017-10-04 4:25 UTC|newest]
Thread overview: 91+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-03 20:40 [PATCH v11 00/25] xfs: online scrub support Darrick J. Wong
2017-10-03 20:40 ` [PATCH 01/25] xfs: create an ioctl to scrub AG metadata Darrick J. Wong
2017-10-03 20:41 ` [PATCH 02/25] xfs: dispatch metadata scrub subcommands Darrick J. Wong
2017-10-03 20:41 ` [PATCH 03/25] xfs: probe the scrub ioctl Darrick J. Wong
2017-10-03 23:32 ` Dave Chinner
2017-10-04 0:02 ` Darrick J. Wong
2017-10-04 1:56 ` Dave Chinner
2017-10-04 3:14 ` Darrick J. Wong
2017-10-03 20:41 ` [PATCH 04/25] xfs: create helpers to record and deal with scrub problems Darrick J. Wong
2017-10-03 23:44 ` Dave Chinner
2017-10-04 0:56 ` Darrick J. Wong
2017-10-03 20:41 ` [PATCH 05/25] xfs: create helpers to scrub a metadata btree Darrick J. Wong
2017-10-03 23:49 ` Dave Chinner
2017-10-04 0:13 ` Darrick J. Wong
2017-10-03 20:41 ` [PATCH 06/25] xfs: scrub the shape of " Darrick J. Wong
2017-10-04 0:15 ` Dave Chinner
2017-10-04 3:51 ` Darrick J. Wong
2017-10-04 5:48 ` Dave Chinner
2017-10-04 17:48 ` Darrick J. Wong
2017-10-03 20:41 ` [PATCH 07/25] xfs: scrub btree keys and records Darrick J. Wong
2017-10-04 20:52 ` Darrick J. Wong
2017-10-03 20:41 ` [PATCH 08/25] xfs: create helpers to scan an allocation group Darrick J. Wong
2017-10-04 0:46 ` Dave Chinner
2017-10-04 3:58 ` Darrick J. Wong
2017-10-04 5:59 ` Dave Chinner
2017-10-04 17:51 ` Darrick J. Wong
2017-10-03 20:41 ` [PATCH 09/25] xfs: scrub the backup superblocks Darrick J. Wong
2017-10-04 0:57 ` Dave Chinner
2017-10-04 4:06 ` Darrick J. Wong
2017-10-04 6:13 ` Dave Chinner
2017-10-04 17:56 ` Darrick J. Wong
2017-10-03 20:41 ` [PATCH 10/25] xfs: scrub AGF and AGFL Darrick J. Wong
2017-10-04 1:31 ` Dave Chinner
2017-10-04 4:21 ` Darrick J. Wong
2017-10-04 6:28 ` Dave Chinner
2017-10-04 17:57 ` Darrick J. Wong
2017-10-03 20:41 ` [PATCH 11/25] xfs: scrub the AGI Darrick J. Wong
2017-10-04 1:43 ` Dave Chinner
2017-10-04 4:25 ` Darrick J. Wong [this message]
2017-10-04 6:43 ` Dave Chinner
2017-10-04 18:02 ` Darrick J. Wong
2017-10-04 22:16 ` Dave Chinner
2017-10-04 23:12 ` Darrick J. Wong
2017-10-03 20:42 ` [PATCH 12/25] xfs: scrub free space btrees Darrick J. Wong
2017-10-05 0:59 ` Dave Chinner
2017-10-05 1:13 ` Darrick J. Wong
2017-10-03 20:42 ` [PATCH 13/25] xfs: scrub inode btrees Darrick J. Wong
2017-10-05 2:08 ` Dave Chinner
2017-10-05 5:47 ` Darrick J. Wong
2017-10-05 7:22 ` Dave Chinner
2017-10-05 18:26 ` Darrick J. Wong
2017-10-03 20:42 ` [PATCH 14/25] xfs: scrub rmap btrees Darrick J. Wong
2017-10-05 2:56 ` Dave Chinner
2017-10-05 5:02 ` Darrick J. Wong
2017-10-03 20:42 ` [PATCH 15/25] xfs: scrub refcount btrees Darrick J. Wong
2017-10-05 2:59 ` Dave Chinner
2017-10-05 5:02 ` Darrick J. Wong
2017-10-03 20:42 ` [PATCH 16/25] xfs: scrub inodes Darrick J. Wong
2017-10-05 4:04 ` Dave Chinner
2017-10-05 5:22 ` Darrick J. Wong
2017-10-05 7:13 ` Dave Chinner
2017-10-05 19:56 ` Darrick J. Wong
2017-10-03 20:42 ` [PATCH 17/25] xfs: scrub inode block mappings Darrick J. Wong
2017-10-06 2:51 ` Dave Chinner
2017-10-06 17:00 ` Darrick J. Wong
2017-10-07 23:10 ` Dave Chinner
2017-10-08 3:54 ` Darrick J. Wong
2017-10-03 20:42 ` [PATCH 18/25] xfs: scrub directory/attribute btrees Darrick J. Wong
2017-10-06 5:07 ` Dave Chinner
2017-10-06 18:30 ` Darrick J. Wong
2017-10-03 20:42 ` [PATCH 19/25] xfs: scrub directory metadata Darrick J. Wong
2017-10-06 7:07 ` Dave Chinner
2017-10-06 19:45 ` Darrick J. Wong
2017-10-06 22:16 ` Dave Chinner
2017-10-03 20:42 ` [PATCH 20/25] xfs: scrub directory freespace Darrick J. Wong
2017-10-09 1:44 ` Dave Chinner
2017-10-09 22:54 ` Darrick J. Wong
2017-10-03 20:43 ` [PATCH 21/25] xfs: scrub extended attributes Darrick J. Wong
2017-10-09 2:13 ` Dave Chinner
2017-10-09 21:14 ` Darrick J. Wong
2017-10-03 20:43 ` [PATCH 22/25] xfs: scrub symbolic links Darrick J. Wong
2017-10-09 2:17 ` Dave Chinner
2017-10-03 20:43 ` [PATCH 23/25] xfs: scrub parent pointers Darrick J. Wong
2017-10-03 20:43 ` [PATCH 24/25] xfs: scrub realtime bitmap/summary Darrick J. Wong
2017-10-09 2:28 ` Dave Chinner
2017-10-09 20:24 ` Darrick J. Wong
2017-10-03 20:43 ` [PATCH 25/25] xfs: scrub quota information Darrick J. Wong
2017-10-09 2:51 ` Dave Chinner
2017-10-09 20:03 ` Darrick J. Wong
2017-10-09 22:17 ` Dave Chinner
2017-10-09 23:08 ` Darrick J. Wong
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=20171004042501.GO6503@magnolia \
--to=darrick.wong@oracle.com \
--cc=david@fromorbit.com \
--cc=linux-xfs@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).