[PATCH 08/16] xfs: cross-reference bnobt records with cntbt

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Darrick J. Wong <darrick.wong@xxxxxxxxxx>

Scrub should make sure that each bnobt record has a corresponding
cntbt record.

Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
---
 fs/xfs/scrub/agheader.c |   21 +++++++++++++++++++++
 fs/xfs/scrub/alloc.c    |   31 +++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)


diff --git a/fs/xfs/scrub/agheader.c b/fs/xfs/scrub/agheader.c
index 17d4b4e..7e7ad5f 100644
--- a/fs/xfs/scrub/agheader.c
+++ b/fs/xfs/scrub/agheader.c
@@ -442,6 +442,7 @@ xfs_scrub_agf(
 	xfs_agblock_t			fl_count;
 	xfs_extlen_t			blocks;
 	bool				is_freesp;
+	int				have;
 	int				level;
 	int				error = 0;
 
@@ -544,6 +545,26 @@ xfs_scrub_agf(
 		break;
 	}
 
+	/* Cross-reference with the cntbt. */
+	while (psa->cnt_cur) {
+		error = xfs_alloc_lookup_le(psa->cnt_cur, 0, -1U, &have);
+		if (!xfs_scrub_should_xref(sc, &error, &psa->cnt_cur))
+			break;
+		if (!have) {
+			xfs_scrub_block_xref_check_ok(sc, sc->sa.agf_bp,
+					agf->agf_freeblks == be32_to_cpu(0));
+			break;
+		}
+
+		error = xfs_alloc_get_rec(psa->cnt_cur, &agbno, &blocks, &have);
+		if (!xfs_scrub_should_xref(sc, &error, &psa->cnt_cur))
+			break;
+		xfs_scrub_block_xref_check_ok(sc, sc->sa.agf_bp,
+				!have ||
+				blocks == be32_to_cpu(agf->agf_longest));
+		break;
+	}
+
 out:
 	return error;
 }
diff --git a/fs/xfs/scrub/alloc.c b/fs/xfs/scrub/alloc.c
index f0e2386..eec27ce 100644
--- a/fs/xfs/scrub/alloc.c
+++ b/fs/xfs/scrub/alloc.c
@@ -30,6 +30,7 @@
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_rmap.h"
+#include "xfs_alloc.h"
 #include "scrub/xfs_scrub.h"
 #include "scrub/scrub.h"
 #include "scrub/common.h"
@@ -58,9 +59,14 @@ xfs_scrub_allocbt_helper(
 {
 	struct xfs_mount		*mp = bs->cur->bc_mp;
 	struct xfs_agf			*agf;
+	struct xfs_btree_cur		**xcur;
+	struct xfs_scrub_ag		*psa;
 	unsigned long long		rec_end;
+	xfs_agblock_t			fbno;
 	xfs_agblock_t			bno;
+	xfs_extlen_t			flen;
 	xfs_extlen_t			len;
+	int				has_otherrec;
 	int				error = 0;
 
 	bno = be32_to_cpu(rec->alloc.ar_startblock);
@@ -75,6 +81,31 @@ xfs_scrub_allocbt_helper(
 			rec_end <= mp->m_sb.sb_agblocks &&
 			rec_end <= be32_to_cpu(agf->agf_length));
 
+	psa = &bs->sc->sa;
+	/*
+	 * Ensure there's a corresponding cntbt/bnobt record matching
+	 * this bnobt/cntbt record, respectively.
+	 */
+	xcur = bs->cur == psa->bno_cur ? &psa->cnt_cur : &psa->bno_cur;
+	while (*xcur) {
+		error = xfs_alloc_lookup_le(*xcur, bno, len, &has_otherrec);
+		if (!xfs_scrub_should_xref(bs->sc, &error, xcur) ||
+		    !xfs_scrub_btree_xref_check_ok(bs->sc, *xcur, 0,
+				has_otherrec))
+			break;
+
+		error = xfs_alloc_get_rec(*xcur, &fbno, &flen,
+				&has_otherrec);
+		if (!xfs_scrub_should_xref(bs->sc, &error, xcur) ||
+		    !xfs_scrub_btree_xref_check_ok(bs->sc, *xcur, 0,
+				has_otherrec))
+			break;
+
+		xfs_scrub_btree_xref_check_ok(bs->sc, *xcur, 0,
+				fbno == bno && flen == len);
+		break;
+	}
+
 	return error;
 }
 

--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux