Commit e8882f69 authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: split the xchk_bmap_check_rmaps into a predicate



This function has two parts: the second part scans every reverse mapping
record for this file fork to make sure that there's a corresponding
mapping in the fork, and the first part decides if we even want to do
that.

Split the first part into a separate predicate so that we can make more
changes to it in the next patch.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
parent 336642f7
Loading
Loading
Loading
Loading
+38 −22
Original line number Diff line number Diff line
@@ -635,28 +635,28 @@ xchk_bmap_check_ag_rmaps(
	return error;
}

/* Make sure each rmap has a corresponding bmbt entry. */
STATIC int
xchk_bmap_check_rmaps(
	struct xfs_scrub	*sc,
	int			whichfork)
/*
 * Decide if we want to walk every rmap btree in the fs to make sure that each
 * rmap for this file fork has corresponding bmbt entries.
 */
static bool
xchk_bmap_want_check_rmaps(
	struct xchk_bmap_info	*info)
{
	struct xfs_ifork	*ifp = xfs_ifork_ptr(sc->ip, whichfork);
	struct xfs_perag	*pag;
	xfs_agnumber_t		agno;
	struct xfs_scrub	*sc = info->sc;
	struct xfs_ifork	*ifp;
	bool			zero_size;
	int			error;

	if (!xfs_has_rmapbt(sc->mp) ||
	    whichfork == XFS_COW_FORK ||
	    (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
		return 0;
	if (!xfs_has_rmapbt(sc->mp))
		return false;
	if (info->whichfork == XFS_COW_FORK)
		return false;
	if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
		return false;

	/* Don't support realtime rmap checks yet. */
	if (XFS_IS_REALTIME_INODE(sc->ip) && whichfork == XFS_DATA_FORK)
		return 0;

	ASSERT(xfs_ifork_ptr(sc->ip, whichfork) != NULL);
	if (info->is_rt)
		return false;

	/*
	 * Only do this for complex maps that are in btree format, or for
@@ -666,14 +666,28 @@ xchk_bmap_check_rmaps(
	 * reattached.
	 */

	if (whichfork == XFS_DATA_FORK)
	if (info->whichfork == XFS_DATA_FORK)
		zero_size = i_size_read(VFS_I(sc->ip)) == 0;
	else
		zero_size = false;

	ifp = xfs_ifork_ptr(sc->ip, info->whichfork);
	if (ifp->if_format != XFS_DINODE_FMT_BTREE &&
	    (zero_size || ifp->if_nextents > 0))
		return 0;
		return false;

	return true;
}

/* Make sure each rmap has a corresponding bmbt entry. */
STATIC int
xchk_bmap_check_rmaps(
	struct xfs_scrub	*sc,
	int			whichfork)
{
	struct xfs_perag	*pag;
	xfs_agnumber_t		agno;
	int			error;

	for_each_perag(sc->mp, agno, pag) {
		error = xchk_bmap_check_ag_rmaps(sc, whichfork, pag);
@@ -915,9 +929,11 @@ xchk_bmap(
		memcpy(&info.prev_rec, &irec, sizeof(struct xfs_bmbt_irec));
	}

	if (xchk_bmap_want_check_rmaps(&info)) {
		error = xchk_bmap_check_rmaps(sc, whichfork);
		if (!xchk_fblock_xref_process_error(sc, whichfork, 0, &error))
			goto out;
	}
out:
	return error;
}