aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2023-05-31 10:59:21 +0200
committerCarlos Maiolino <cem@kernel.org>2023-06-09 10:27:50 +0200
commite70bf9ba99546b22a362e58d968e838feb886a6a (patch)
treeeb82f0f789a9a79830450e58765f842778054527
parentfd1d74cd69383ec7baaee7ad2e5dbe47f0061bbf (diff)
downloadxfsprogs-dev-e70bf9ba99546b22a362e58d968e838feb886a6a.tar.gz
xfs: complain about bad records in query_range helpers
Source kernel commit: ee12eaaa435a7be17152ac50943ee77249de624a For every btree type except for the bmbt, refactor the code that complains about bad records into a helper and make the ->query_range helpers call it so that corruptions found via that avenue are logged. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Carlos Maiolino <cem@kernel.org>
-rw-r--r--libxfs/xfs_alloc.c38
-rw-r--r--libxfs/xfs_ialloc.c38
-rw-r--r--libxfs/xfs_refcount.c32
-rw-r--r--libxfs/xfs_rmap.c40
4 files changed, 91 insertions, 57 deletions
diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c
index e3d243ddae..eeac7e8ae1 100644
--- a/libxfs/xfs_alloc.c
+++ b/libxfs/xfs_alloc.c
@@ -257,6 +257,24 @@ xfs_alloc_check_irec(
return NULL;
}
+static inline int
+xfs_alloc_complain_bad_rec(
+ struct xfs_btree_cur *cur,
+ xfs_failaddr_t fa,
+ const struct xfs_alloc_rec_incore *irec)
+{
+ struct xfs_mount *mp = cur->bc_mp;
+
+ xfs_warn(mp,
+ "%s Freespace BTree record corruption in AG %d detected at %pS!",
+ cur->bc_btnum == XFS_BTNUM_BNO ? "Block" : "Size",
+ cur->bc_ag.pag->pag_agno, fa);
+ xfs_warn(mp,
+ "start block 0x%x block count 0x%x", irec->ar_startblock,
+ irec->ar_blockcount);
+ return -EFSCORRUPTED;
+}
+
/*
* Get the data from the pointed-to record.
*/
@@ -268,8 +286,6 @@ xfs_alloc_get_rec(
int *stat) /* output: success/failure */
{
struct xfs_alloc_rec_incore irec;
- struct xfs_mount *mp = cur->bc_mp;
- struct xfs_perag *pag = cur->bc_ag.pag;
union xfs_btree_rec *rec;
xfs_failaddr_t fa;
int error;
@@ -281,21 +297,11 @@ xfs_alloc_get_rec(
xfs_alloc_btrec_to_irec(rec, &irec);
fa = xfs_alloc_check_irec(cur, &irec);
if (fa)
- goto out_bad_rec;
+ return xfs_alloc_complain_bad_rec(cur, fa, &irec);
*bno = irec.ar_startblock;
*len = irec.ar_blockcount;
return 0;
-
-out_bad_rec:
- xfs_warn(mp,
- "%s Freespace BTree record corruption in AG %d detected at %pS!",
- cur->bc_btnum == XFS_BTNUM_BNO ? "Block" : "Size",
- pag->pag_agno, fa);
- xfs_warn(mp,
- "start block 0x%x block count 0x%x", irec.ar_startblock,
- irec.ar_blockcount);
- return -EFSCORRUPTED;
}
/*
@@ -3688,10 +3694,12 @@ xfs_alloc_query_range_helper(
{
struct xfs_alloc_query_range_info *query = priv;
struct xfs_alloc_rec_incore irec;
+ xfs_failaddr_t fa;
xfs_alloc_btrec_to_irec(rec, &irec);
- if (xfs_alloc_check_irec(cur, &irec) != NULL)
- return -EFSCORRUPTED;
+ fa = xfs_alloc_check_irec(cur, &irec);
+ if (fa)
+ return xfs_alloc_complain_bad_rec(cur, fa, &irec);
return query->fn(cur, &irec, query->priv);
}
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 78634c5a7b..fa5ac81801 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -117,6 +117,25 @@ xfs_inobt_check_irec(
return NULL;
}
+static inline int
+xfs_inobt_complain_bad_rec(
+ struct xfs_btree_cur *cur,
+ xfs_failaddr_t fa,
+ const struct xfs_inobt_rec_incore *irec)
+{
+ struct xfs_mount *mp = cur->bc_mp;
+
+ xfs_warn(mp,
+ "%s Inode BTree record corruption in AG %d detected at %pS!",
+ cur->bc_btnum == XFS_BTNUM_INO ? "Used" : "Free",
+ cur->bc_ag.pag->pag_agno, fa);
+ xfs_warn(mp,
+"start inode 0x%x, count 0x%x, free 0x%x freemask 0x%llx, holemask 0x%x",
+ irec->ir_startino, irec->ir_count, irec->ir_freecount,
+ irec->ir_free, irec->ir_holemask);
+ return -EFSCORRUPTED;
+}
+
/*
* Get the data from the pointed-to record.
*/
@@ -138,20 +157,9 @@ xfs_inobt_get_rec(
xfs_inobt_btrec_to_irec(mp, rec, irec);
fa = xfs_inobt_check_irec(cur, irec);
if (fa)
- goto out_bad_rec;
+ return xfs_inobt_complain_bad_rec(cur, fa, irec);
return 0;
-
-out_bad_rec:
- xfs_warn(mp,
- "%s Inode BTree record corruption in AG %d detected at %pS!",
- cur->bc_btnum == XFS_BTNUM_INO ? "Used" : "Free",
- cur->bc_ag.pag->pag_agno, fa);
- xfs_warn(mp,
-"start inode 0x%x, count 0x%x, free 0x%x freemask 0x%llx, holemask 0x%x",
- irec->ir_startino, irec->ir_count, irec->ir_freecount,
- irec->ir_free, irec->ir_holemask);
- return -EFSCORRUPTED;
}
/*
@@ -2697,10 +2705,12 @@ xfs_ialloc_count_inodes_rec(
{
struct xfs_inobt_rec_incore irec;
struct xfs_ialloc_count_inodes *ci = priv;
+ xfs_failaddr_t fa;
xfs_inobt_btrec_to_irec(cur->bc_mp, rec, &irec);
- if (xfs_inobt_check_irec(cur, &irec) != NULL)
- return -EFSCORRUPTED;
+ fa = xfs_inobt_check_irec(cur, &irec);
+ if (fa)
+ return xfs_inobt_complain_bad_rec(cur, fa, &irec);
ci->count += irec.ir_count;
ci->freecount += irec.ir_freecount;
diff --git a/libxfs/xfs_refcount.c b/libxfs/xfs_refcount.c
index 7028342c77..c83074d2ec 100644
--- a/libxfs/xfs_refcount.c
+++ b/libxfs/xfs_refcount.c
@@ -143,6 +143,23 @@ xfs_refcount_check_irec(
return NULL;
}
+static inline int
+xfs_refcount_complain_bad_rec(
+ struct xfs_btree_cur *cur,
+ xfs_failaddr_t fa,
+ const struct xfs_refcount_irec *irec)
+{
+ struct xfs_mount *mp = cur->bc_mp;
+
+ xfs_warn(mp,
+ "Refcount BTree record corruption in AG %d detected at %pS!",
+ cur->bc_ag.pag->pag_agno, fa);
+ xfs_warn(mp,
+ "Start block 0x%x, block count 0x%x, references 0x%x",
+ irec->rc_startblock, irec->rc_blockcount, irec->rc_refcount);
+ return -EFSCORRUPTED;
+}
+
/*
* Get the data from the pointed-to record.
*/
@@ -152,8 +169,6 @@ xfs_refcount_get_rec(
struct xfs_refcount_irec *irec,
int *stat)
{
- struct xfs_mount *mp = cur->bc_mp;
- struct xfs_perag *pag = cur->bc_ag.pag;
union xfs_btree_rec *rec;
xfs_failaddr_t fa;
int error;
@@ -165,19 +180,10 @@ xfs_refcount_get_rec(
xfs_refcount_btrec_to_irec(rec, irec);
fa = xfs_refcount_check_irec(cur, irec);
if (fa)
- goto out_bad_rec;
+ return xfs_refcount_complain_bad_rec(cur, fa, irec);
- trace_xfs_refcount_get(cur->bc_mp, pag->pag_agno, irec);
+ trace_xfs_refcount_get(cur->bc_mp, cur->bc_ag.pag->pag_agno, irec);
return 0;
-
-out_bad_rec:
- xfs_warn(mp,
- "Refcount BTree record corruption in AG %d detected at %pS!",
- pag->pag_agno, fa);
- xfs_warn(mp,
- "Start block 0x%x, block count 0x%x, references 0x%x",
- irec->rc_startblock, irec->rc_blockcount, irec->rc_refcount);
- return -EFSCORRUPTED;
}
/*
diff --git a/libxfs/xfs_rmap.c b/libxfs/xfs_rmap.c
index 5ac2ca509a..a5b48f0ec2 100644
--- a/libxfs/xfs_rmap.c
+++ b/libxfs/xfs_rmap.c
@@ -234,6 +234,24 @@ xfs_rmap_check_irec(
return NULL;
}
+static inline int
+xfs_rmap_complain_bad_rec(
+ struct xfs_btree_cur *cur,
+ xfs_failaddr_t fa,
+ const struct xfs_rmap_irec *irec)
+{
+ struct xfs_mount *mp = cur->bc_mp;
+
+ xfs_warn(mp,
+ "Reverse Mapping BTree record corruption in AG %d detected at %pS!",
+ cur->bc_ag.pag->pag_agno, fa);
+ xfs_warn(mp,
+ "Owner 0x%llx, flags 0x%x, start block 0x%x block count 0x%x",
+ irec->rm_owner, irec->rm_flags, irec->rm_startblock,
+ irec->rm_blockcount);
+ return -EFSCORRUPTED;
+}
+
/*
* Get the data from the pointed-to record.
*/
@@ -243,8 +261,6 @@ xfs_rmap_get_rec(
struct xfs_rmap_irec *irec,
int *stat)
{
- struct xfs_mount *mp = cur->bc_mp;
- struct xfs_perag *pag = cur->bc_ag.pag;
union xfs_btree_rec *rec;
xfs_failaddr_t fa;
int error;
@@ -257,18 +273,9 @@ xfs_rmap_get_rec(
if (!fa)
fa = xfs_rmap_check_irec(cur, irec);
if (fa)
- goto out_bad_rec;
+ return xfs_rmap_complain_bad_rec(cur, fa, irec);
return 0;
-out_bad_rec:
- xfs_warn(mp,
- "Reverse Mapping BTree record corruption in AG %d detected at %pS!",
- pag->pag_agno, fa);
- xfs_warn(mp,
- "Owner 0x%llx, flags 0x%x, start block 0x%x block count 0x%x",
- irec->rm_owner, irec->rm_flags, irec->rm_startblock,
- irec->rm_blockcount);
- return -EFSCORRUPTED;
}
struct xfs_find_left_neighbor_info {
@@ -2334,10 +2341,13 @@ xfs_rmap_query_range_helper(
{
struct xfs_rmap_query_range_info *query = priv;
struct xfs_rmap_irec irec;
+ xfs_failaddr_t fa;
- if (xfs_rmap_btrec_to_irec(rec, &irec) != NULL ||
- xfs_rmap_check_irec(cur, &irec) != NULL)
- return -EFSCORRUPTED;
+ fa = xfs_rmap_btrec_to_irec(rec, &irec);
+ if (!fa)
+ fa = xfs_rmap_check_irec(cur, &irec);
+ if (fa)
+ return xfs_rmap_complain_bad_rec(cur, fa, &irec);
return query->fn(cur, &irec, query->priv);
}