summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2021-01-05 17:46:02 -0800
committerDarrick J. Wong <djwong@kernel.org>2021-03-25 17:08:46 -0700
commit02080c0dbabd98aceec5631d298de5125489149a (patch)
tree6ab49b6af852ebd03d9e6922ed99cf0f1452907f
parent01c8f48b9f12a33c932524bee2efd517a260cbb9 (diff)
xfs: scan rt rmap when we're doing an intense rmap check
Teach the bmbt scrubber how to perform a comprehensive check that the rmapbt does not contain /any/ mappings that are not described by bmbt records when it's dealing with a realtime file. Signed-off-by: Darrick J. Wong <djwong@kernel.org>
-rw-r--r--fs/xfs/scrub/bmap.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c
index e77d72a71bd3..448735d9213d 100644
--- a/fs/xfs/scrub/bmap.c
+++ b/fs/xfs/scrub/bmap.c
@@ -19,6 +19,8 @@
#include "xfs_bmap_btree.h"
#include "xfs_rmap.h"
#include "xfs_rmap_btree.h"
+#include "xfs_rtalloc.h"
+#include "xfs_rtrmap_btree.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/btree.h"
@@ -671,6 +673,29 @@ xchk_bmap_check_ag_rmaps(
return error;
}
+/* Make sure each rt rmap has a corresponding bmbt entry. */
+STATIC int
+xchk_bmap_check_rt_rmaps(
+ struct xfs_scrub *sc)
+{
+ struct xchk_bmap_check_rmap_info sbcri;
+ struct xfs_btree_cur *cur;
+ int error;
+
+ xfs_rtlock(NULL, sc->mp, XFS_RTLOCK_RMAP);
+ cur = xfs_rtrmapbt_init_cursor(sc->mp, sc->tp, sc->mp->m_rrmapip);
+
+ sbcri.sc = sc;
+ sbcri.whichfork = XFS_DATA_FORK;
+ error = xfs_rmap_query_all(cur, xchk_bmap_check_rmap, &sbcri);
+ if (error == -ECANCELED)
+ error = 0;
+
+ xfs_btree_del_cursor(cur, error);
+ xfs_rtunlock(sc->mp, XFS_RTLOCK_RMAP);
+ return error;
+}
+
/* Make sure each rmap has a corresponding bmbt entry. */
STATIC int
xchk_bmap_check_rmaps(
@@ -687,10 +712,6 @@ xchk_bmap_check_rmaps(
(sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
return 0;
- /* Don't support realtime rmap checks yet. */
- if (xfs_ifork_is_realtime(sc->ip, whichfork))
- return 0;
-
ASSERT(XFS_IFORK_PTR(sc->ip, whichfork) != NULL);
/*
@@ -710,6 +731,9 @@ xchk_bmap_check_rmaps(
(zero_size || ifp->if_nextents > 0))
return 0;
+ if (xfs_ifork_is_realtime(sc->ip, whichfork))
+ return xchk_bmap_check_rt_rmaps(sc);
+
for (agno = 0; agno < sc->mp->m_sb.sb_agcount; agno++) {
error = xchk_bmap_check_ag_rmaps(sc, whichfork, agno);
if (error)