From: Dave Chinner <david@fromorbit.com>
To: "Darrick J. Wong" <darrick.wong@oracle.com>
Cc: linux-xfs@vger.kernel.org
Subject: Re: [PATCH 6/8] xfs: clean up the inode cluster checking in the inobt scrub
Date: Wed, 7 Nov 2018 09:11:35 +1100 [thread overview]
Message-ID: <20181106221135.GT19305@dastard> (raw)
In-Reply-To: <154147732686.32496.17362148568991301258.stgit@magnolia>
On Mon, Nov 05, 2018 at 08:08:46PM -0800, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
>
> The code to check inobt records against inode clusters is a mess of
> poorly named variables and unnecessary parameters. Clean the
> unnecessary inode number parameters out of _check_cluster_freemask in
> favor of computing them inside the function instead of making the caller
> do it. In xchk_iallocbt_check_cluster, rename the variables to make it
> more obvious just what chunk_ino and cluster_ino represent.
Comment about new trace point? (used to debug change?)
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
> fs/xfs/scrub/ialloc.c | 130 ++++++++++++++++++++++++++++++-------------------
> fs/xfs/scrub/trace.h | 45 +++++++++++++++++
> 2 files changed, 125 insertions(+), 50 deletions(-)
>
>
> diff --git a/fs/xfs/scrub/ialloc.c b/fs/xfs/scrub/ialloc.c
> index 12158ed8ad29..645b248faa80 100644
> --- a/fs/xfs/scrub/ialloc.c
> +++ b/fs/xfs/scrub/ialloc.c
> @@ -147,41 +147,63 @@ xchk_iallocbt_freecount(
> return hweight64(freemask);
> }
>
> -/* Check a particular inode with ir_free. */
> +/*
> + * Given the number of an inode within an inode cluster, check that the inode's
> + * allocation status matches ir_free in the inobt record.
> + *
> + * @chunk_ioff is the inode offset of the cluster within the @irec.
> + * @irec is the inobt record.
> + * @bp is the cluster buffer.
> + * @loop_ioff is the inode offset within the inode cluster.
> + */
> STATIC int
> -xchk_iallocbt_check_cluster_freemask(
> +xchk_iallocbt_check_cluster_ifree(
> struct xchk_btree *bs,
> - xfs_ino_t fsino,
> - xfs_agino_t chunkino,
> - xfs_agino_t clusterino,
> struct xfs_inobt_rec_incore *irec,
> - struct xfs_buf *bp)
> + unsigned int chunk_ioff,
> + struct xfs_buf *bp,
> + unsigned int loop_ioff)
"loop_ioff" really isn't very descriptive. I've got no idea what it
means in the context of this function. More below.
> {
> - struct xfs_dinode *dip;
> struct xfs_mount *mp = bs->cur->bc_mp;
> - bool inode_is_free = false;
> + struct xfs_dinode *dip;
> + xfs_ino_t fsino;
> + xfs_agino_t agino;
> + unsigned int offset;
> + bool irec_free;
> + bool ino_inuse;
> bool freemask_ok;
> - bool inuse;
> - int error = 0;
> + int error;
>
> if (xchk_should_terminate(bs->sc, &error))
> return error;
>
> - dip = xfs_buf_offset(bp, clusterino * mp->m_sb.sb_inodesize);
> + /*
> + * Given an inobt record, an offset of a cluster within the record,
> + * and an offset of an inode within a cluster, compute which fs inode
> + * we're talking about and the offset of the inode record within the
> + * inode buffer.
> + */
> + agino = irec->ir_startino + chunk_ioff + loop_ioff;
> + fsino = XFS_AGINO_TO_INO(mp, bs->cur->bc_private.a.agno, agino);
> + offset = loop_ioff * mp->m_sb.sb_inodesize;
> + if (offset >= BBTOB(bp->b_length)) {
> + xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
> + goto out;
> + }
New check...
> + dip = xfs_buf_offset(bp, offset);
> + irec_free = (irec->ir_free & XFS_INOBT_MASK(chunk_ioff + loop_ioff));
And after 15 minutes of trying to work out if this is safe, I can
say that the new code isn't much clearer than the old code.
chunk_ioff is actually the first inode in the current cluster,
and loop_ioff is the current of the inode in the cluster.
They are indexes, not offsets. i.e. chunk_ioff is cluster_base,
and loop_ioff is cluster_index. (or something similar).
> +
> if (be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC ||
> - (dip->di_version >= 3 &&
> - be64_to_cpu(dip->di_ino) != fsino + clusterino)) {
> + (dip->di_version >= 3 && be64_to_cpu(dip->di_ino) != fsino)) {
> xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
> goto out;
> }
>
> - if (irec->ir_free & XFS_INOBT_MASK(chunkino + clusterino))
> - inode_is_free = true;
> - error = xfs_icache_inode_is_allocated(mp, bs->cur->bc_tp,
> - fsino + clusterino, &inuse);
> + error = xfs_icache_inode_is_allocated(mp, bs->cur->bc_tp, fsino,
> + &ino_inuse);
> if (error == -ENODATA) {
> /* Not cached, just read the disk buffer */
> - freemask_ok = inode_is_free ^ !!(dip->di_mode);
> + freemask_ok = irec_free ^ !!(dip->di_mode);
> if (!bs->sc->try_harder && !freemask_ok)
> return -EDEADLOCK;
> } else if (error < 0) {
> @@ -193,7 +215,7 @@ xchk_iallocbt_check_cluster_freemask(
> goto out;
> } else {
> /* Inode is all there. */
> - freemask_ok = inode_is_free ^ inuse;
> + freemask_ok = irec_free ^ ino_inuse;
> }
> if (!freemask_ok)
> xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
> @@ -201,44 +223,57 @@ xchk_iallocbt_check_cluster_freemask(
> return 0;
> }
>
> -/* Check an inode cluster. */
> +/*
> + * Check that the holemask and freemask of a hypothetical inode cluster match
> + * what's actually on disk. If sparse inodes are enabled, the cluster does
> + * not actually have to map to inodes if the corresponding holemask bit is set.
> + *
> + * @chunk_ioff is the inode offset of the cluster within the @irec.
> + */
> STATIC int
> xchk_iallocbt_check_cluster(
> struct xchk_btree *bs,
> struct xchk_iallocbt *iabt,
> struct xfs_inobt_rec_incore *irec,
> - xfs_agino_t agino)
> + unsigned int chunk_ioff)
cluster_base
> {
> struct xfs_imap imap;
> struct xfs_mount *mp = bs->cur->bc_mp;
> struct xfs_dinode *dip;
> struct xfs_buf *bp;
> - xfs_ino_t fsino;
> unsigned int nr_inodes;
> - xfs_agino_t chunkino;
> - xfs_agino_t clusterino;
> + xfs_agnumber_t agno = bs->cur->bc_private.a.agno;
> xfs_agblock_t agbno;
> - uint16_t holemask;
> + unsigned int loop_ioff;
cluster_index
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
next prev parent reply other threads:[~2018-11-07 7:39 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-06 4:08 [PATCH 0/8] xfs-5.0: inode btree scrub fixes Darrick J. Wong
2018-11-06 4:08 ` [PATCH 1/8] xfs: count inode blocks correctly in inobt scrub Darrick J. Wong
2018-11-06 21:20 ` Dave Chinner
2018-11-06 4:08 ` [PATCH 2/8] xfs: calculate inode cluster geometry once during " Darrick J. Wong
2018-11-06 21:32 ` Dave Chinner
2018-11-07 3:40 ` Darrick J. Wong
2018-11-06 4:08 ` [PATCH 3/8] xfs: check the ir_startino alignment directly Darrick J. Wong
2018-11-06 21:34 ` Dave Chinner
2018-11-07 3:50 ` Darrick J. Wong
2018-11-06 4:08 ` [PATCH 4/8] xfs: check inobt record alignment on big block filesystems Darrick J. Wong
2018-11-06 21:36 ` Dave Chinner
2018-11-06 4:08 ` [PATCH 5/8] xfs: hoist inode cluster checks out of loop Darrick J. Wong
2018-11-06 21:39 ` Dave Chinner
2018-11-06 4:08 ` [PATCH 6/8] xfs: clean up the inode cluster checking in the inobt scrub Darrick J. Wong
2018-11-06 22:11 ` Dave Chinner [this message]
2018-11-06 4:08 ` [PATCH 7/8] xfs: rename xchk_iallocbt_check_freemask Darrick J. Wong
2018-11-06 22:13 ` Dave Chinner
2018-11-06 4:08 ` [PATCH 8/8] xfs: scrub big block inode btrees correctly Darrick J. Wong
2018-11-06 22:26 ` Dave Chinner
2018-11-09 15:07 ` [PATCH 0/8] xfs-5.0: inode btree scrub fixes Christoph Hellwig
2018-11-09 16:39 ` 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=20181106221135.GT19305@dastard \
--to=david@fromorbit.com \
--cc=darrick.wong@oracle.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