From e04bcbac35aa8cda71dcbdd6fc8262ee5a2ceab4 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 17 Mar 2020 13:16:48 -0700 Subject: xfs: refactor realtime scrubbing context management Create a pair of helpers to deal with setting up the necessary incore context to check metadata records against the realtime metadata. This was already (sort of) open-coded in the data fork checker. Signed-off-by: Darrick J. Wong --- fs/xfs/scrub/bmap.c | 14 ++++++++++++++ fs/xfs/scrub/common.c | 26 ++++++++++++++++++++++++++ fs/xfs/scrub/common.h | 5 +++++ fs/xfs/scrub/rtbitmap.c | 5 +---- 4 files changed, 46 insertions(+), 4 deletions(-) (limited to 'fs') diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c index 8908a3cf31ba..bb57ab32f525 100644 --- a/fs/xfs/scrub/bmap.c +++ b/fs/xfs/scrub/bmap.c @@ -249,8 +249,22 @@ xchk_bmap_rt_iextent_xref( struct xchk_bmap_info *info, struct xfs_bmbt_irec *irec) { + struct xfs_mount *mp = info->sc->mp; + + xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP); + if (mp->m_rrmapip) + xfs_ilock(mp->m_rrmapip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM); + + xchk_rt_init(info->sc, &info->sc->sa); + xchk_xref_is_used_rt_space(info->sc, irec->br_startblock, irec->br_blockcount); + + xchk_rt_free(info->sc, &info->sc->sa); + + if (mp->m_rrmapip) + xfs_iunlock(mp->m_rrmapip, XFS_ILOCK_EXCL); + xfs_iunlock(mp->m_rbmip, XFS_ILOCK_EXCL); } /* Cross-reference a single datadev extent record. */ diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index 681dc98634e9..28eacf531c39 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -27,6 +27,7 @@ #include "xfs_trans_priv.h" #include "xfs_attr.h" #include "xfs_reflink.h" +#include "xfs_rtrmap_btree.h" #include "scrub/scrub.h" #include "scrub/common.h" #include "scrub/trace.h" @@ -585,6 +586,31 @@ xchk_perag_get( sa->pag = xfs_perag_get(mp, sa->agno); } +/* + * For scrubbing a realtime file, grab all the in-core resources we'll need to + * check the realtime metadata. The caller must hold the ILOCK of realtime + * metadata inodes. We follow the same resource release rules as + * xfs_scrub_ag_init. + */ +void +xchk_rt_init( + struct xfs_scrub *sc, + struct xchk_ag *sa) +{ + ASSERT(xfs_isilocked(sc->mp->m_rbmip, + XFS_ILOCK_EXCL | XFS_ILOCK_SHARED)); + + memset(sa, 0, sizeof(*sa)); + sa->agno = NULLAGNUMBER; + + if (xfs_sb_version_hasrmapbt(&sc->mp->m_sb)) { + ASSERT(xfs_isilocked(sc->mp->m_rrmapip, + XFS_ILOCK_EXCL | XFS_ILOCK_SHARED)); + sa->rmap_cur = xfs_rtrmapbt_init_cursor(sc->mp, sc->tp, + sc->mp->m_rrmapip); + } +} + /* Per-scrubber setup functions */ /* diff --git a/fs/xfs/scrub/common.h b/fs/xfs/scrub/common.h index f28f90bd95a1..712e68552606 100644 --- a/fs/xfs/scrub/common.h +++ b/fs/xfs/scrub/common.h @@ -124,6 +124,11 @@ int xchk_setup_fscounters(struct xfs_scrub *sc, struct xfs_inode *ip); void xchk_ag_free(struct xfs_scrub *sc, struct xchk_ag *sa); int xchk_ag_init(struct xfs_scrub *sc, xfs_agnumber_t agno, struct xchk_ag *sa); +void xchk_rt_init(struct xfs_scrub *sc, struct xchk_ag *sa); +static inline void xchk_rt_free(struct xfs_scrub *sc, struct xchk_ag *sa) +{ + return xchk_ag_free(sc, sa); +} void xchk_perag_get(struct xfs_mount *mp, struct xchk_ag *sa); int xchk_ag_read_headers(struct xfs_scrub *sc, xfs_agnumber_t agno, struct xfs_buf **agi, struct xfs_buf **agf, diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c index fb58c25f35ac..fc76702acf8f 100644 --- a/fs/xfs/scrub/rtbitmap.c +++ b/fs/xfs/scrub/rtbitmap.c @@ -146,13 +146,10 @@ xchk_xref_is_used_rt_space( do_div(startext, sc->mp->m_sb.sb_rextsize); do_div(endext, sc->mp->m_sb.sb_rextsize); extcount = endext - startext + 1; - xfs_ilock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); error = xfs_rtalloc_extent_is_free(sc->mp, sc->tp, startext, extcount, &is_free); if (!xchk_should_check_xref(sc, &error, NULL)) - goto out_unlock; + return; if (is_free) xchk_ino_xref_set_corrupt(sc, sc->mp->m_rbmip->i_ino); -out_unlock: - xfs_iunlock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); } -- cgit v1.2.3