]> git.apps.os.sepia.ceph.com Git - xfsprogs-dev.git/commitdiff
xfs: report block map corruption errors to the health tracking system
authorDarrick J. Wong <djwong@kernel.org>
Mon, 22 Apr 2024 17:00:54 +0000 (10:00 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Mon, 3 Jun 2024 18:37:36 +0000 (11:37 -0700)
Source kernel commit: 1196f3f5abf736809cafac1696967ac318a44ca0

Whenever we encounter a corrupt block mapping, we should report that to
the health monitoring system for later reporting.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
libxfs/util.c
libxfs/xfs_bmap.c
libxfs/xfs_health.h

index c30d83a8d6fba527b7be8178b8b32467d7f9becd..2403d64b4cc02073f9697a71fd2dd515fac131d6 100644 (file)
@@ -732,3 +732,4 @@ void xfs_fs_mark_sick(struct xfs_mount *mp, unsigned int mask) { }
 void xfs_agno_mark_sick(struct xfs_mount *mp, xfs_agnumber_t agno,
                unsigned int mask) { }
 void xfs_ag_mark_sick(struct xfs_perag *pag, unsigned int mask) { }
+void xfs_bmap_mark_sick(struct xfs_inode *ip, int whichfork) { }
index 4f616a5473dfc398fd6a659fd09c8c2824fe29db..4d21720e9ac6661cb4d3e3e3576ee37540033c5d 100644 (file)
@@ -30,6 +30,7 @@
 #include "xfs_ag_resv.h"
 #include "xfs_refcount.h"
 #include "xfs_rtbitmap.h"
+#include "xfs_health.h"
 
 struct kmem_cache              *xfs_bmap_intent_cache;
 
@@ -954,6 +955,7 @@ xfs_bmap_add_attrfork_local(
 
        /* should only be called for types that support local format data */
        ASSERT(0);
+       xfs_bmap_mark_sick(ip, XFS_ATTR_FORK);
        return -EFSCORRUPTED;
 }
 
@@ -1137,6 +1139,7 @@ xfs_iread_bmbt_block(
                                (unsigned long long)ip->i_ino);
                xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, block,
                                sizeof(*block), __this_address);
+               xfs_bmap_mark_sick(ip, whichfork);
                return -EFSCORRUPTED;
        }
 
@@ -1152,6 +1155,7 @@ xfs_iread_bmbt_block(
                        xfs_inode_verifier_error(ip, -EFSCORRUPTED,
                                        "xfs_iread_extents(2)", frp,
                                        sizeof(*frp), fa);
+                       xfs_bmap_mark_sick(ip, whichfork);
                        return xfs_bmap_complain_bad_rec(ip, whichfork, fa,
                                        &new);
                }
@@ -1207,6 +1211,8 @@ xfs_iread_extents(
        smp_store_release(&ifp->if_needextents, 0);
        return 0;
 out:
+       if (xfs_metadata_is_sick(error))
+               xfs_bmap_mark_sick(ip, whichfork);
        xfs_iext_destroy(ifp);
        return error;
 }
@@ -1286,6 +1292,7 @@ xfs_bmap_last_before(
                break;
        default:
                ASSERT(0);
+               xfs_bmap_mark_sick(ip, whichfork);
                return -EFSCORRUPTED;
        }
 
@@ -3894,12 +3901,16 @@ xfs_bmapi_read(
        ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK | XFS_BMAPI_ENTIRE)));
        xfs_assert_ilocked(ip, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL);
 
-       if (WARN_ON_ONCE(!ifp))
+       if (WARN_ON_ONCE(!ifp)) {
+               xfs_bmap_mark_sick(ip, whichfork);
                return -EFSCORRUPTED;
+       }
 
        if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
-           XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT))
+           XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
+               xfs_bmap_mark_sick(ip, whichfork);
                return -EFSCORRUPTED;
+       }
 
        if (xfs_is_shutdown(mp))
                return -EIO;
@@ -4380,6 +4391,7 @@ xfs_bmapi_write(
 
        if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
            XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
+               xfs_bmap_mark_sick(ip, whichfork);
                return -EFSCORRUPTED;
        }
 
@@ -4607,9 +4619,11 @@ xfs_bmapi_convert_delalloc(
        error = -ENOSPC;
        if (WARN_ON_ONCE(bma.blkno == NULLFSBLOCK))
                goto out_finish;
-       error = -EFSCORRUPTED;
-       if (WARN_ON_ONCE(!xfs_valid_startblock(ip, bma.got.br_startblock)))
+       if (WARN_ON_ONCE(!xfs_valid_startblock(ip, bma.got.br_startblock))) {
+               xfs_bmap_mark_sick(ip, whichfork);
+               error = -EFSCORRUPTED;
                goto out_finish;
+       }
 
        XFS_STATS_ADD(mp, xs_xstrat_bytes, XFS_FSB_TO_B(mp, bma.length));
        XFS_STATS_INC(mp, xs_xstrat_quick);
@@ -4668,6 +4682,7 @@ xfs_bmapi_remap(
 
        if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
            XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
+               xfs_bmap_mark_sick(ip, whichfork);
                return -EFSCORRUPTED;
        }
 
@@ -5280,8 +5295,10 @@ __xfs_bunmapi(
        whichfork = xfs_bmapi_whichfork(flags);
        ASSERT(whichfork != XFS_COW_FORK);
        ifp = xfs_ifork_ptr(ip, whichfork);
-       if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)))
+       if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp))) {
+               xfs_bmap_mark_sick(ip, whichfork);
                return -EFSCORRUPTED;
+       }
        if (xfs_is_shutdown(mp))
                return -EIO;
 
@@ -5751,6 +5768,7 @@ xfs_bmap_collapse_extents(
 
        if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
            XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
+               xfs_bmap_mark_sick(ip, whichfork);
                return -EFSCORRUPTED;
        }
 
@@ -5866,6 +5884,7 @@ xfs_bmap_insert_extents(
 
        if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
            XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
+               xfs_bmap_mark_sick(ip, whichfork);
                return -EFSCORRUPTED;
        }
 
@@ -5969,6 +5988,7 @@ xfs_bmap_split_extent(
 
        if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
            XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
+               xfs_bmap_mark_sick(ip, whichfork);
                return -EFSCORRUPTED;
        }
 
@@ -6151,8 +6171,10 @@ xfs_bmap_finish_one(
                        bmap->br_startoff, bmap->br_blockcount,
                        bmap->br_state);
 
-       if (WARN_ON_ONCE(bi->bi_whichfork != XFS_DATA_FORK))
+       if (WARN_ON_ONCE(bi->bi_whichfork != XFS_DATA_FORK)) {
+               xfs_bmap_mark_sick(bi->bi_owner, bi->bi_whichfork);
                return -EFSCORRUPTED;
+       }
 
        if (XFS_TEST_ERROR(false, tp->t_mountp,
                        XFS_ERRTAG_BMAP_FINISH_ONE))
@@ -6170,6 +6192,7 @@ xfs_bmap_finish_one(
                break;
        default:
                ASSERT(0);
+               xfs_bmap_mark_sick(bi->bi_owner, bi->bi_whichfork);
                error = -EFSCORRUPTED;
        }
 
index fb3f2b49087de686e1526f5ca323a3df1303beed..3c8fd060744f2c76170b7ab35af72f84f0c08fa6 100644 (file)
@@ -159,6 +159,7 @@ void xfs_inode_measure_sickness(struct xfs_inode *ip, unsigned int *sick,
                unsigned int *checked);
 
 void xfs_health_unmount(struct xfs_mount *mp);
+void xfs_bmap_mark_sick(struct xfs_inode *ip, int whichfork);
 
 /* Now some helpers. */