summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2020-03-17 13:16:48 -0700
committerDarrick J. Wong <darrick.wong@oracle.com>2020-06-01 21:16:46 -0700
commite04bcbac35aa8cda71dcbdd6fc8262ee5a2ceab4 (patch)
treeb096ecc504a02137820c00394a114e5b7d940551 /fs
parente093524bb4d70e37cbade163a2dcc66876b40d0b (diff)
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 <darrick.wong@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/scrub/bmap.c14
-rw-r--r--fs/xfs/scrub/common.c26
-rw-r--r--fs/xfs/scrub/common.h5
-rw-r--r--fs/xfs/scrub/rtbitmap.c5
4 files changed, 46 insertions, 4 deletions
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);
}