From patchwork Tue Mar 26 03:33:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13603446 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A91E686AC1 for ; Tue, 26 Mar 2024 03:33:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711424002; cv=none; b=FHfTLAid1AlduM9JyWOaOUOnnTNltUe8J6xBueIlsg/DYYH0nTza1b6pC3OWqbx7YNJHTs/u3n7xr7nlpVuXNUCbX2FyLI7eiZFg9WmXKIGXo6QTjD0vnpEOagpZH53GcR4tQoOadn8qRQ9YyqY9s5kCfTqWttK4pgTYov6bXrg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711424002; c=relaxed/simple; bh=TZb1wCh3GtaXucmNMDsNFX+4UVdVmwzLKMIO6lAP3j4=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=go9whwJfJSQCyIosHowVhSika8tDq2zzs5dqg5aCeZh5fuDkfARX1ZXgnGj/2J+MS6TUcUQZt+aD0cN112fVC7jeIvwIbVN/WjsjTclE2sqNZghivJxsNb0/+0X+WdVB0QPOM09VWSX4tD4If2c4XB8xOb3Go8WZErm+rlVXpFE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dFjeQBN6; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dFjeQBN6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 44583C433F1; Tue, 26 Mar 2024 03:33:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1711424002; bh=TZb1wCh3GtaXucmNMDsNFX+4UVdVmwzLKMIO6lAP3j4=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=dFjeQBN6pdp6jesBpHgpyfz/mmtwqJiXphZm/9cwmgA8h206fkcqg2mAH/h7G6des /57PJ3E6BvAd+uqvKxChad7Rwya6J3qQvZyWqatUMTucv4ROnxVl7b4Nia2vtjcj51 1gukp1lfQmQd/lWzsMD2u5KgWeMoZkhjW3y7RhBKkRcqaJoGIdtFW3hlWy1pq40oGS +SnCnSM4NK5E3VupXOJDmFBIVyVGlv6PQrbYGx43HBg6cSx8VIRpGVB+E4GR+TnuuG rj0e6BnQKz/xT9EwIhg9gki395GCfWmLaZbKO9AO0CrXvL5kA3UeyMjOEoV+xgaP2N WpNoicNUZL8Rg== Date: Mon, 25 Mar 2024 20:33:21 -0700 Subject: [PATCH 019/110] xfs: report block map corruption errors to the health tracking system From: "Darrick J. Wong" To: cem@kernel.org, djwong@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <171142131658.2215168.12791179744625557508.stgit@frogsfrogsfrogs> In-Reply-To: <171142131228.2215168.2795743548791967397.stgit@frogsfrogsfrogs> References: <171142131228.2215168.2795743548791967397.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong 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 Reviewed-by: Christoph Hellwig --- libxfs/util.c | 1 + libxfs/xfs_bmap.c | 35 +++++++++++++++++++++++++++++------ libxfs/xfs_health.h | 1 + 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/libxfs/util.c b/libxfs/util.c index c30d83a8d6fb..2403d64b4cc0 100644 --- a/libxfs/util.c +++ b/libxfs/util.c @@ -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) { } diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index 4f616a5473df..4d21720e9ac6 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -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; } diff --git a/libxfs/xfs_health.h b/libxfs/xfs_health.h index fb3f2b49087d..3c8fd060744f 100644 --- a/libxfs/xfs_health.h +++ b/libxfs/xfs_health.h @@ -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. */