]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: complain about bad records in query_range helpers
authorDarrick J. Wong <djwong@kernel.org>
Wed, 31 May 2023 08:59:21 +0000 (10:59 +0200)
committerCarlos Maiolino <cem@kernel.org>
Fri, 9 Jun 2023 08:27:50 +0000 (10:27 +0200)
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>
libxfs/xfs_alloc.c
libxfs/xfs_ialloc.c
libxfs/xfs_refcount.c
libxfs/xfs_rmap.c

index e3d243ddae5ec638dc98cf921540daf90fb4a29b..eeac7e8ae162823b6de7040022b8d5ac1c7cf1b4 100644 (file)
@@ -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);
 }
index 78634c5a7b2ffde76f2c8eaed8cfb6bfa0683603..fa5ac818014964bf0a592bb82bf29caa71fb6118 100644 (file)
@@ -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;
index 7028342c77f382f57b232a3b26cb19a5f9bd7613..c83074d2ec838ce6129d00bff863fc401f0f44f6 100644 (file)
@@ -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;
 }
 
 /*
index 5ac2ca509a594b6fa5da792abb3379e8bcc42b87..a5b48f0ec241fce9726076d6736316117c60599a 100644 (file)
@@ -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);
 }