summaryrefslogtreecommitdiff
path: root/fs/xfs/scrub/rtbitmap.c
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2022-08-18 15:40:05 -0700
committerDarrick J. Wong <djwong@kernel.org>2022-11-09 19:07:59 -0800
commitfb7c029fd084205c511cd2b1cf2d44f525f727c9 (patch)
treeebfa698b7cd0cd46c8dbaccfc62305c5f107b411 /fs/xfs/scrub/rtbitmap.c
parenta77db85b442f185dc3dcb5290c905266b449ee3c (diff)
xfs: scrub each rtgroup's portion of the rtbitmap separately
Create a new scrub type code so that userspace can scrub each rtgroup's portion of the rtbitmap file separately. This reduces the long tail latency that results from scanning the entire bitmap all at once, and prepares us for future patchsets, wherein we'll need to be able to lock a specific rtgroup so that we can rebuild that rtgroup's part of the rtbitmap contents from the rtgroup's rmap btree. Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs/scrub/rtbitmap.c')
-rw-r--r--fs/xfs/scrub/rtbitmap.c69
1 files changed, 66 insertions, 3 deletions
diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c
index 57dab8ad3bfb..1d3f8d5f3f37 100644
--- a/fs/xfs/scrub/rtbitmap.c
+++ b/fs/xfs/scrub/rtbitmap.c
@@ -14,10 +14,30 @@
#include "xfs_rtbitmap.h"
#include "xfs_inode.h"
#include "xfs_bmap.h"
+#include "xfs_rtgroup.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/repair.h"
+/* Set us up with the realtime group metadata locked. */
+int
+xchk_setup_rgbitmap(
+ struct xfs_scrub *sc)
+{
+ int error;
+
+ error = xchk_trans_alloc(sc, 0);
+ if (error)
+ return error;
+
+ error = xchk_install_live_inode(sc, sc->mp->m_rbmip);
+ if (error)
+ return error;
+
+ return xchk_rtgroup_init(sc, sc->sm->sm_agno, &sc->sr,
+ XCHK_RTGLOCK_ALL);
+}
+
/* Set us up with the realtime metadata locked. */
int
xchk_setup_rtbitmap(
@@ -101,6 +121,43 @@ xchk_rtbitmap_check_extents(
return error;
}
+/* Scrub this group's realtime bitmap. */
+int
+xchk_rgbitmap(
+ struct xfs_scrub *sc)
+{
+ struct xfs_rtalloc_rec keys[2];
+ struct xfs_rtgroup *rtg = sc->sr.rtg;
+ xfs_rtblock_t rtbno;
+ xfs_rgblock_t last_rgbno = rtg->rtg_blockcount - 1;
+ int error;
+
+ /* Sanity check the realtime bitmap size. */
+ if (sc->mp->m_rbmip->i_disk_size !=
+ XFS_FSB_TO_B(sc->mp, sc->mp->m_sb.sb_rbmblocks)) {
+ xchk_ino_set_corrupt(sc, sc->mp->m_rbmip->i_ino);
+ return 0;
+ }
+
+ /*
+ * Check only the portion of the rtbitmap that corresponds to this
+ * realtime group.
+ */
+ rtbno = xfs_rgbno_to_rtb(sc->mp, rtg->rtg_rgno, 0);
+ keys[0].ar_startext = xfs_rtb_to_rtxt(sc->mp, rtbno);
+
+ rtbno = xfs_rgbno_to_rtb(sc->mp, rtg->rtg_rgno, last_rgbno);
+ keys[1].ar_startext = xfs_rtb_to_rtxt(sc->mp, rtbno);
+ keys[0].ar_extcount = keys[1].ar_extcount = 0;
+
+ error = xfs_rtalloc_query_range(sc->mp, sc->tp, &keys[0], &keys[1],
+ xchk_rtbitmap_rec, sc);
+ if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
+ return error;
+
+ return 0;
+}
+
/* Scrub the realtime bitmap. */
int
xchk_rtbitmap(
@@ -124,12 +181,18 @@ xchk_rtbitmap(
if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
return error;
+ /*
+ * Each rtgroup checks its portion of the rt bitmap, so if we don't
+ * have that feature, we have to check the bitmap contents now.
+ */
+ if (xfs_has_rtgroups(sc->mp))
+ return 0;
+
error = xfs_rtalloc_query_all(sc->mp, sc->tp, xchk_rtbitmap_rec, sc);
if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
- goto out;
+ return error;
-out:
- return error;
+ return 0;
}
/* xref check that the extent is not free in the rtbitmap */