[PATCH 20/25] xfs: cross-reference extents with AG header

"Darrick J. Wong" <[email protected]>
Newsgroups gmane.comp.file-systems.xfs.general
Message-ID <[email protected]>
Ensure that none of the AG btree records overlap the AG sb/agf/agfl/agi
headers except for the XFS_RMAP_OWN_FS rmap.

Signed-off-by: Darrick J. Wong <[email protected]>
---
 fs/xfs/xfs_scrub.c |   54 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)


diff --git a/fs/xfs/xfs_scrub.c b/fs/xfs/xfs_scrub.c
index 66365e2..63a7434 100644
--- a/fs/xfs/xfs_scrub.c
+++ b/fs/xfs/xfs_scrub.c
@@ -434,6 +434,30 @@ xfs_scrub_put_ag_headers(
 	*agi_bpp = *agf_bpp = NULL;
 }
 
+/* Does this AG extent cover the AG headers? */
+STATIC bool
+xfs_scrub_extent_covers_ag_head(
+	struct xfs_mount	*mp,
+	xfs_agblock_t		agbno,
+	xfs_extlen_t		len)
+{
+	xfs_agblock_t		bno;
+
+	bno = XFS_SB_BLOCK(mp);
+	if (bno >= agbno && bno < agbno + len)
+		return true;
+	bno = XFS_AGF_BLOCK(mp);
+	if (bno >= agbno && bno < agbno + len)
+		return true;
+	bno = XFS_AGFL_BLOCK(mp);
+	if (bno >= agbno && bno < agbno + len)
+		return true;
+	bno = XFS_AGI_BLOCK(mp);
+	if (bno >= agbno && bno < agbno + len)
+		return true;
+	return false;
+}
+
 /*
  * For scrub, grab the AGI and the AGF headers, in that order.
  * Locking order requires us to get the AGI before the AGF.
@@ -1013,6 +1037,10 @@ xfs_scrub_agfl(
 		XFS_SCRUB_CHECK(mp, agfl_bp, "AGFL",
 				agbno < eoag);
 
+		/* Cross-reference with the AG headers. */
+		XFS_SCRUB_CHECK(mp, agfl_bp, "AGFL",
+				!xfs_scrub_extent_covers_ag_head(mp, agbno, 1));
+
 		/* Cross-reference with the bnobt. */
 		err2 = xfs_alloc_has_record(xcur, agbno, 1, &is_freesp);
 		if (!err2)
@@ -1117,6 +1145,10 @@ xfs_scrub_allocbt_helper(
 	XFS_BTREC_SCRUB_CHECK(bs, (unsigned long long)bno + len <=
 			be32_to_cpu(agf->agf_length));
 
+	/* Make sure we don't cover the AG headers. */
+	XFS_BTREC_SCRUB_CHECK(bs,
+			!xfs_scrub_extent_covers_ag_head(mp, bno, len));
+
 	/*
 	 * Ensure there's a corresponding cntbt/bnobt record matching
 	 * this bnobt/cntbt record, respectively.
@@ -1233,6 +1265,10 @@ xfs_scrub_iallocbt_helper(
 		XFS_BTREC_SCRUB_CHECK(bs, (unsigned long long)bno + len <=
 				eoag);
 
+		/* Make sure we don't cover the AG headers. */
+		XFS_BTREC_SCRUB_CHECK(bs,
+				!xfs_scrub_extent_covers_ag_head(mp, bno, len));
+
 		/* Cross-reference with the bnobt. */
 		err2 = xfs_alloc_has_record(bs->bno_cur, bno, len,
 				&is_freesp);
@@ -1267,6 +1303,10 @@ xfs_scrub_iallocbt_helper(
 		XFS_BTREC_SCRUB_CHECK(bs, (unsigned long long)bno + len <=
 				eoag);
 
+		/* Make sure we don't cover the AG headers. */
+		XFS_BTREC_SCRUB_CHECK(bs,
+				!xfs_scrub_extent_covers_ag_head(mp, bno, len));
+
 		/* Cross-reference with the bnobt. */
 		err2 = xfs_alloc_has_record(bs->bno_cur, bno, len,
 				&is_freesp);
@@ -1378,6 +1418,11 @@ xfs_scrub_rmapbt_helper(
 	XFS_BTREC_SCRUB_CHECK(bs, !non_inode || !(is_bmbt || is_unwritten ||
 			is_attr));
 
+	/* Make sure only the AG header owner maps to the AG header. */
+	XFS_BTREC_SCRUB_CHECK(bs, irec.rm_owner == XFS_RMAP_OWN_FS ||
+			!xfs_scrub_extent_covers_ag_head(mp, irec.rm_startblock,
+				irec.rm_blockcount));
+
 	/* check there's no record in freesp btrees */
 	err2 = xfs_alloc_has_record(bs->bno_cur, irec.rm_startblock,
 			irec.rm_blockcount, &is_freesp);
@@ -1452,6 +1497,10 @@ xfs_scrub_refcountbt_helper(
 			irec.rc_blockcount <= eoag);
 	XFS_BTREC_SCRUB_CHECK(bs, irec.rc_refcount >= 1);
 
+	/* Make sure we don't cover the AG headers. */
+	XFS_BTREC_SCRUB_CHECK(bs, !xfs_scrub_extent_covers_ag_head(mp,
+			irec.rc_startblock, irec.rc_blockcount));
+
 	/* Cross-reference with the bnobt. */
 	err2 = xfs_alloc_has_record(bs->bno_cur, irec.rc_startblock,
 			irec.rc_blockcount, &is_freesp);
@@ -1639,6 +1688,11 @@ xfs_scrub_bmap_extent(
 		if (error)
 			goto out;
 
+		/* Make sure we don't cover the AG headers. */
+		XFS_INO_SCRUB_CHECK(ip, bp, info->type, info->is_rt ||
+				!xfs_scrub_extent_covers_ag_head(mp, bno,
+					irec->br_blockcount));
+
 		/* Cross-reference with the bnobt. */
 		xcur = xfs_allocbt_init_cursor(mp, NULL, agf_bp, agno,
 				XFS_BTNUM_BNO);

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.