diff mbox

[20/20] xfs: cross-reference the realtime rmapbt

Message ID 147216873241.3688.11988964019948967528.stgit@birch.djwong.org
State Superseded
Headers show

Commit Message

Darrick J. Wong Aug. 25, 2016, 11:45 p.m. UTC
When we're scrubbing the realtime metadata, cross-reference
the rtrmapt.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_scrub.c |   33 +++++++++++++++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)
diff mbox

Patch

diff --git a/fs/xfs/xfs_scrub.c b/fs/xfs/xfs_scrub.c
index f0cd21f..61c99ea 100644
--- a/fs/xfs/xfs_scrub.c
+++ b/fs/xfs/xfs_scrub.c
@@ -2405,8 +2405,15 @@  xfs_scrub_bmap_extent(
 	}
 
 	/* Cross-reference with rmapbt. */
-	if (xfs_sb_version_hasrmapbt(&mp->m_sb) && !info->is_rt) {
-		xcur = xfs_rmapbt_init_cursor(mp, NULL, agf_bp, agno);
+	if (xfs_sb_version_hasrmapbt(&mp->m_sb)) {
+		if (!info->is_rt)
+			xcur = xfs_rmapbt_init_cursor(mp, NULL, agf_bp, agno);
+		else {
+			xfs_ilock(mp->m_rrmapip, XFS_ILOCK_SHARED |
+						 XFS_ILOCK_RTBITMAP);
+			xcur = xfs_rtrmapbt_init_cursor(mp, NULL,
+					mp->m_rrmapip);
+		}
 
 		if (info->whichfork == XFS_COW_FORK) {
 			owner = XFS_RMAP_OWN_COW;
@@ -2495,6 +2502,9 @@  skip_rmap_xref:
 		/* Free cursor. */
 		xfs_btree_del_cursor(xcur, err2 ? XFS_BTREE_ERROR :
 						  XFS_BTREE_NOERROR);
+		if (info->is_rt)
+			xfs_iunlock(mp->m_rrmapip, XFS_ILOCK_SHARED |
+						   XFS_ILOCK_RTBITMAP);
 	}
 
 	/*
@@ -2768,10 +2778,12 @@  xfs_scrub_rtbitmap(
 {
 	struct xfs_mount		*mp = ip->i_mount;
 	struct xfs_buf			*bp = NULL;
+	struct xfs_btree_cur		*cur = NULL;
 	xfs_rtblock_t			rtstart;
 	xfs_rtblock_t			rtend;
 	xfs_rtblock_t			block;
 	xfs_rtblock_t			rem;
+	bool				has_rmap;
 	int				is_free;
 	int				error = 0;
 	int				err2 = 0;
@@ -2780,6 +2792,10 @@  xfs_scrub_rtbitmap(
 		return -EINVAL;
 
 	xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
+	if (xfs_sb_version_hasrmapbt(&mp->m_sb)) {
+		xfs_ilock(mp->m_rrmapip, XFS_ILOCK_SHARED | XFS_ILOCK_RTSUM);
+		cur = xfs_rtrmapbt_init_cursor(mp, NULL, mp->m_rrmapip);
+	}
 
 	/* Iterate the bitmap, looking for discrepancies. */
 	rtstart = 0;
@@ -2807,6 +2823,14 @@  xfs_scrub_rtbitmap(
 			break;
 		XFS_SCRUB_CHECK(mp, bp, "rtbitmap", rtend >= rtstart);
 
+		/* Cross-reference the rtrmapbt. */
+		if (cur && is_free) {
+			err2 = xfs_rmap_has_record(cur, rtstart,
+					rtend - rtstart + 1, &has_rmap);
+			if (!err2)
+				XFS_SCRUB_CHECK(mp, bp, "rtbitmap", !has_rmap);
+		}
+
 		xfs_buf_relse(bp);
 		bp = NULL;
 		rem -= rtend - rtstart + 1;
@@ -2816,6 +2840,11 @@  xfs_scrub_rtbitmap(
 out_unlock:
 	if (bp)
 		xfs_buf_relse(bp);
+	if (cur) {
+		xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR :
+						  XFS_BTREE_NOERROR);
+		xfs_iunlock(mp->m_rrmapip, XFS_ILOCK_SHARED | XFS_ILOCK_RTSUM);
+	}
 	xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
 	if (!error && err2)
 		error = err2;