Re: [PATCH v2 16/21] xfs: cross-reference inode btrees during scrub

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jan 09, 2018 at 01:22:18PM -0800, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
> 
> Cross-reference the inode btrees with the other metadata when we
> scrub the filesystem.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
> ---
> v2: streamline scrubber arguments, remove stack allocated objects
> ---
>  fs/xfs/scrub/agheader.c |   19 +++++++++++++
>  fs/xfs/scrub/alloc.c    |    1 +
>  fs/xfs/scrub/bmap.c     |    1 +
>  fs/xfs/scrub/ialloc.c   |   70 +++++++++++++++++++++++++++++++++++++++++++++++
>  fs/xfs/scrub/inode.c    |   49 +++++++++++++++++++++++++++++++++
>  fs/xfs/scrub/refcount.c |    1 +
>  fs/xfs/scrub/rmap.c     |    4 +++
>  fs/xfs/scrub/scrub.h    |    4 +++
>  8 files changed, 149 insertions(+)
> 
> diff --git a/fs/xfs/scrub/agheader.c b/fs/xfs/scrub/agheader.c
> index 3b66cd4..4d4ce1f 100644
> --- a/fs/xfs/scrub/agheader.c
> +++ b/fs/xfs/scrub/agheader.c
> @@ -122,6 +122,7 @@ xfs_scrub_superblock_xref(
>  		return;
>  
>  	xfs_scrub_xref_is_used_space(sc, agbno, 1);
> +	xfs_scrub_xref_not_inodes(sc, agbno, 1);

Seems a bit strange to have "is" in "_is_used_space" and then don't
put it in "_is_not_inodes"....

> @@ -752,6 +760,17 @@ xfs_scrub_agi_xref(
>  		return;
>  
>  	xfs_scrub_xref_is_used_space(sc, agbno, 1);
> +	xfs_scrub_xref_not_inodes(sc, agbno, 1);

Hmmm, what this actually means is "_is_not_inode_chunk", right?
Kinda obscure to have the inode index checking it's "not inodes" :P

> +	if (sc->sa.ino_cur) {
> +		error = xfs_ialloc_count_inodes(sc->sa.ino_cur, &icount,
> +				&freecount);
> +		if (xfs_scrub_should_check_xref(sc, &error, &sc->sa.ino_cur) &&
> +		    (be32_to_cpu(agi->agi_count) != icount ||
> +		     be32_to_cpu(agi->agi_freecount) != freecount))
> +			xfs_scrub_block_xref_set_corrupt(sc, sc->sa.agi_bp);
> +	}

Reduce the indent by doing:

if (!sc->sa.ino_cur)
	return;

?

> diff --git a/fs/xfs/scrub/ialloc.c b/fs/xfs/scrub/ialloc.c
> index 4526894..34c133e 100644
> --- a/fs/xfs/scrub/ialloc.c
> +++ b/fs/xfs/scrub/ialloc.c
> @@ -67,10 +67,32 @@ xfs_scrub_iallocbt_chunk_xref(
>  	xfs_agblock_t			agbno,
>  	xfs_extlen_t			len)
>  {
> +	struct xfs_btree_cur		**pcur;
> +	bool				has_irec;
> +	int				error;
> +
>  	if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
>  		return;
>  
>  	xfs_scrub_xref_is_used_space(sc, agbno, len);
> +
> +	/*
> +	 * If we're checking the finobt, cross-reference with the inobt.
> +	 * Otherwise we're checking the inobt; if there is an finobt,
> +	 * make sure we have a record or not depending on freecount.
> +	 */
> +	if (sc->sm->sm_type == XFS_SCRUB_TYPE_FINOBT)
> +		pcur = &sc->sa.ino_cur;
> +	else
> +		pcur = &sc->sa.fino_cur;
> +	if (*pcur) {
> +		error = xfs_ialloc_has_inode_record(*pcur,
> +				agino, agino, &has_irec);
> +		if (xfs_scrub_should_check_xref(sc, &error, pcur) &&
> +		    ((irec->ir_freecount > 0 && !has_irec) ||
> +		     (irec->ir_freecount == 0 && has_irec)))
> +			xfs_scrub_btree_xref_set_corrupt(sc, *pcur, 0);
> +	}

Same here?

>  }
>  
>  /* Is this chunk worth checking? */
> @@ -352,3 +374,51 @@ xfs_scrub_finobt(
>  {
>  	return xfs_scrub_iallocbt(sc, XFS_BTNUM_FINO);
>  }
> +
> +/* xref check that the extent is not covered by inodes */
> +void
> +xfs_scrub_xref_not_inodes(
> +	struct xfs_scrub_context	*sc,
> +	xfs_agblock_t			bno,
> +	xfs_extlen_t			len)
> +{
> +	bool				has_inodes;
> +	int				error;
> +
> +	if (sc->sa.ino_cur) {
> +		error = xfs_ialloc_has_inodes_at_extent(sc->sa.ino_cur, bno,
> +				len, &has_inodes);
> +		if (xfs_scrub_should_check_xref(sc, &error, &sc->sa.ino_cur) &&
> +		    has_inodes)
> +			xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.ino_cur, 0);
> +	}
> +
> +	if (sc->sa.fino_cur) {
> +		error = xfs_ialloc_has_inodes_at_extent(sc->sa.fino_cur, bno,
> +				len, &has_inodes);
> +		if (xfs_scrub_should_check_xref(sc, &error, &sc->sa.fino_cur) &&
> +		    has_inodes)
> +			xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.fino_cur,
> +					0);
> +	}
> +}
> +
> +/* xref check that the extent is covered by inodes */
> +void
> +xfs_scrub_xref_are_inodes(
> +	struct xfs_scrub_context	*sc,
> +	xfs_agblock_t			bno,
> +	xfs_extlen_t			len)
> +{
> +	bool				has_inodes;
> +	int				error;
> +
> +	if (!sc->sa.ino_cur)
> +		return;
> +
> +	error = xfs_ialloc_has_inodes_at_extent(sc->sa.ino_cur, bno,
> +			len, &has_inodes);
> +	if (xfs_scrub_should_check_xref(sc, &error, &sc->sa.ino_cur) &&
> +	    !has_inodes)
> +		xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.ino_cur, 0);
> +}

That's 3 copies of that check and error handling.

xfs_scrub_xref_inode_check(
	struct xfs_scrub_context	*sc,
	xfs_agblock_t			bno,
	xfs_extlen_t			len,
	struct xfs_btree_cursor		**icur))
{
	error = xfs_ialloc_has_inodes_at_extent(*icur, bno, len, &has_inodes);
	if (xfs_scrub_should_check_xref(sc, &error, icur) &&
	    !has_inodes)
		xfs_scrub_btree_xref_set_corrupt(sc, *icur, 0);
}

And the callers become:

	if (sc->sa.ino_cur)
		xfs_scrub_xref_inode_check(sc, bno, len, &sc->sa.ino_cur);

I find that much easier to read...

Cheers,

Dave.
-- 
Dave Chinner
david@xxxxxxxxxxxxx
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux