Commit 48039926 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Darrick J. Wong
Browse files

xfs: refactor the btree cursor allocation logic in xchk_ag_btcur_init



Change xchk_ag_btcur_init to allocate all cursors first and only then
check if we should delete them again because the btree is to damaged.

This allows reusing the sick_mask in struct xfs_btree_ops and simplifies
the code.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
parent 7f47734a
Loading
Loading
Loading
Loading
+33 −29
Original line number Diff line number Diff line
@@ -588,46 +588,50 @@ xchk_ag_btcur_init(
{
	struct xfs_mount	*mp = sc->mp;

	if (sa->agf_bp &&
	    xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_BNO)) {
	if (sa->agf_bp) {
		/* Set up a bnobt cursor for cross-referencing. */
		sa->bno_cur = xfs_allocbt_init_cursor(mp, sc->tp, sa->agf_bp,
				sa->pag, XFS_BTNUM_BNO);
	}
		xchk_ag_btree_del_cursor_if_sick(sc, &sa->bno_cur,
				XFS_SCRUB_TYPE_BNOBT);

	if (sa->agf_bp &&
	    xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_CNT)) {
		/* Set up a cntbt cursor for cross-referencing. */
		sa->cnt_cur = xfs_allocbt_init_cursor(mp, sc->tp, sa->agf_bp,
				sa->pag, XFS_BTNUM_CNT);
		xchk_ag_btree_del_cursor_if_sick(sc, &sa->cnt_cur,
				XFS_SCRUB_TYPE_CNTBT);

		/* Set up a rmapbt cursor for cross-referencing. */
		if (xfs_has_rmapbt(mp)) {
			sa->rmap_cur = xfs_rmapbt_init_cursor(mp, sc->tp,
					sa->agf_bp, sa->pag);
			xchk_ag_btree_del_cursor_if_sick(sc, &sa->rmap_cur,
					XFS_SCRUB_TYPE_RMAPBT);
		}

		/* Set up a refcountbt cursor for cross-referencing. */
		if (xfs_has_reflink(mp)) {
			sa->refc_cur = xfs_refcountbt_init_cursor(mp, sc->tp,
					sa->agf_bp, sa->pag);
			xchk_ag_btree_del_cursor_if_sick(sc, &sa->refc_cur,
					XFS_SCRUB_TYPE_REFCNTBT);
		}
	}

	if (sa->agi_bp) {
		/* Set up a inobt cursor for cross-referencing. */
	if (sa->agi_bp &&
	    xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_INO)) {
		sa->ino_cur = xfs_inobt_init_cursor(sa->pag, sc->tp, sa->agi_bp,
				XFS_BTNUM_INO);
	}
		xchk_ag_btree_del_cursor_if_sick(sc, &sa->ino_cur,
				XFS_SCRUB_TYPE_INOBT);

		/* Set up a finobt cursor for cross-referencing. */
	if (sa->agi_bp && xfs_has_finobt(mp) &&
	    xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_FINO)) {
		sa->fino_cur = xfs_inobt_init_cursor(sa->pag, sc->tp, sa->agi_bp,
				XFS_BTNUM_FINO);
	}

	/* Set up a rmapbt cursor for cross-referencing. */
	if (sa->agf_bp && xfs_has_rmapbt(mp) &&
	    xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_RMAP)) {
		sa->rmap_cur = xfs_rmapbt_init_cursor(mp, sc->tp, sa->agf_bp,
				sa->pag);
		if (xfs_has_finobt(mp)) {
			sa->fino_cur = xfs_inobt_init_cursor(sa->pag, sc->tp,
					sa->agi_bp, XFS_BTNUM_FINO);
			xchk_ag_btree_del_cursor_if_sick(sc, &sa->fino_cur,
					XFS_SCRUB_TYPE_FINOBT);
		}

	/* Set up a refcountbt cursor for cross-referencing. */
	if (sa->agf_bp && xfs_has_reflink(mp) &&
	    xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_REFC)) {
		sa->refc_cur = xfs_refcountbt_init_cursor(mp, sc->tp,
				sa->agf_bp, sa->pag);
	}
}

+10 −44
Original line number Diff line number Diff line
@@ -248,13 +248,13 @@ xchk_update_health(
}

/* Is the given per-AG btree healthy enough for scanning? */
bool
xchk_ag_btree_healthy_enough(
void
xchk_ag_btree_del_cursor_if_sick(
	struct xfs_scrub	*sc,
	struct xfs_perag	*pag,
	xfs_btnum_t		btnum)
	struct xfs_btree_cur	**curp,
	unsigned int		sm_type)
{
	unsigned int		mask = 0;
	unsigned int		mask = (*curp)->bc_ops->sick_mask;

	/*
	 * We always want the cursor if it's the same type as whatever we're
@@ -263,41 +263,8 @@ xchk_ag_btree_healthy_enough(
	 * Otherwise, we're only interested in the btree for cross-referencing.
	 * If we know the btree is bad then don't bother, just set XFAIL.
	 */
	switch (btnum) {
	case XFS_BTNUM_BNO:
		if (sc->sm->sm_type == XFS_SCRUB_TYPE_BNOBT)
			return true;
		mask = XFS_SICK_AG_BNOBT;
		break;
	case XFS_BTNUM_CNT:
		if (sc->sm->sm_type == XFS_SCRUB_TYPE_CNTBT)
			return true;
		mask = XFS_SICK_AG_CNTBT;
		break;
	case XFS_BTNUM_INO:
		if (sc->sm->sm_type == XFS_SCRUB_TYPE_INOBT)
			return true;
		mask = XFS_SICK_AG_INOBT;
		break;
	case XFS_BTNUM_FINO:
		if (sc->sm->sm_type == XFS_SCRUB_TYPE_FINOBT)
			return true;
		mask = XFS_SICK_AG_FINOBT;
		break;
	case XFS_BTNUM_RMAP:
		if (sc->sm->sm_type == XFS_SCRUB_TYPE_RMAPBT)
			return true;
		mask = XFS_SICK_AG_RMAPBT;
		break;
	case XFS_BTNUM_REFC:
		if (sc->sm->sm_type == XFS_SCRUB_TYPE_REFCNTBT)
			return true;
		mask = XFS_SICK_AG_REFCNTBT;
		break;
	default:
		ASSERT(0);
		return true;
	}
	if (sc->sm->sm_type == sm_type)
		return;

	/*
	 * If we just repaired some AG metadata, sc->sick_mask will reflect all
@@ -309,12 +276,11 @@ xchk_ag_btree_healthy_enough(
	    type_to_health_flag[sc->sm->sm_type].group == XHG_AG)
		mask &= ~sc->sick_mask;

	if (xfs_ag_has_sickness(pag, mask)) {
	if (xfs_ag_has_sickness((*curp)->bc_ag.pag, mask)) {
		sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XFAIL;
		return false;
		xfs_btree_del_cursor(*curp, XFS_BTREE_NOERROR);
		*curp = NULL;
	}

	return true;
}

/*
+2 −2
Original line number Diff line number Diff line
@@ -8,8 +8,8 @@

unsigned int xchk_health_mask_for_scrub_type(__u32 scrub_type);
void xchk_update_health(struct xfs_scrub *sc);
bool xchk_ag_btree_healthy_enough(struct xfs_scrub *sc, struct xfs_perag *pag,
		xfs_btnum_t btnum);
void xchk_ag_btree_del_cursor_if_sick(struct xfs_scrub *sc,
		struct xfs_btree_cur **curp, unsigned int sm_type);
void xchk_mark_healthy_if_clean(struct xfs_scrub *sc, unsigned int mask);
bool xchk_file_looks_zapped(struct xfs_scrub *sc, unsigned int mask);
int xchk_health_record(struct xfs_scrub *sc);