Blame SOURCES/xfsprogs-5.7.0-xfs_repair-convert-to-libxfs_verify_agbno.patch

48cf7c
From dcd6c2e1490ba5c59c14ca8ea843ca36048888b8 Mon Sep 17 00:00:00 2001
48cf7c
From: "Darrick J. Wong" <darrick.wong@oracle.com>
48cf7c
Date: Fri, 10 Jul 2020 15:35:45 -0400
48cf7c
Subject: [PATCH] xfs_repair: convert to libxfs_verify_agbno
48cf7c
48cf7c
Convert the homegrown verify_agbno callers to use the libxfs function,
48cf7c
as needed.  In some places we drop the "bno != 0" checks because those
48cf7c
conditionals are checking btree roots; btree roots should never be
48cf7c
zero if the corresponding feature bit is set; and repair skips the if
48cf7c
clause entirely if the feature bit is disabled.
48cf7c
48cf7c
In effect, this strengthens repair to validate that AG btree pointers
48cf7c
neither point to the AG headers nor past the end of the AG.
48cf7c
48cf7c
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
48cf7c
Reviewed-by: Christoph Hellwig <hch@lst.de>
48cf7c
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
48cf7c
---
48cf7c
 libxfs/libxfs_api_defs.h |  1 +
48cf7c
 repair/dinode.c          | 11 -----------
48cf7c
 repair/dinode.h          |  5 -----
48cf7c
 repair/scan.c            | 36 +++++++++++++++++++++++-------------
48cf7c
 4 files changed, 24 insertions(+), 29 deletions(-)
48cf7c
48cf7c
Index: xfsprogs-5.0.0/libxfs/libxfs_api_defs.h
48cf7c
===================================================================
48cf7c
--- xfsprogs-5.0.0.orig/libxfs/libxfs_api_defs.h
48cf7c
+++ xfsprogs-5.0.0/libxfs/libxfs_api_defs.h
48cf7c
@@ -121,6 +121,7 @@
48cf7c
 #define xfs_verify_agbno		libxfs_verify_agbno
48cf7c
 #define xfs_verify_cksum		libxfs_verify_cksum
48cf7c
 #define xfs_dinode_verify		libxfs_dinode_verify
48cf7c
+#define xfs_ag_block_count		libxfs_ag_block_count
48cf7c
 
48cf7c
 #define xfs_alloc_ag_max_usable		libxfs_alloc_ag_max_usable
48cf7c
 #define xfs_allocbt_maxrecs		libxfs_allocbt_maxrecs
48cf7c
Index: xfsprogs-5.0.0/repair/dinode.c
48cf7c
===================================================================
48cf7c
--- xfsprogs-5.0.0.orig/repair/dinode.c
48cf7c
+++ xfsprogs-5.0.0/repair/dinode.c
48cf7c
@@ -284,17 +284,6 @@ verify_dfsbno_range(xfs_mount_t	*mp,
48cf7c
 	return (XR_DFSBNORANGE_VALID);
48cf7c
 }
48cf7c
 
48cf7c
-int
48cf7c
-verify_agbno(xfs_mount_t	*mp,
48cf7c
-		xfs_agnumber_t	agno,
48cf7c
-		xfs_agblock_t	agbno)
48cf7c
-{
48cf7c
-	xfs_sb_t	*sbp = &mp->m_sb;;
48cf7c
-
48cf7c
-	/* range check ag #, ag block.  range-checking offset is pointless */
48cf7c
-	return verify_ag_bno(sbp, agno, agbno) == 0;
48cf7c
-}
48cf7c
-
48cf7c
 static int
48cf7c
 process_rt_rec(
48cf7c
 	xfs_mount_t		*mp,
48cf7c
Index: xfsprogs-5.0.0/repair/dinode.h
48cf7c
===================================================================
48cf7c
--- xfsprogs-5.0.0.orig/repair/dinode.h
48cf7c
+++ xfsprogs-5.0.0/repair/dinode.h
48cf7c
@@ -10,11 +10,6 @@ struct blkmap;
48cf7c
 struct prefetch_args;
48cf7c
 
48cf7c
 int
48cf7c
-verify_agbno(xfs_mount_t	*mp,
48cf7c
-		xfs_agnumber_t	agno,
48cf7c
-		xfs_agblock_t	agbno);
48cf7c
-
48cf7c
-int
48cf7c
 verify_dfsbno(xfs_mount_t	*mp,
48cf7c
 		xfs_fsblock_t	fsbno);
48cf7c
 
48cf7c
Index: xfsprogs-5.0.0/repair/scan.c
48cf7c
===================================================================
48cf7c
--- xfsprogs-5.0.0.orig/repair/scan.c
48cf7c
+++ xfsprogs-5.0.0/repair/scan.c
48cf7c
@@ -642,14 +642,14 @@ _("%s freespace btree block claimed (sta
48cf7c
 			len = be32_to_cpu(rp[i].ar_blockcount);
48cf7c
 			end = b + len;
48cf7c
 
48cf7c
-			if (b == 0 || !verify_agbno(mp, agno, b)) {
48cf7c
+			if (!libxfs_verify_agbno(mp, agno, b)) {
48cf7c
 				do_warn(
48cf7c
 	_("invalid start block %u in record %u of %s btree block %u/%u\n"),
48cf7c
 					b, i, name, agno, bno);
48cf7c
 				continue;
48cf7c
 			}
48cf7c
 			if (len == 0 || end <= b ||
48cf7c
-			    !verify_agbno(mp, agno, end - 1)) {
48cf7c
+			    !libxfs_verify_agbno(mp, agno, end - 1)) {
48cf7c
 				do_warn(
48cf7c
 	_("invalid length %u in record %u of %s btree block %u/%u\n"),
48cf7c
 					len, i, name, agno, bno);
48cf7c
@@ -914,6 +914,16 @@ rmap_in_order(
48cf7c
 	return offset > lastoffset;
48cf7c
 }
48cf7c
 
48cf7c
+static inline bool
48cf7c
+verify_rmap_agbno(
48cf7c
+	struct xfs_mount	*mp,
48cf7c
+	xfs_agnumber_t		agno,
48cf7c
+	xfs_agblock_t		agbno)
48cf7c
+{
48cf7c
+	return agbno < libxfs_ag_block_count(mp, agno);
48cf7c
+}
48cf7c
+
48cf7c
+
48cf7c
 static void
48cf7c
 scan_rmapbt(
48cf7c
 	struct xfs_btree_block	*block,
48cf7c
@@ -1031,14 +1041,14 @@ _("%s rmap btree block claimed (state %d
48cf7c
 			end = key.rm_startblock + key.rm_blockcount;
48cf7c
 
48cf7c
 			/* Make sure agbno & len make sense. */
48cf7c
-			if (!verify_agbno(mp, agno, b)) {
48cf7c
+			if (!verify_rmap_agbno(mp, agno, b)) {
48cf7c
 				do_warn(
48cf7c
 	_("invalid start block %u in record %u of %s btree block %u/%u\n"),
48cf7c
 					b, i, name, agno, bno);
48cf7c
 				continue;
48cf7c
 			}
48cf7c
 			if (len == 0 || end <= b ||
48cf7c
-			    !verify_agbno(mp, agno, end - 1)) {
48cf7c
+			    !verify_rmap_agbno(mp, agno, end - 1)) {
48cf7c
 				do_warn(
48cf7c
 	_("invalid length %u in record %u of %s btree block %u/%u\n"),
48cf7c
 					len, i, name, agno, bno);
48cf7c
@@ -1325,14 +1335,14 @@ _("leftover CoW extent has invalid start
48cf7c
 			}
48cf7c
 			end = agb + len;
48cf7c
 
48cf7c
-			if (!verify_agbno(mp, agno, agb)) {
48cf7c
+			if (!libxfs_verify_agbno(mp, agno, agb)) {
48cf7c
 				do_warn(
48cf7c
 	_("invalid start block %u in record %u of %s btree block %u/%u\n"),
48cf7c
 					b, i, name, agno, bno);
48cf7c
 				continue;
48cf7c
 			}
48cf7c
 			if (len == 0 || end <= agb ||
48cf7c
-			    !verify_agbno(mp, agno, end - 1)) {
48cf7c
+			    !libxfs_verify_agbno(mp, agno, end - 1)) {
48cf7c
 				do_warn(
48cf7c
 	_("invalid length %u in record %u of %s btree block %u/%u\n"),
48cf7c
 					len, i, name, agno, bno);
48cf7c
@@ -2145,7 +2155,7 @@ scan_agfl(
48cf7c
 {
48cf7c
 	struct agfl_state	*as = priv;
48cf7c
 
48cf7c
-	if (verify_agbno(mp, as->agno, bno))
48cf7c
+	if (libxfs_verify_agbno(mp, as->agno, bno))
48cf7c
 		set_bmap(as->agno, bno, XR_E_FREE);
48cf7c
 	else
48cf7c
 		do_warn(_("bad agbno %u in agfl, agno %d\n"),
48cf7c
@@ -2217,7 +2227,7 @@ validate_agf(
48cf7c
 	uint32_t		magic;
48cf7c
 
48cf7c
 	bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]);
48cf7c
-	if (bno != 0 && verify_agbno(mp, agno, bno)) {
48cf7c
+	if (libxfs_verify_agbno(mp, agno, bno)) {
48cf7c
 		magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_ABTB_CRC_MAGIC
48cf7c
 							 : XFS_ABTB_MAGIC;
48cf7c
 		scan_sbtree(bno, be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]),
48cf7c
@@ -2229,7 +2239,7 @@ validate_agf(
48cf7c
 	}
48cf7c
 
48cf7c
 	bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]);
48cf7c
-	if (bno != 0 && verify_agbno(mp, agno, bno)) {
48cf7c
+	if (libxfs_verify_agbno(mp, agno, bno)) {
48cf7c
 		magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_ABTC_CRC_MAGIC
48cf7c
 							 : XFS_ABTC_MAGIC;
48cf7c
 		scan_sbtree(bno, be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]),
48cf7c
@@ -2249,7 +2259,7 @@ validate_agf(
48cf7c
 		priv.last_rec.rm_owner = XFS_RMAP_OWN_UNKNOWN;
48cf7c
 		priv.nr_blocks = 0;
48cf7c
 		bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_RMAP]);
48cf7c
-		if (bno != 0 && verify_agbno(mp, agno, bno)) {
48cf7c
+		if (libxfs_verify_agbno(mp, agno, bno)) {
48cf7c
 			scan_sbtree(bno,
48cf7c
 				    be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]),
48cf7c
 				    agno, 0, scan_rmapbt, 1, XFS_RMAP_CRC_MAGIC,
48cf7c
@@ -2267,7 +2277,7 @@ validate_agf(
48cf7c
 
48cf7c
 	if (xfs_sb_version_hasreflink(&mp->m_sb)) {
48cf7c
 		bno = be32_to_cpu(agf->agf_refcount_root);
48cf7c
-		if (bno != 0 && verify_agbno(mp, agno, bno)) {
48cf7c
+		if (libxfs_verify_agbno(mp, agno, bno)) {
48cf7c
 			struct refc_priv	priv;
48cf7c
 
48cf7c
 			memset(&priv, 0, sizeof(priv));
48cf7c
@@ -2315,7 +2325,7 @@ validate_agi(
48cf7c
 	uint32_t		magic;
48cf7c
 
48cf7c
 	bno = be32_to_cpu(agi->agi_root);
48cf7c
-	if (bno != 0 && verify_agbno(mp, agno, bno)) {
48cf7c
+	if (libxfs_verify_agbno(mp, agno, bno)) {
48cf7c
 		magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_IBT_CRC_MAGIC
48cf7c
 							 : XFS_IBT_MAGIC;
48cf7c
 		scan_sbtree(bno, be32_to_cpu(agi->agi_level),
48cf7c
@@ -2328,7 +2338,7 @@ validate_agi(
48cf7c
 
48cf7c
 	if (xfs_sb_version_hasfinobt(&mp->m_sb)) {
48cf7c
 		bno = be32_to_cpu(agi->agi_free_root);
48cf7c
-		if (bno != 0 && verify_agbno(mp, agno, bno)) {
48cf7c
+		if (libxfs_verify_agbno(mp, agno, bno)) {
48cf7c
 			magic = xfs_sb_version_hascrc(&mp->m_sb) ?
48cf7c
 					XFS_FIBT_CRC_MAGIC : XFS_FIBT_MAGIC;
48cf7c
 			scan_sbtree(bno, be32_to_cpu(agi->agi_free_level),