From patchwork Sun Nov 3 22:24:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 11224771 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E80F81709 for ; Sun, 3 Nov 2019 22:24:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C60E621D56 for ; Sun, 3 Nov 2019 22:24:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="CORbDMJA" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727951AbfKCWY4 (ORCPT ); Sun, 3 Nov 2019 17:24:56 -0500 Received: from userp2120.oracle.com ([156.151.31.85]:44162 "EHLO userp2120.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727520AbfKCWYz (ORCPT ); Sun, 3 Nov 2019 17:24:55 -0500 Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MOJa8061265 for ; Sun, 3 Nov 2019 22:24:54 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=subject : from : to : cc : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=corp-2019-08-05; bh=mv307vKI/QFT2CsQrVvl+3KoVJ3jqodMd5PgrEZk6AI=; b=CORbDMJAkL3JBtN60HtdWb4Q68KFl8/QqArrf0TVqcOZizDmnI6TwrRP2nL9K3ZOZYG1 /MhQ2FjeB12zdKV6CV3zNTrkF7WKrdkn/dxtTso1d6juXUUCa2b7f75NLxqd21nwA/97 Hz1P7Ga/6lPUNPYNYZczB78kgaG50GWbhJsjC47uu2Xgrfh2XKzFKaDMTqvoHbAyZBWp LHsYQXdKeDv5e94ZcDnnbyxJOZZElQsF5NeTb3OFchCbEYMp348DpAhoyKzzAVt3eItm voydoKz0hIwPy2o79eM+yfOIGhDDX4RBcgHGd3w415+pNJBh+6KiFl7N4I7j1cMdK7Wk /Q== Received: from aserp3030.oracle.com (aserp3030.oracle.com [141.146.126.71]) by userp2120.oracle.com with ESMTP id 2w12eqv059-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:24:54 +0000 Received: from pps.filterd (aserp3030.oracle.com [127.0.0.1]) by aserp3030.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MOOgr026519 for ; Sun, 3 Nov 2019 22:24:53 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserp3030.oracle.com with ESMTP id 2w1kxk9rtj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:24:53 +0000 Received: from abhmp0007.oracle.com (abhmp0007.oracle.com [141.146.116.13]) by aserv0121.oracle.com (8.14.4/8.13.8) with ESMTP id xA3MOqTI032235 for ; Sun, 3 Nov 2019 22:24:52 GMT Received: from localhost (/67.169.218.210) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sun, 03 Nov 2019 14:24:52 -0800 Subject: [PATCH 01/10] xfs: separate the marking of sick and checked metadata From: "Darrick J. Wong" To: darrick.wong@oracle.com Cc: linux-xfs@vger.kernel.org Date: Sun, 03 Nov 2019 14:24:51 -0800 Message-ID: <157281989116.4152102.12394617850649490093.stgit@magnolia> In-Reply-To: <157281988489.4152102.1632857939932700344.stgit@magnolia> References: <157281988489.4152102.1632857939932700344.stgit@magnolia> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=1 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Split the setting of the sick and checked masks into separate functions as part of preparing to add the ability for regular runtime fs code (i.e. not scrub) to mark metadata structures sick when corruptions are found. Improve the documentation of libxfs' requirements for helper behavior. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_health.h | 16 +++++++++++++- fs/xfs/scrub/health.c | 20 +++++++++++------- fs/xfs/xfs_health.c | 49 ++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_mount.c | 5 ++++ 4 files changed, 80 insertions(+), 10 deletions(-) diff --git a/fs/xfs/libxfs/xfs_health.h b/fs/xfs/libxfs/xfs_health.h index 272005ac8c88..96919a257870 100644 --- a/fs/xfs/libxfs/xfs_health.h +++ b/fs/xfs/libxfs/xfs_health.h @@ -97,24 +97,38 @@ struct xfs_fsop_geom; XFS_SICK_INO_SYMLINK | \ XFS_SICK_INO_PARENT) -/* These functions must be provided by the xfs implementation. */ +/* + * These functions must be provided by the xfs implementation. Function + * behavior with respect to the first argument should be as follows: + * + * xfs_*_mark_sick: set the sick flags and do not set checked flags. + * xfs_*_mark_checked: set the checked flags. + * xfs_*_mark_healthy: clear the sick flags and set the checked flags. + * + * xfs_*_measure_sickness: return the sick and check status in the provided + * out parameters. + */ void xfs_fs_mark_sick(struct xfs_mount *mp, unsigned int mask); +void xfs_fs_mark_checked(struct xfs_mount *mp, unsigned int mask); void xfs_fs_mark_healthy(struct xfs_mount *mp, unsigned int mask); void xfs_fs_measure_sickness(struct xfs_mount *mp, unsigned int *sick, unsigned int *checked); void xfs_rt_mark_sick(struct xfs_mount *mp, unsigned int mask); +void xfs_rt_mark_checked(struct xfs_mount *mp, unsigned int mask); void xfs_rt_mark_healthy(struct xfs_mount *mp, unsigned int mask); void xfs_rt_measure_sickness(struct xfs_mount *mp, unsigned int *sick, unsigned int *checked); void xfs_ag_mark_sick(struct xfs_perag *pag, unsigned int mask); +void xfs_ag_mark_checked(struct xfs_perag *pag, unsigned int mask); void xfs_ag_mark_healthy(struct xfs_perag *pag, unsigned int mask); void xfs_ag_measure_sickness(struct xfs_perag *pag, unsigned int *sick, unsigned int *checked); void xfs_inode_mark_sick(struct xfs_inode *ip, unsigned int mask); +void xfs_inode_mark_checked(struct xfs_inode *ip, unsigned int mask); void xfs_inode_mark_healthy(struct xfs_inode *ip, unsigned int mask); void xfs_inode_measure_sickness(struct xfs_inode *ip, unsigned int *sick, unsigned int *checked); diff --git a/fs/xfs/scrub/health.c b/fs/xfs/scrub/health.c index b2f602811e9d..fe5ecc1d9224 100644 --- a/fs/xfs/scrub/health.c +++ b/fs/xfs/scrub/health.c @@ -136,30 +136,34 @@ xchk_update_health( switch (type_to_health_flag[sc->sm->sm_type].group) { case XHG_AG: pag = xfs_perag_get(sc->mp, sc->sm->sm_agno); - if (bad) + if (bad) { xfs_ag_mark_sick(pag, sc->sick_mask); - else + xfs_ag_mark_checked(pag, sc->sick_mask); + } else xfs_ag_mark_healthy(pag, sc->sick_mask); xfs_perag_put(pag); break; case XHG_INO: if (!sc->ip) return; - if (bad) + if (bad) { xfs_inode_mark_sick(sc->ip, sc->sick_mask); - else + xfs_inode_mark_checked(sc->ip, sc->sick_mask); + } else xfs_inode_mark_healthy(sc->ip, sc->sick_mask); break; case XHG_FS: - if (bad) + if (bad) { xfs_fs_mark_sick(sc->mp, sc->sick_mask); - else + xfs_fs_mark_checked(sc->mp, sc->sick_mask); + } else xfs_fs_mark_healthy(sc->mp, sc->sick_mask); break; case XHG_RT: - if (bad) + if (bad) { xfs_rt_mark_sick(sc->mp, sc->sick_mask); - else + xfs_rt_mark_checked(sc->mp, sc->sick_mask); + } else xfs_rt_mark_healthy(sc->mp, sc->sick_mask); break; default: diff --git a/fs/xfs/xfs_health.c b/fs/xfs/xfs_health.c index 8e0cb05a7142..860dc70c99e7 100644 --- a/fs/xfs/xfs_health.c +++ b/fs/xfs/xfs_health.c @@ -100,6 +100,18 @@ xfs_fs_mark_sick( spin_lock(&mp->m_sb_lock); mp->m_fs_sick |= mask; + spin_unlock(&mp->m_sb_lock); +} + +/* Mark per-fs metadata as having been checked. */ +void +xfs_fs_mark_checked( + struct xfs_mount *mp, + unsigned int mask) +{ + ASSERT(!(mask & ~XFS_SICK_FS_PRIMARY)); + + spin_lock(&mp->m_sb_lock); mp->m_fs_checked |= mask; spin_unlock(&mp->m_sb_lock); } @@ -143,6 +155,19 @@ xfs_rt_mark_sick( spin_lock(&mp->m_sb_lock); mp->m_rt_sick |= mask; + spin_unlock(&mp->m_sb_lock); +} + +/* Mark realtime metadata as having been checked. */ +void +xfs_rt_mark_checked( + struct xfs_mount *mp, + unsigned int mask) +{ + ASSERT(!(mask & ~XFS_SICK_RT_PRIMARY)); + trace_xfs_rt_mark_sick(mp, mask); + + spin_lock(&mp->m_sb_lock); mp->m_rt_checked |= mask; spin_unlock(&mp->m_sb_lock); } @@ -186,6 +211,18 @@ xfs_ag_mark_sick( spin_lock(&pag->pag_state_lock); pag->pag_sick |= mask; + spin_unlock(&pag->pag_state_lock); +} + +/* Mark per-ag metadata as having been checked. */ +void +xfs_ag_mark_checked( + struct xfs_perag *pag, + unsigned int mask) +{ + ASSERT(!(mask & ~XFS_SICK_AG_PRIMARY)); + + spin_lock(&pag->pag_state_lock); pag->pag_checked |= mask; spin_unlock(&pag->pag_state_lock); } @@ -229,6 +266,18 @@ xfs_inode_mark_sick( spin_lock(&ip->i_flags_lock); ip->i_sick |= mask; + spin_unlock(&ip->i_flags_lock); +} + +/* Mark inode metadata as having been checked. */ +void +xfs_inode_mark_checked( + struct xfs_inode *ip, + unsigned int mask) +{ + ASSERT(!(mask & ~XFS_SICK_INO_PRIMARY)); + + spin_lock(&ip->i_flags_lock); ip->i_checked |= mask; spin_unlock(&ip->i_flags_lock); } diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 8af714421460..76af110eb79f 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -555,8 +555,10 @@ xfs_check_summary_counts( if (XFS_LAST_UNMOUNT_WAS_CLEAN(mp) && (mp->m_sb.sb_fdblocks > mp->m_sb.sb_dblocks || !xfs_verify_icount(mp, mp->m_sb.sb_icount) || - mp->m_sb.sb_ifree > mp->m_sb.sb_icount)) + mp->m_sb.sb_ifree > mp->m_sb.sb_icount)) { xfs_fs_mark_sick(mp, XFS_SICK_FS_COUNTERS); + xfs_fs_mark_checked(mp, XFS_SICK_FS_COUNTERS); + } /* * We can safely re-initialise incore superblock counters from the @@ -1321,6 +1323,7 @@ xfs_force_summary_recalc( return; xfs_fs_mark_sick(mp, XFS_SICK_FS_COUNTERS); + xfs_fs_mark_checked(mp, XFS_SICK_FS_COUNTERS); } /* From patchwork Sun Nov 3 22:24:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 11224773 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BA87C16B1 for ; Sun, 3 Nov 2019 22:25:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 905B421D56 for ; Sun, 3 Nov 2019 22:25:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="aIRnCf+r" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727955AbfKCWZD (ORCPT ); Sun, 3 Nov 2019 17:25:03 -0500 Received: from userp2130.oracle.com ([156.151.31.86]:39798 "EHLO userp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727520AbfKCWZD (ORCPT ); Sun, 3 Nov 2019 17:25:03 -0500 Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MOxuM086774 for ; Sun, 3 Nov 2019 22:25:01 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=subject : from : to : cc : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=corp-2019-08-05; bh=2pELZhJTcdzCYm2nZfF+b1IjOQo7IXDe+pdteaMtB7g=; b=aIRnCf+r0Q1jA4rq41bMalJg1XV1HgkR34n6KumpX0m7q6yiHPSoYOdZb8RrEtZtayS6 tbfGk2b3VY5VrAIGUkh+z3eMwaFwHwjqKq7hhUoXjXwQCFMNH8TaOM05LRUaJ1aNOi/4 lWFvr1+dm8CIJzUnXebLoDAV6C0mURZBC8unv88t3IYQwBe6Vhp1yTOuStD1o3l0WiFn wxljzdjnz3Yg3c2D7X2WXYG5N+0sf7PzsGyQ598bNTwM75bzQKKMdWvgsjKZdjecVK9Q 5OH0bilW/XwHS4PZYSbjlToZRhJt3K7DgpJ/ufhvK9hZywwN3WDWB/xtEYydkNWIRNDZ Sg== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by userp2130.oracle.com with ESMTP id 2w117tm60e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:25:01 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MOAK5071444 for ; Sun, 3 Nov 2019 22:25:00 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserp3020.oracle.com with ESMTP id 2w1ka8e775-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:25:00 +0000 Received: from abhmp0021.oracle.com (abhmp0021.oracle.com [141.146.116.27]) by aserv0121.oracle.com (8.14.4/8.13.8) with ESMTP id xA3MP0xh032239 for ; Sun, 3 Nov 2019 22:25:00 GMT Received: from localhost (/67.169.218.210) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sun, 03 Nov 2019 14:24:58 -0800 Subject: [PATCH 02/10] xfs: report ag header corruption errors to the health tracking system From: "Darrick J. Wong" To: darrick.wong@oracle.com Cc: linux-xfs@vger.kernel.org Date: Sun, 03 Nov 2019 14:24:57 -0800 Message-ID: <157281989728.4152102.8612960889220308936.stgit@magnolia> In-Reply-To: <157281988489.4152102.1632857939932700344.stgit@magnolia> References: <157281988489.4152102.1632857939932700344.stgit@magnolia> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=3 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=3 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Whenever we encounter a corrupt AG header, we should report that to the health monitoring system for later reporting. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc.c | 6 ++++++ fs/xfs/libxfs/xfs_health.h | 14 +++++++++++--- fs/xfs/libxfs/xfs_ialloc.c | 3 +++ fs/xfs/libxfs/xfs_refcount.c | 1 + fs/xfs/libxfs/xfs_rmap.c | 1 + fs/xfs/libxfs/xfs_sb.c | 2 ++ fs/xfs/xfs_health.c | 17 +++++++++++++++++ fs/xfs/xfs_inode.c | 9 +++++++++ 8 files changed, 50 insertions(+), 3 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 8231be43f48d..72cfe243d58d 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -26,6 +26,7 @@ #include "xfs_log.h" #include "xfs_ag_resv.h" #include "xfs_bmap.h" +#include "xfs_health.h" extern kmem_zone_t *xfs_bmap_free_item_zone; @@ -694,6 +695,8 @@ xfs_alloc_read_agfl( mp, tp, mp->m_ddev_targp, XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), 0, &bp, &xfs_agfl_buf_ops); + if (xfs_metadata_is_sick(error)) + xfs_agno_mark_sick(mp, agno, XFS_SICK_AG_AGFL); if (error) return error; xfs_buf_set_ref(bp, XFS_AGFL_REF); @@ -717,6 +720,7 @@ xfs_alloc_update_counters( if (unlikely(be32_to_cpu(agf->agf_freeblks) > be32_to_cpu(agf->agf_length))) { xfs_buf_corruption_error(agbp); + xfs_ag_mark_sick(pag, XFS_SICK_AG_AGF); return -EFSCORRUPTED; } @@ -2930,6 +2934,8 @@ xfs_read_agf( mp, tp, mp->m_ddev_targp, XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), flags, bpp, &xfs_agf_buf_ops); + if (xfs_metadata_is_sick(error)) + xfs_agno_mark_sick(mp, agno, XFS_SICK_AG_AGF); if (error) return error; if (!*bpp) diff --git a/fs/xfs/libxfs/xfs_health.h b/fs/xfs/libxfs/xfs_health.h index 96919a257870..ce8954a10c66 100644 --- a/fs/xfs/libxfs/xfs_health.h +++ b/fs/xfs/libxfs/xfs_health.h @@ -26,9 +26,11 @@ * and the "sick" field tells us if that piece was found to need repairs. * Therefore we can conclude that for a given sick flag value: * - * - checked && sick => metadata needs repair - * - checked && !sick => metadata is ok - * - !checked => has not been examined since mount + * - checked && sick => metadata needs repair + * - checked && !sick => metadata is ok + * - !checked && sick => errors have been observed during normal operation, + * but the metadata has not been checked thoroughly + * - !checked && !sick => has not been examined since mount */ struct xfs_mount; @@ -121,6 +123,8 @@ void xfs_rt_mark_healthy(struct xfs_mount *mp, unsigned int mask); void xfs_rt_measure_sickness(struct xfs_mount *mp, unsigned int *sick, unsigned int *checked); +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_ag_mark_checked(struct xfs_perag *pag, unsigned int mask); void xfs_ag_mark_healthy(struct xfs_perag *pag, unsigned int mask); @@ -201,4 +205,8 @@ void xfs_fsop_geom_health(struct xfs_mount *mp, struct xfs_fsop_geom *geo); void xfs_ag_geom_health(struct xfs_perag *pag, struct xfs_ag_geometry *ageo); void xfs_bulkstat_health(struct xfs_inode *ip, struct xfs_bulkstat *bs); +#define xfs_metadata_is_sick(error) \ + (unlikely((error) == -EFSCORRUPTED || (error) == -EIO || \ + (error) == -EFSBADCRC)) + #endif /* __XFS_HEALTH_H__ */ diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 9232d9a03ebb..57da33556e9f 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -27,6 +27,7 @@ #include "xfs_trace.h" #include "xfs_log.h" #include "xfs_rmap.h" +#include "xfs_health.h" /* * Lookup a record by ino in the btree given by cur. @@ -2635,6 +2636,8 @@ xfs_read_agi( error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), 0, bpp, &xfs_agi_buf_ops); + if (xfs_metadata_is_sick(error)) + xfs_agno_mark_sick(mp, agno, XFS_SICK_AG_AGI); if (error) return error; if (tp) diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index 0d998e3b6acf..26ab2c629c1f 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -1178,6 +1178,7 @@ xfs_refcount_finish_one( if (error) return error; if (XFS_CORRUPT_ON(tp->t_mountp, !agbp)) { + xfs_agno_mark_sick(tp->t_mountp, agno, XFS_SICK_AG_AGF); return -EFSCORRUPTED; } diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index 74efdbc56a60..03ce3d6f4c87 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -2395,6 +2395,7 @@ xfs_rmap_finish_one( if (error) return error; if (XFS_CORRUPT_ON(tp->t_mountp, !agbp)) { + xfs_agno_mark_sick(tp->t_mountp, agno, XFS_SICK_AG_AGF); return -EFSCORRUPTED; } diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index ac6cdca63e15..6a8d821a1dbc 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -1168,6 +1168,8 @@ xfs_sb_read_secondary( error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, XFS_AG_DADDR(mp, agno, XFS_SB_BLOCK(mp)), XFS_FSS_TO_BB(mp, 1), 0, &bp, &xfs_sb_buf_ops); + if (xfs_metadata_is_sick(error)) + xfs_agno_mark_sick(mp, agno, XFS_SICK_AG_SB); if (error) return error; xfs_buf_set_ref(bp, XFS_SSB_REF); diff --git a/fs/xfs/xfs_health.c b/fs/xfs/xfs_health.c index 860dc70c99e7..36c32b108b39 100644 --- a/fs/xfs/xfs_health.c +++ b/fs/xfs/xfs_health.c @@ -200,6 +200,23 @@ xfs_rt_measure_sickness( spin_unlock(&mp->m_sb_lock); } +/* Mark unhealthy per-ag metadata given a raw AG number. */ +void +xfs_agno_mark_sick( + struct xfs_mount *mp, + xfs_agnumber_t agno, + unsigned int mask) +{ + struct xfs_perag *pag = xfs_perag_get(mp, agno); + + /* per-ag structure not set up yet? */ + if (!pag) + return; + + xfs_ag_mark_sick(pag, mask); + xfs_perag_put(pag); +} + /* Mark unhealthy per-ag metadata. */ void xfs_ag_mark_sick( diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index a92d4521748d..d02246e2fb21 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -35,6 +35,7 @@ #include "xfs_log.h" #include "xfs_bmap_btree.h" #include "xfs_reflink.h" +#include "xfs_health.h" kmem_zone_t *xfs_inode_zone; @@ -787,6 +788,8 @@ xfs_ialloc( */ if ((pip && ino == pip->i_ino) || !xfs_verify_dir_ino(mp, ino)) { xfs_alert(mp, "Allocated a known in-use inode 0x%llx!", ino); + xfs_agno_mark_sick(mp, XFS_INO_TO_AGNO(mp, ino), + XFS_SICK_AG_INOBT); return -EFSCORRUPTED; } @@ -2138,6 +2141,7 @@ xfs_iunlink_update_bucket( */ if (old_value == new_agino) { xfs_buf_corruption_error(agibp); + xfs_agno_mark_sick(tp->t_mountp, agno, XFS_SICK_AG_AGI); return -EFSCORRUPTED; } @@ -2204,6 +2208,7 @@ xfs_iunlink_update_inode( if (!xfs_verify_agino_or_null(mp, agno, old_value)) { xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip, sizeof(*dip), __this_address); + xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE); error = -EFSCORRUPTED; goto out; } @@ -2218,6 +2223,7 @@ xfs_iunlink_update_inode( if (next_agino != NULLAGINO) { xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip, sizeof(*dip), __this_address); + xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE); error = -EFSCORRUPTED; } goto out; @@ -2272,6 +2278,7 @@ xfs_iunlink( if (next_agino == agino || !xfs_verify_agino_or_null(mp, agno, next_agino)) { xfs_buf_corruption_error(agibp); + xfs_agno_mark_sick(mp, agno, XFS_SICK_AG_AGI); return -EFSCORRUPTED; } @@ -2409,6 +2416,7 @@ xfs_iunlink_map_prev( XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, *dipp, sizeof(**dipp)); + xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI); error = -EFSCORRUPTED; return error; } @@ -2455,6 +2463,7 @@ xfs_iunlink_remove( if (!xfs_verify_agino(mp, agno, head_agino)) { XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, agi, sizeof(*agi)); + xfs_agno_mark_sick(mp, agno, XFS_SICK_AG_AGI); return -EFSCORRUPTED; } From patchwork Sun Nov 3 22:25:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 11224775 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F1FCE1709 for ; Sun, 3 Nov 2019 22:25:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C661E21D56 for ; Sun, 3 Nov 2019 22:25:08 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="NRncXQJB" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727520AbfKCWZI (ORCPT ); Sun, 3 Nov 2019 17:25:08 -0500 Received: from aserp2120.oracle.com ([141.146.126.78]:39822 "EHLO aserp2120.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727503AbfKCWZI (ORCPT ); Sun, 3 Nov 2019 17:25:08 -0500 Received: from pps.filterd (aserp2120.oracle.com [127.0.0.1]) by aserp2120.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MOJTn073221 for ; Sun, 3 Nov 2019 22:25:06 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=subject : from : to : cc : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=corp-2019-08-05; bh=4hugr4An6f0QMQT33VAB7/rcaEgVWTNVWooPBdLfkLU=; b=NRncXQJB3SEQD7gzi3wqb9c8eGUxriN6TIyvuEkPjc8mrw9HitKu/WVUEZ4chCcamx5i 8HuEFB1MNyVJ0j1VKgpSPDhuyEimiYSbaL+AykrBXOUTR6LImfV0QNjN/KxmIHP7Ik0s 9ra1sQfnfrY+wAVJLWmMcC2fEuJIMR5xNgwJN/DrQM01/3yaap0ufomFrz2/LzdJwTuO Jo1RjWk4sDJ5x84NHtgKNI7q5ISmHCSOupCahPe+khZrg3toKbCN0ygpkrqJ1LebJ8Rj tsWXYJvcDw3O+LbJXo6BFohPeYppay7fds0AtSwDYayjGMl6W4rNjgctaCUTmQKQKESB og== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by aserp2120.oracle.com with ESMTP id 2w11rpm48v-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:25:06 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MOAx1071437 for ; Sun, 3 Nov 2019 22:25:06 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserp3020.oracle.com with ESMTP id 2w1ka8e7bj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:25:06 +0000 Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id xA3MP54w007476 for ; Sun, 3 Nov 2019 22:25:05 GMT Received: from localhost (/67.169.218.210) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sun, 03 Nov 2019 14:25:04 -0800 Subject: [PATCH 03/10] xfs: report block map corruption errors to the health tracking system From: "Darrick J. Wong" To: darrick.wong@oracle.com Cc: linux-xfs@vger.kernel.org Date: Sun, 03 Nov 2019 14:25:03 -0800 Message-ID: <157281990353.4152102.15406319284510044621.stgit@magnolia> In-Reply-To: <157281988489.4152102.1632857939932700344.stgit@magnolia> References: <157281988489.4152102.1632857939932700344.stgit@magnolia> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=3 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=3 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong 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 --- fs/xfs/libxfs/xfs_bmap.c | 32 ++++++++++++++++++++++++++++---- fs/xfs/libxfs/xfs_health.h | 1 + fs/xfs/xfs_health.c | 26 ++++++++++++++++++++++++++ fs/xfs/xfs_iomap.c | 15 +++++++++++---- 4 files changed, 66 insertions(+), 8 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 0ad47ca9b14d..13523be72b8a 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -35,7 +35,7 @@ #include "xfs_refcount.h" #include "xfs_icache.h" #include "xfs_iomap.h" - +#include "xfs_health.h" kmem_zone_t *xfs_bmap_free_item_zone; @@ -732,6 +732,7 @@ xfs_bmap_extents_to_btree( xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); abp = xfs_btree_get_bufl(mp, tp, args.fsbno); if (XFS_CORRUPT_ON(mp, !abp)) { + xfs_bmap_mark_sick(ip, whichfork); error = -EFSCORRUPTED; goto out_unreserve_dquot; } @@ -1021,6 +1022,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; } @@ -1090,6 +1092,7 @@ xfs_bmap_add_attrfork( if (XFS_IFORK_Q(ip)) goto trans_cancel; if (XFS_CORRUPT_ON(mp, ip->i_d.di_anextents != 0)) { + xfs_bmap_mark_sick(ip, XFS_ATTR_FORK); error = -EFSCORRUPTED; goto trans_cancel; } @@ -1192,6 +1195,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; } @@ -1207,6 +1211,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 -EFSCORRUPTED; } xfs_iext_insert(ip, &ir->icur, &new, @@ -1238,6 +1243,7 @@ xfs_iread_extents( if (XFS_CORRUPT_ON(mp, XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) { + xfs_bmap_mark_sick(ip, whichfork); error = -EFSCORRUPTED; goto out; } @@ -1253,6 +1259,7 @@ xfs_iread_extents( if (XFS_CORRUPT_ON(mp, ir.loaded != XFS_IFORK_NEXTENTS(ip, whichfork))) { + xfs_bmap_mark_sick(ip, whichfork); error = -EFSCORRUPTED; goto out; } @@ -1261,6 +1268,8 @@ xfs_iread_extents( ifp->if_flags |= XFS_IFEXTENTS; return 0; out: + if (xfs_metadata_is_sick(error)) + xfs_bmap_mark_sick(ip, whichfork); xfs_iext_destroy(ifp); return error; } @@ -1344,6 +1353,7 @@ xfs_bmap_last_before( break; default: ASSERT(0); + xfs_bmap_mark_sick(ip, whichfork); return -EFSCORRUPTED; } @@ -1445,6 +1455,7 @@ xfs_bmap_last_offset( if (XFS_CORRUPT_ON(ip->i_mount, !XFS_IFORK_MAPS_BLOCKS(ip, whichfork))) { + xfs_bmap_mark_sick(ip, whichfork); return -EFSCORRUPTED; } @@ -3907,6 +3918,7 @@ xfs_bmapi_read( if (XFS_CORRUPT_ON(mp, !XFS_IFORK_MAPS_BLOCKS(ip, whichfork)) || XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { + xfs_bmap_mark_sick(ip, whichfork); return -EFSCORRUPTED; } @@ -3937,6 +3949,7 @@ xfs_bmapi_read( xfs_alert(mp, "%s: inode %llu missing fork %d", __func__, ip->i_ino, whichfork); #endif /* DEBUG */ + xfs_bmap_mark_sick(ip, whichfork); return -EFSCORRUPTED; } @@ -4415,6 +4428,7 @@ xfs_bmapi_write( if (XFS_CORRUPT_ON(mp, !XFS_IFORK_MAPS_BLOCKS(ip, whichfork)) || XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { + xfs_bmap_mark_sick(ip, whichfork); return -EFSCORRUPTED; } @@ -4622,9 +4636,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); @@ -4682,6 +4698,7 @@ xfs_bmapi_remap( if (XFS_CORRUPT_ON(mp, !XFS_IFORK_MAPS_BLOCKS(ip, whichfork)) || XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { + xfs_bmap_mark_sick(ip, whichfork); return -EFSCORRUPTED; } @@ -5321,6 +5338,7 @@ __xfs_bunmapi( ASSERT(whichfork != XFS_COW_FORK); ifp = XFS_IFORK_PTR(ip, whichfork); if (XFS_CORRUPT_ON(mp, !XFS_IFORK_MAPS_BLOCKS(ip, whichfork))) { + xfs_bmap_mark_sick(ip, whichfork); return -EFSCORRUPTED; } if (XFS_FORCED_SHUTDOWN(mp)) @@ -5817,6 +5835,7 @@ xfs_bmap_collapse_extents( if (XFS_CORRUPT_ON(mp, !XFS_IFORK_MAPS_BLOCKS(ip, whichfork)) || XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { + xfs_bmap_mark_sick(ip, whichfork); return -EFSCORRUPTED; } @@ -5934,6 +5953,7 @@ xfs_bmap_insert_extents( if (XFS_CORRUPT_ON(mp, !XFS_IFORK_MAPS_BLOCKS(ip, whichfork)) || XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { + xfs_bmap_mark_sick(ip, whichfork); return -EFSCORRUPTED; } @@ -6040,6 +6060,7 @@ xfs_bmap_split_extent_at( if (XFS_CORRUPT_ON(mp, !XFS_IFORK_MAPS_BLOCKS(ip, whichfork)) || XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { + xfs_bmap_mark_sick(ip, whichfork); return -EFSCORRUPTED; } @@ -6255,8 +6276,10 @@ xfs_bmap_finish_one( XFS_FSB_TO_AGBNO(tp->t_mountp, startblock), ip->i_ino, whichfork, startoff, *blockcount, state); - if (WARN_ON_ONCE(whichfork != XFS_DATA_FORK)) + if (WARN_ON_ONCE(whichfork != XFS_DATA_FORK)) { + xfs_bmap_mark_sick(ip, whichfork); return -EFSCORRUPTED; + } if (XFS_TEST_ERROR(false, tp->t_mountp, XFS_ERRTAG_BMAP_FINISH_ONE)) @@ -6274,6 +6297,7 @@ xfs_bmap_finish_one( break; default: ASSERT(0); + xfs_bmap_mark_sick(ip, whichfork); error = -EFSCORRUPTED; } diff --git a/fs/xfs/libxfs/xfs_health.h b/fs/xfs/libxfs/xfs_health.h index ce8954a10c66..25b61180b562 100644 --- a/fs/xfs/libxfs/xfs_health.h +++ b/fs/xfs/libxfs/xfs_health.h @@ -138,6 +138,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. */ diff --git a/fs/xfs/xfs_health.c b/fs/xfs/xfs_health.c index 36c32b108b39..5e5de5338476 100644 --- a/fs/xfs/xfs_health.c +++ b/fs/xfs/xfs_health.c @@ -452,3 +452,29 @@ xfs_bulkstat_health( bs->bs_sick |= m->ioctl_mask; } } + +/* Mark a block mapping sick. */ +void +xfs_bmap_mark_sick( + struct xfs_inode *ip, + int whichfork) +{ + unsigned int mask; + + switch (whichfork) { + case XFS_DATA_FORK: + mask = XFS_SICK_INO_BMBTD; + break; + case XFS_ATTR_FORK: + mask = XFS_SICK_INO_BMBTA; + break; + case XFS_COW_FORK: + mask = XFS_SICK_INO_BMBTC; + break; + default: + ASSERT(0); + return; + } + + xfs_inode_mark_sick(ip, mask); +} diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index d78df4bdd700..894ec033b3f1 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -27,7 +27,7 @@ #include "xfs_dquot_item.h" #include "xfs_dquot.h" #include "xfs_reflink.h" - +#include "xfs_health.h" #define XFS_ALLOC_ALIGN(mp, off) \ (((off) >> mp->m_allocsize_log) << mp->m_allocsize_log) @@ -59,8 +59,10 @@ xfs_bmbt_to_iomap( struct xfs_mount *mp = ip->i_mount; struct xfs_buftarg *target = xfs_inode_buftarg(ip); - if (unlikely(!xfs_valid_startblock(ip, imap->br_startblock))) + if (unlikely(!xfs_valid_startblock(ip, imap->br_startblock))) { + xfs_bmap_mark_sick(ip, XFS_DATA_FORK); return xfs_alert_fsblock_zero(ip, imap); + } if (imap->br_startblock == HOLESTARTBLOCK) { iomap->addr = IOMAP_NULL_ADDR; @@ -277,8 +279,10 @@ xfs_iomap_write_direct( goto out_unlock; } - if (unlikely(!xfs_valid_startblock(ip, imap->br_startblock))) + if (unlikely(!xfs_valid_startblock(ip, imap->br_startblock))) { + xfs_bmap_mark_sick(ip, XFS_DATA_FORK); error = xfs_alert_fsblock_zero(ip, imap); + } out_unlock: xfs_iunlock(ip, XFS_ILOCK_EXCL); @@ -588,8 +592,10 @@ xfs_iomap_write_unwritten( if (error) return error; - if (unlikely(!xfs_valid_startblock(ip, imap.br_startblock))) + if (unlikely(!xfs_valid_startblock(ip, imap.br_startblock))) { + xfs_bmap_mark_sick(ip, XFS_DATA_FORK); return xfs_alert_fsblock_zero(ip, &imap); + } if ((numblks_fsb = imap.br_blockcount) == 0) { /* @@ -848,6 +854,7 @@ xfs_buffered_write_iomap_begin( if (XFS_CORRUPT_ON(mp, !XFS_IFORK_MAPS_BLOCKS(ip, XFS_DATA_FORK)) || XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { + xfs_bmap_mark_sick(ip, XFS_DATA_FORK); error = -EFSCORRUPTED; goto out_unlock; } From patchwork Sun Nov 3 22:25:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 11224777 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 16B741390 for ; Sun, 3 Nov 2019 22:25:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E1C1921D71 for ; Sun, 3 Nov 2019 22:25:15 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="Xu+jFeN+" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727965AbfKCWZP (ORCPT ); Sun, 3 Nov 2019 17:25:15 -0500 Received: from userp2120.oracle.com ([156.151.31.85]:44398 "EHLO userp2120.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727503AbfKCWZP (ORCPT ); Sun, 3 Nov 2019 17:25:15 -0500 Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MODWp061235 for ; Sun, 3 Nov 2019 22:25:13 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=subject : from : to : cc : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=corp-2019-08-05; bh=Jqfkyx3N1SBWixGWlKQqc5BgVAhIJbEASLkuzy63fpk=; b=Xu+jFeN+ReGdJAkdpuKch9qmr9GecfKXXKbX/ymN9z0+tQBSOViYFWZl/t/mzdTZ786F 1ilP9q40nc1mwv7i7Z6lAvqTpFlw/0nj6HJYNcnHAZ46NXjUIejbhquzaox8gEzDsD4S BqE2MfB4NHbJq9gLOtp+yiHc3/qXuOcmB+1JCWUEaUKQPkOR49bfiB7S6hp3m0OIeG0l WZ1dFxsDu2uoD9A2/6Gy5rp634ZrJLN2qJzeszb5qp4RC5wmNlq79YtiURSMgydOhCU0 gkQ775EQsy7nOuRh6iM1nuERIYAlAER/MMDXIqBrhd+Nxvvg5HLmhC9qpCYt+wGwx2OB gg== Received: from userp3030.oracle.com (userp3030.oracle.com [156.151.31.80]) by userp2120.oracle.com with ESMTP id 2w12eqv05v-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:25:12 +0000 Received: from pps.filterd (userp3030.oracle.com [127.0.0.1]) by userp3030.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MNKHn072701 for ; Sun, 3 Nov 2019 22:25:12 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userp3030.oracle.com with ESMTP id 2w1k8tmtkw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:25:11 +0000 Received: from abhmp0004.oracle.com (abhmp0004.oracle.com [141.146.116.10]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id xA3MPBwO007488 for ; Sun, 3 Nov 2019 22:25:11 GMT Received: from localhost (/67.169.218.210) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sun, 03 Nov 2019 14:25:10 -0800 Subject: [PATCH 04/10] xfs: report btree block corruption errors to the health system From: "Darrick J. Wong" To: darrick.wong@oracle.com Cc: linux-xfs@vger.kernel.org Date: Sun, 03 Nov 2019 14:25:09 -0800 Message-ID: <157281990960.4152102.11682866870966346595.stgit@magnolia> In-Reply-To: <157281988489.4152102.1632857939932700344.stgit@magnolia> References: <157281988489.4152102.1632857939932700344.stgit@magnolia> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=3 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=3 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Whenever we encounter corrupt btree blocks, we should report that to the health monitoring system for later reporting. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc.c | 1 + fs/xfs/libxfs/xfs_bmap.c | 7 +++++++ fs/xfs/libxfs/xfs_btree.c | 13 +++++++++++++ fs/xfs/libxfs/xfs_health.h | 2 ++ fs/xfs/libxfs/xfs_ialloc.c | 1 + fs/xfs/libxfs/xfs_refcount.c | 3 +++ fs/xfs/libxfs/xfs_rmap.c | 14 +++++++++++--- fs/xfs/libxfs/xfs_rmap.h | 2 +- fs/xfs/scrub/rmap.c | 2 +- fs/xfs/xfs_health.c | 39 +++++++++++++++++++++++++++++++++++++++ 10 files changed, 79 insertions(+), 5 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 72cfe243d58d..742ad359da6b 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -261,6 +261,7 @@ xfs_alloc_get_rec( cur->bc_btnum == XFS_BTNUM_BNO ? "Block" : "Size", agno); xfs_warn(mp, "start block 0x%x block count 0x%x", *bno, *len); + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; } diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 13523be72b8a..f3a6598d364a 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -369,6 +369,8 @@ xfs_bmap_check_leaf_extents( error = xfs_btree_read_bufl(mp, NULL, bno, &bp, XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops); + if (xfs_metadata_is_sick(error)) + xfs_btree_mark_sick(cur); if (error) goto error_norelse; } @@ -455,6 +457,8 @@ xfs_bmap_check_leaf_extents( error = xfs_btree_read_bufl(mp, NULL, bno, &bp, XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops); + if (xfs_metadata_is_sick(error)) + xfs_btree_mark_sick(cur); if (error) goto error_norelse; } @@ -619,6 +623,8 @@ xfs_bmap_btree_to_extents( #endif error = xfs_btree_read_bufl(mp, tp, cbno, &cbp, XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops); + if (xfs_metadata_is_sick(error)) + xfs_btree_mark_sick(cur); if (error) return error; cblock = XFS_BUF_TO_BLOCK(cbp); @@ -5993,6 +5999,7 @@ xfs_bmap_insert_extents( if (XFS_CORRUPT_ON(mp, stop_fsb >= got.br_startoff + got.br_blockcount)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto del_cursor; } diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 94404d8555f0..fee1dad5eab9 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -20,6 +20,7 @@ #include "xfs_trace.h" #include "xfs_alloc.h" #include "xfs_log.h" +#include "xfs_health.h" /* * Cursor allocation zone. @@ -109,6 +110,7 @@ xfs_btree_check_lblock( XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK)) { if (bp) trace_xfs_btree_corrupt(bp, _RET_IP_); + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; } return 0; @@ -172,6 +174,7 @@ xfs_btree_check_sblock( XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_SBLOCK)) { if (bp) trace_xfs_btree_corrupt(bp, _RET_IP_); + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; } return 0; @@ -247,6 +250,7 @@ xfs_btree_check_ptr( level, index); } + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; } @@ -426,6 +430,8 @@ xfs_btree_dup_cursor( XFS_BUF_ADDR(bp), mp->m_bsize, 0, &bp, cur->bc_ops->buf_ops); + if (xfs_metadata_is_sick(error)) + xfs_btree_mark_sick(new); if (error) { xfs_btree_del_cursor(new, error); *ncur = NULL; @@ -1325,6 +1331,8 @@ xfs_btree_read_buf_block( error = xfs_trans_read_buf(mp, cur->bc_tp, mp->m_ddev_targp, d, mp->m_bsize, flags, bpp, cur->bc_ops->buf_ops); + if (xfs_metadata_is_sick(error)) + xfs_btree_mark_sick(cur); if (error) return error; @@ -1635,6 +1643,7 @@ xfs_btree_increment( if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) goto out0; ASSERT(0); + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } @@ -1728,6 +1737,7 @@ xfs_btree_decrement( if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) goto out0; ASSERT(0); + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } @@ -1820,6 +1830,7 @@ xfs_btree_lookup_get_block( *blkp = NULL; xfs_buf_corruption_error(bp); xfs_trans_brelse(cur->bc_tp, bp); + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; } @@ -1867,6 +1878,7 @@ xfs_btree_lookup( /* No such thing as a zero-level tree. */ if (XFS_CORRUPT_ON(cur->bc_mp, cur->bc_nlevels == 0)) { + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; } @@ -1911,6 +1923,7 @@ xfs_btree_lookup( XFS_ERRLEVEL_LOW, cur->bc_mp, block, sizeof(*block)); + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; } diff --git a/fs/xfs/libxfs/xfs_health.h b/fs/xfs/libxfs/xfs_health.h index 25b61180b562..2049419e9555 100644 --- a/fs/xfs/libxfs/xfs_health.h +++ b/fs/xfs/libxfs/xfs_health.h @@ -37,6 +37,7 @@ struct xfs_mount; struct xfs_perag; struct xfs_inode; struct xfs_fsop_geom; +struct xfs_btree_cur; /* Observable health issues for metadata spanning the entire filesystem. */ #define XFS_SICK_FS_COUNTERS (1 << 0) /* summary counters */ @@ -139,6 +140,7 @@ void xfs_inode_measure_sickness(struct xfs_inode *ip, unsigned int *sick, void xfs_health_unmount(struct xfs_mount *mp); void xfs_bmap_mark_sick(struct xfs_inode *ip, int whichfork); +void xfs_btree_mark_sick(struct xfs_btree_cur *cur); /* Now some helpers. */ diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 57da33556e9f..20d539923b2f 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -143,6 +143,7 @@ xfs_inobt_get_rec( "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); + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; } diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index 26ab2c629c1f..75c4f45e1221 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -22,6 +22,7 @@ #include "xfs_bit.h" #include "xfs_refcount.h" #include "xfs_rmap.h" +#include "xfs_health.h" /* Allowable refcount adjustment amounts. */ enum xfs_refc_adjust_op { @@ -153,6 +154,7 @@ xfs_refcount_get_rec( xfs_warn(mp, "Start block 0x%x, block count 0x%x, references 0x%x", irec->rc_startblock, irec->rc_blockcount, irec->rc_refcount); + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; } @@ -1672,6 +1674,7 @@ xfs_refcount_recover_extent( if (XFS_CORRUPT_ON(cur->bc_mp, be32_to_cpu(rec->refc.rc_refcount) != 1)) { + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; } diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index 03ce3d6f4c87..ac579cdcb885 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -21,6 +21,7 @@ #include "xfs_errortag.h" #include "xfs_error.h" #include "xfs_inode.h" +#include "xfs_health.h" /* * Lookup the first record less than or equal to [bno, len, owner, offset] @@ -177,14 +178,20 @@ xfs_rmap_delete( /* Convert an internal btree record to an rmap record. */ int xfs_rmap_btrec_to_irec( + struct xfs_btree_cur *cur, union xfs_btree_rec *rec, struct xfs_rmap_irec *irec) { + int error; + irec->rm_startblock = be32_to_cpu(rec->rmap.rm_startblock); irec->rm_blockcount = be32_to_cpu(rec->rmap.rm_blockcount); irec->rm_owner = be64_to_cpu(rec->rmap.rm_owner); - return xfs_rmap_irec_offset_unpack(be64_to_cpu(rec->rmap.rm_offset), + error = xfs_rmap_irec_offset_unpack(be64_to_cpu(rec->rmap.rm_offset), irec); + if (xfs_metadata_is_sick(error)) + xfs_btree_mark_sick(cur); + return error; } /* @@ -205,7 +212,7 @@ xfs_rmap_get_rec( if (error || !*stat) return error; - if (xfs_rmap_btrec_to_irec(rec, irec)) + if (xfs_rmap_btrec_to_irec(cur, rec, irec)) goto out_bad_rec; if (irec->rm_blockcount == 0) @@ -241,6 +248,7 @@ xfs_rmap_get_rec( "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); + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; } @@ -2278,7 +2286,7 @@ xfs_rmap_query_range_helper( struct xfs_rmap_irec irec; int error; - error = xfs_rmap_btrec_to_irec(rec, &irec); + error = xfs_rmap_btrec_to_irec(cur, rec, &irec); if (error) return error; return query->fn(cur, &irec, query->priv); diff --git a/fs/xfs/libxfs/xfs_rmap.h b/fs/xfs/libxfs/xfs_rmap.h index abe633403fd1..e756989d0da5 100644 --- a/fs/xfs/libxfs/xfs_rmap.h +++ b/fs/xfs/libxfs/xfs_rmap.h @@ -190,7 +190,7 @@ int xfs_rmap_lookup_le_range(struct xfs_btree_cur *cur, xfs_agblock_t bno, int xfs_rmap_compare(const struct xfs_rmap_irec *a, const struct xfs_rmap_irec *b); union xfs_btree_rec; -int xfs_rmap_btrec_to_irec(union xfs_btree_rec *rec, +int xfs_rmap_btrec_to_irec(struct xfs_btree_cur *cur, union xfs_btree_rec *rec, struct xfs_rmap_irec *irec); int xfs_rmap_has_record(struct xfs_btree_cur *cur, xfs_agblock_t bno, xfs_extlen_t len, bool *exists); diff --git a/fs/xfs/scrub/rmap.c b/fs/xfs/scrub/rmap.c index 8d4cefd761c1..eb92ccb67a98 100644 --- a/fs/xfs/scrub/rmap.c +++ b/fs/xfs/scrub/rmap.c @@ -99,7 +99,7 @@ xchk_rmapbt_rec( bool is_attr; int error; - error = xfs_rmap_btrec_to_irec(rec, &irec); + error = xfs_rmap_btrec_to_irec(bs->cur, rec, &irec); if (!xchk_btree_process_error(bs->sc, bs->cur, 0, &error)) goto out; diff --git a/fs/xfs/xfs_health.c b/fs/xfs/xfs_health.c index 5e5de5338476..1f09027c55ad 100644 --- a/fs/xfs/xfs_health.c +++ b/fs/xfs/xfs_health.c @@ -14,6 +14,7 @@ #include "xfs_inode.h" #include "xfs_trace.h" #include "xfs_health.h" +#include "xfs_btree.h" /* * Warn about metadata corruption that we detected but haven't fixed, and @@ -478,3 +479,41 @@ xfs_bmap_mark_sick( xfs_inode_mark_sick(ip, mask); } + +/* Record observations of btree corruption with the health tracking system. */ +void +xfs_btree_mark_sick( + struct xfs_btree_cur *cur) +{ + unsigned int mask; + + switch (cur->bc_btnum) { + case XFS_BTNUM_BMAP: + xfs_bmap_mark_sick(cur->bc_private.b.ip, + cur->bc_private.b.whichfork); + return; + case XFS_BTNUM_BNO: + mask = XFS_SICK_AG_BNOBT; + break; + case XFS_BTNUM_CNT: + mask = XFS_SICK_AG_CNTBT; + break; + case XFS_BTNUM_INO: + mask = XFS_SICK_AG_INOBT; + break; + case XFS_BTNUM_FINO: + mask = XFS_SICK_AG_FINOBT; + break; + case XFS_BTNUM_RMAP: + mask = XFS_SICK_AG_RMAPBT; + break; + case XFS_BTNUM_REFC: + mask = XFS_SICK_AG_REFCNTBT; + break; + default: + ASSERT(0); + return; + } + + xfs_agno_mark_sick(cur->bc_mp, cur->bc_private.a.agno, mask); +} From patchwork Sun Nov 3 22:25:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 11224779 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5FB851390 for ; Sun, 3 Nov 2019 22:25:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2A31C21D71 for ; Sun, 3 Nov 2019 22:25:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="qgpwOwVJ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727969AbfKCWZV (ORCPT ); Sun, 3 Nov 2019 17:25:21 -0500 Received: from aserp2120.oracle.com ([141.146.126.78]:39936 "EHLO aserp2120.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727503AbfKCWZV (ORCPT ); Sun, 3 Nov 2019 17:25:21 -0500 Received: from pps.filterd (aserp2120.oracle.com [127.0.0.1]) by aserp2120.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MOGSu073209 for ; Sun, 3 Nov 2019 22:25:18 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=subject : from : to : cc : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=corp-2019-08-05; bh=nfBxameV9vdAGzCjM0VDdRhyhIRDZIBvT5NdcnLcxn4=; b=qgpwOwVJRxbZ0mZswDX3LgRiA9hR7EO5qtwZm7e8nZFxISHimnnj6ajpOsPY2FasEK56 6Cnu0csnY/Rhq4YVpTQFO81X303G4O18FI6O+TfdJCzs/P7pX+1S0jRHfHcya9h2snST YnUoI/SLQReObpvzgzylsfY+8Oy3Oum9NwYJeGe55pwyeFvdp3PpWOTHylpqsfwngfZw UQEyfHye0mkhG0FOgN4IJM2/YwyQWlbD1oF8laQZfJwug4HzZtg3E5JSOcN/+i0rHPcV 3wbaGxs1fTSmdD+ASWGWX/SfX24fWszNvmr1YnwH1DFKXTOpACVa74XAfdeTB6hNVh+M ag== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by aserp2120.oracle.com with ESMTP id 2w11rpm492-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:25:18 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MOAUN071436 for ; Sun, 3 Nov 2019 22:25:18 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserp3020.oracle.com with ESMTP id 2w1ka8e7jn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:25:17 +0000 Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by aserv0121.oracle.com (8.14.4/8.13.8) with ESMTP id xA3MPH2w032413 for ; Sun, 3 Nov 2019 22:25:17 GMT Received: from localhost (/67.169.218.210) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sun, 03 Nov 2019 14:25:17 -0800 Subject: [PATCH 05/10] xfs: report dir/attr block corruption errors to the health system From: "Darrick J. Wong" To: darrick.wong@oracle.com Cc: linux-xfs@vger.kernel.org Date: Sun, 03 Nov 2019 14:25:15 -0800 Message-ID: <157281991584.4152102.5773934835175995862.stgit@magnolia> In-Reply-To: <157281988489.4152102.1632857939932700344.stgit@magnolia> References: <157281988489.4152102.1632857939932700344.stgit@magnolia> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=3 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=3 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Whenever we encounter corrupt directory or extended attribute blocks, we should report that to the health monitoring system for later reporting. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr_leaf.c | 5 ++++- fs/xfs/libxfs/xfs_attr_remote.c | 27 ++++++++++++++++----------- fs/xfs/libxfs/xfs_da_btree.c | 20 ++++++++++++++++++++ fs/xfs/libxfs/xfs_dir2.c | 2 ++ fs/xfs/libxfs/xfs_dir2_data.c | 2 ++ fs/xfs/libxfs/xfs_dir2_leaf.c | 3 +++ fs/xfs/libxfs/xfs_dir2_node.c | 7 +++++++ fs/xfs/libxfs/xfs_health.h | 3 +++ fs/xfs/xfs_attr_inactive.c | 4 ++++ fs/xfs/xfs_attr_list.c | 13 +++++++++++-- fs/xfs/xfs_dir2_readdir.c | 6 +++++- fs/xfs/xfs_health.c | 39 +++++++++++++++++++++++++++++++++++++++ 12 files changed, 116 insertions(+), 15 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index dca8840496ea..78c2bd639fc6 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -27,7 +27,7 @@ #include "xfs_buf_item.h" #include "xfs_dir2.h" #include "xfs_log.h" - +#include "xfs_health.h" /* * xfs_attr_leaf.c @@ -2348,6 +2348,7 @@ xfs_attr3_leaf_lookup_int( entries = xfs_attr3_leaf_entryp(leaf); if (ichdr.count >= args->geo->blksize / 8) { xfs_buf_corruption_error(bp); + xfs_da_mark_sick(args); return -EFSCORRUPTED; } @@ -2367,10 +2368,12 @@ xfs_attr3_leaf_lookup_int( } if (!(probe >= 0 && (!ichdr.count || probe < ichdr.count))) { xfs_buf_corruption_error(bp); + xfs_da_mark_sick(args); return -EFSCORRUPTED; } if (!(span <= 4 || be32_to_cpu(entry->hashval) == hashval)) { xfs_buf_corruption_error(bp); + xfs_da_mark_sick(args); return -EFSCORRUPTED; } diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index 3e39b7d40f25..0d6404fd5f14 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -21,6 +21,7 @@ #include "xfs_attr.h" #include "xfs_trace.h" #include "xfs_error.h" +#include "xfs_health.h" #define ATTR_RMTVALUE_MAPSIZE 1 /* # of map entries at once */ @@ -260,17 +261,18 @@ xfs_attr3_rmt_hdr_set( */ STATIC int xfs_attr_rmtval_copyout( - struct xfs_mount *mp, - struct xfs_buf *bp, - xfs_ino_t ino, - int *offset, - int *valuelen, - uint8_t **dst) + struct xfs_mount *mp, + struct xfs_buf *bp, + struct xfs_inode *dp, + int *offset, + int *valuelen, + uint8_t **dst) { - char *src = bp->b_addr; - xfs_daddr_t bno = bp->b_bn; - int len = BBTOB(bp->b_length); - int blksize = mp->m_attr_geo->blksize; + char *src = bp->b_addr; + xfs_ino_t ino = dp->i_ino; + xfs_daddr_t bno = bp->b_bn; + int len = BBTOB(bp->b_length); + int blksize = mp->m_attr_geo->blksize; ASSERT(len >= blksize); @@ -286,6 +288,7 @@ xfs_attr_rmtval_copyout( xfs_alert(mp, "remote attribute header mismatch bno/off/len/owner (0x%llx/0x%x/Ox%x/0x%llx)", bno, *offset, byte_cnt, ino); + xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK); return -EFSCORRUPTED; } hdr_size = sizeof(struct xfs_attr3_rmt_hdr); @@ -404,10 +407,12 @@ xfs_attr_rmtval_get( mp->m_ddev_targp, dblkno, dblkcnt, 0, &bp, &xfs_attr3_rmt_buf_ops); + if (xfs_metadata_is_sick(error)) + xfs_da_mark_sick(args); if (error) return error; - error = xfs_attr_rmtval_copyout(mp, bp, args->dp->i_ino, + error = xfs_attr_rmtval_copyout(mp, bp, args->dp, &offset, &valuelen, &dst); xfs_trans_brelse(args->trans, bp); diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 36fc8ffc06b1..c641bcbcb2ac 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -22,6 +22,7 @@ #include "xfs_trace.h" #include "xfs_buf_item.h" #include "xfs_log.h" +#include "xfs_health.h" /* * xfs_da_btree.c @@ -310,6 +311,7 @@ xfs_da3_node_read( tp->t_mountp, info, sizeof(*info)); xfs_trans_brelse(tp, *bpp); *bpp = NULL; + xfs_dirattr_mark_sick(dp, which_fork); return -EFSCORRUPTED; } xfs_trans_buf_set_type(tp, *bpp, type); @@ -505,6 +507,7 @@ xfs_da3_split( if (node->hdr.info.forw) { if (be32_to_cpu(node->hdr.info.forw) != addblk->blkno) { xfs_buf_corruption_error(oldblk->bp); + xfs_da_mark_sick(state->args); error = -EFSCORRUPTED; goto out; } @@ -518,6 +521,7 @@ xfs_da3_split( if (node->hdr.info.back) { if (be32_to_cpu(node->hdr.info.back) != addblk->blkno) { xfs_buf_corruption_error(oldblk->bp); + xfs_da_mark_sick(state->args); error = -EFSCORRUPTED; goto out; } @@ -1545,6 +1549,7 @@ xfs_da3_node_lookup_int( if (magic != XFS_DA_NODE_MAGIC && magic != XFS_DA3_NODE_MAGIC) { xfs_buf_corruption_error(blk->bp); + xfs_da_mark_sick(args); return -EFSCORRUPTED; } @@ -1560,6 +1565,7 @@ xfs_da3_node_lookup_int( /* Tree taller than we can handle; bail out! */ if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) { xfs_buf_corruption_error(blk->bp); + xfs_da_mark_sick(args); return -EFSCORRUPTED; } @@ -1568,6 +1574,7 @@ xfs_da3_node_lookup_int( expected_level = nodehdr.level - 1; else if (expected_level != nodehdr.level) { xfs_buf_corruption_error(blk->bp); + xfs_da_mark_sick(args); return -EFSCORRUPTED; } else expected_level--; @@ -1620,11 +1627,13 @@ xfs_da3_node_lookup_int( /* We can't point back to the root. */ if (XFS_CORRUPT_ON(dp->i_mount, blkno == args->geo->leafblk)) { + xfs_da_mark_sick(args); return -EFSCORRUPTED; } } if (XFS_CORRUPT_ON(dp->i_mount, expected_level != 0)) { + xfs_da_mark_sick(args); return -EFSCORRUPTED; } @@ -1644,6 +1653,7 @@ xfs_da3_node_lookup_int( args->blkno = blk->blkno; } else { ASSERT(0); + xfs_da_mark_sick(args); return -EFSCORRUPTED; } if (((retval == -ENOENT) || (retval == -ENOATTR)) && @@ -2223,6 +2233,7 @@ xfs_da3_swap_lastblock( if (error) return error; if (XFS_CORRUPT_ON(mp, lastoff == 0)) { + xfs_da_mark_sick(args); return -EFSCORRUPTED; } /* @@ -2272,6 +2283,7 @@ xfs_da3_swap_lastblock( if (XFS_CORRUPT_ON(mp, be32_to_cpu(sib_info->forw) != last_blkno || sib_info->magic != dead_info->magic)) { + xfs_da_mark_sick(args); error = -EFSCORRUPTED; goto done; } @@ -2292,6 +2304,7 @@ xfs_da3_swap_lastblock( if (XFS_CORRUPT_ON(mp, be32_to_cpu(sib_info->back) != last_blkno || sib_info->magic != dead_info->magic)) { + xfs_da_mark_sick(args); error = -EFSCORRUPTED; goto done; } @@ -2314,6 +2327,7 @@ xfs_da3_swap_lastblock( dp->d_ops->node_hdr_from_disk(&par_hdr, par_node); if (XFS_CORRUPT_ON(mp, level >= 0 && level != par_hdr.level + 1)) { + xfs_da_mark_sick(args); error = -EFSCORRUPTED; goto done; } @@ -2325,6 +2339,7 @@ xfs_da3_swap_lastblock( entno++) continue; if (XFS_CORRUPT_ON(mp, entno == par_hdr.count)) { + xfs_da_mark_sick(args); error = -EFSCORRUPTED; goto done; } @@ -2350,6 +2365,7 @@ xfs_da3_swap_lastblock( xfs_trans_brelse(tp, par_buf); par_buf = NULL; if (XFS_CORRUPT_ON(mp, par_blkno == 0)) { + xfs_da_mark_sick(args); error = -EFSCORRUPTED; goto done; } @@ -2359,6 +2375,7 @@ xfs_da3_swap_lastblock( par_node = par_buf->b_addr; dp->d_ops->node_hdr_from_disk(&par_hdr, par_node); if (XFS_CORRUPT_ON(mp, par_hdr.level != level)) { + xfs_da_mark_sick(args); error = -EFSCORRUPTED; goto done; } @@ -2576,6 +2593,7 @@ xfs_dabuf_map( irecs[i].br_state); } } + xfs_dirattr_mark_sick(dp, whichfork); error = -EFSCORRUPTED; goto out; } @@ -2668,6 +2686,8 @@ xfs_da_read_buf( error = xfs_trans_read_buf_map(dp->i_mount, trans, dp->i_mount->m_ddev_targp, mapp, nmap, 0, &bp, ops); + if (xfs_metadata_is_sick(error)) + xfs_dirattr_mark_sick(dp, whichfork); if (error) goto out_free; diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 9d4596b52b72..f05a2f0124dc 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -18,6 +18,7 @@ #include "xfs_errortag.h" #include "xfs_error.h" #include "xfs_trace.h" +#include "xfs_health.h" struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2, XFS_DIR3_FT_DIR }; @@ -602,6 +603,7 @@ xfs_dir2_isblock( rval = XFS_FSB_TO_B(args->dp->i_mount, last) == args->geo->blksize; if (XFS_CORRUPT_ON(args->dp->i_mount, rval != 0 && args->dp->i_d.di_size != args->geo->blksize)) { + xfs_da_mark_sick(args); return -EFSCORRUPTED; } *vp = rval; diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index 2c79be4c3153..9876c34c18c0 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c @@ -17,6 +17,7 @@ #include "xfs_trans.h" #include "xfs_buf_item.h" #include "xfs_log.h" +#include "xfs_health.h" static xfs_failaddr_t xfs_dir2_data_freefind_verify( struct xfs_dir2_data_hdr *hdr, struct xfs_dir2_data_free *bf, @@ -1145,6 +1146,7 @@ xfs_dir2_data_use_free( corrupt: xfs_corruption_error(__func__, XFS_ERRLEVEL_LOW, args->dp->i_mount, hdr, sizeof(*hdr), __FILE__, __LINE__, fa); + xfs_da_mark_sick(args); return -EFSCORRUPTED; } diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index 388b5da12228..a2e192a55e58 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -19,6 +19,7 @@ #include "xfs_trace.h" #include "xfs_trans.h" #include "xfs_buf_item.h" +#include "xfs_health.h" /* * Local function declarations. @@ -1345,8 +1346,10 @@ xfs_dir2_leaf_removename( bestsp = xfs_dir2_leaf_bests_p(ltp); if (be16_to_cpu(bestsp[db]) != oldbest) { xfs_buf_corruption_error(lbp); + xfs_da_mark_sick(args); return -EFSCORRUPTED; } + /* * Mark the former data entry unused. */ diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index d58cfbe29316..f9c20af0d803 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -20,6 +20,7 @@ #include "xfs_trans.h" #include "xfs_buf_item.h" #include "xfs_log.h" +#include "xfs_health.h" /* * Function declarations. @@ -210,6 +211,7 @@ __xfs_dir3_free_read( if (fa) { xfs_verifier_error(*bpp, -EFSCORRUPTED, fa); xfs_trans_brelse(tp, *bpp); + xfs_dirattr_mark_sick(dp, XFS_DATA_FORK); return -EFSCORRUPTED; } @@ -375,6 +377,7 @@ xfs_dir2_leaf_to_node( if (be32_to_cpu(ltp->bestcount) > (uint)dp->i_d.di_size / args->geo->blksize) { xfs_buf_corruption_error(lbp); + xfs_da_mark_sick(args); return -EFSCORRUPTED; } @@ -449,6 +452,7 @@ xfs_dir2_leafn_add( */ if (index < 0) { xfs_buf_corruption_error(bp); + xfs_da_mark_sick(args); return -EFSCORRUPTED; } @@ -674,6 +678,7 @@ xfs_dir2_leafn_lookup_for_addname( bests[fi] == cpu_to_be16(NULLDATAOFF))) { if (curfdb != newfdb) xfs_trans_brelse(tp, curbp); + xfs_da_mark_sick(args); return -EFSCORRUPTED; } curfdb = newfdb; @@ -744,6 +749,7 @@ xfs_dir2_leafn_lookup_for_entry( xfs_dir3_leaf_check(dp, bp); if (leafhdr.count <= 0) { xfs_buf_corruption_error(bp); + xfs_da_mark_sick(args); return -EFSCORRUPTED; } @@ -1685,6 +1691,7 @@ xfs_dir2_node_add_datablk( } else { xfs_alert(mp, " ... fblk is NULL"); } + xfs_da_mark_sick(args); return -EFSCORRUPTED; } diff --git a/fs/xfs/libxfs/xfs_health.h b/fs/xfs/libxfs/xfs_health.h index 2049419e9555..d9404cd3d09b 100644 --- a/fs/xfs/libxfs/xfs_health.h +++ b/fs/xfs/libxfs/xfs_health.h @@ -38,6 +38,7 @@ struct xfs_perag; struct xfs_inode; struct xfs_fsop_geom; struct xfs_btree_cur; +struct xfs_da_args; /* Observable health issues for metadata spanning the entire filesystem. */ #define XFS_SICK_FS_COUNTERS (1 << 0) /* summary counters */ @@ -141,6 +142,8 @@ void xfs_inode_measure_sickness(struct xfs_inode *ip, unsigned int *sick, void xfs_health_unmount(struct xfs_mount *mp); void xfs_bmap_mark_sick(struct xfs_inode *ip, int whichfork); void xfs_btree_mark_sick(struct xfs_btree_cur *cur); +void xfs_dirattr_mark_sick(struct xfs_inode *ip, int whichfork); +void xfs_da_mark_sick(struct xfs_da_args *args); /* Now some helpers. */ diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c index 43ae392992e7..c2f885173343 100644 --- a/fs/xfs/xfs_attr_inactive.c +++ b/fs/xfs/xfs_attr_inactive.c @@ -23,6 +23,7 @@ #include "xfs_quota.h" #include "xfs_dir2.h" #include "xfs_error.h" +#include "xfs_health.h" /* * Look at all the extents for this logical region, @@ -211,6 +212,7 @@ xfs_attr3_node_inactive( if (level > XFS_DA_NODE_MAXDEPTH) { xfs_trans_brelse(*trans, bp); /* no locks for later trans */ xfs_buf_corruption_error(bp); + xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK); return -EFSCORRUPTED; } @@ -260,6 +262,7 @@ xfs_attr3_node_inactive( error = xfs_attr3_leaf_inactive(trans, dp, child_bp); break; default: + xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK); xfs_buf_corruption_error(child_bp); xfs_trans_brelse(*trans, child_bp); error = -EFSCORRUPTED; @@ -344,6 +347,7 @@ xfs_attr3_root_inactive( error = xfs_attr3_leaf_inactive(trans, dp, bp); break; default: + xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK); error = -EFSCORRUPTED; xfs_buf_corruption_error(bp); xfs_trans_brelse(*trans, bp); diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c index 01cbc1950cfd..25d926a44766 100644 --- a/fs/xfs/xfs_attr_list.c +++ b/fs/xfs/xfs_attr_list.c @@ -21,6 +21,7 @@ #include "xfs_error.h" #include "xfs_trace.h" #include "xfs_dir2.h" +#include "xfs_health.h" STATIC int xfs_attr_shortform_compare(const void *a, const void *b) @@ -87,8 +88,10 @@ xfs_attr_shortform_list( (dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) { for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { if (XFS_CORRUPT_ON(context->dp->i_mount, - !xfs_attr_namecheck(sfe->nameval, sfe->namelen))) + !xfs_attr_namecheck(sfe->nameval, sfe->namelen))) { + xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK); return -EFSCORRUPTED; + } context->put_listent(context, sfe->flags, sfe->nameval, @@ -130,6 +133,7 @@ xfs_attr_shortform_list( context->dp->i_mount, sfe, sizeof(*sfe)); kmem_free(sbuf); + xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK); return -EFSCORRUPTED; } @@ -179,6 +183,7 @@ xfs_attr_shortform_list( } if (XFS_CORRUPT_ON(context->dp->i_mount, !xfs_attr_namecheck(sbp->name, sbp->namelen))) { + xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK); error = -EFSCORRUPTED; goto out; } @@ -267,6 +272,7 @@ xfs_attr_node_list_lookup( /* We can't point back to the root. */ if (XFS_CORRUPT_ON(mp, cursor->blkno == 0)) { + xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK); return -EFSCORRUPTED; } } @@ -280,6 +286,7 @@ xfs_attr_node_list_lookup( out_corruptbuf: xfs_buf_corruption_error(bp); xfs_trans_brelse(tp, bp); + xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK); return -EFSCORRUPTED; } @@ -470,8 +477,10 @@ xfs_attr3_leaf_list_int( } if (XFS_CORRUPT_ON(context->dp->i_mount, - !xfs_attr_namecheck(name, namelen))) + !xfs_attr_namecheck(name, namelen))) { + xfs_dirattr_mark_sick(context->dp, XFS_ATTR_FORK); return -EFSCORRUPTED; + } context->put_listent(context, entry->flags, name, namelen, valuelen); if (context->seen_enough) diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index a516d83158d1..cbf5ff949e03 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c @@ -18,6 +18,7 @@ #include "xfs_bmap.h" #include "xfs_trans.h" #include "xfs_error.h" +#include "xfs_health.h" /* * Directory file type support functions @@ -117,8 +118,10 @@ xfs_dir2_sf_getdents( filetype = dp->d_ops->sf_get_ftype(sfep); ctx->pos = off & 0x7fffffff; if (XFS_CORRUPT_ON(dp->i_mount, - !xfs_dir2_namecheck(sfep->name, sfep->namelen))) + !xfs_dir2_namecheck(sfep->name, sfep->namelen))) { + xfs_dirattr_mark_sick(dp, XFS_DATA_FORK); return -EFSCORRUPTED; + } if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino, xfs_dir3_get_dtype(dp->i_mount, filetype))) return 0; @@ -466,6 +469,7 @@ xfs_dir2_leaf_getdents( ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff; if (XFS_CORRUPT_ON(dp->i_mount, !xfs_dir2_namecheck(dep->name, dep->namelen))) { + xfs_dirattr_mark_sick(dp, XFS_DATA_FORK); error = -EFSCORRUPTED; break; } diff --git a/fs/xfs/xfs_health.c b/fs/xfs/xfs_health.c index 1f09027c55ad..c1b6e8fb72ec 100644 --- a/fs/xfs/xfs_health.c +++ b/fs/xfs/xfs_health.c @@ -15,6 +15,8 @@ #include "xfs_trace.h" #include "xfs_health.h" #include "xfs_btree.h" +#include "xfs_da_format.h" +#include "xfs_da_btree.h" /* * Warn about metadata corruption that we detected but haven't fixed, and @@ -517,3 +519,40 @@ xfs_btree_mark_sick( xfs_agno_mark_sick(cur->bc_mp, cur->bc_private.a.agno, mask); } + +/* + * Record observations of dir/attr btree corruption with the health tracking + * system. + */ +void +xfs_dirattr_mark_sick( + struct xfs_inode *ip, + int whichfork) +{ + unsigned int mask; + + switch (whichfork) { + case XFS_DATA_FORK: + mask = XFS_SICK_INO_DIR; + break; + case XFS_ATTR_FORK: + mask = XFS_SICK_INO_XATTR; + break; + default: + ASSERT(0); + return; + } + + xfs_inode_mark_sick(ip, mask); +} + +/* + * Record observations of dir/attr btree corruption with the health tracking + * system. + */ +void +xfs_da_mark_sick( + struct xfs_da_args *args) +{ + xfs_dirattr_mark_sick(args->dp, args->whichfork); +} From patchwork Sun Nov 3 22:25:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 11224793 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 652F01390 for ; Sun, 3 Nov 2019 22:27:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 438F621A4A for ; Sun, 3 Nov 2019 22:27:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="ZSYlfbk/" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727842AbfKCW10 (ORCPT ); Sun, 3 Nov 2019 17:27:26 -0500 Received: from aserp2120.oracle.com ([141.146.126.78]:41548 "EHLO aserp2120.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727856AbfKCW10 (ORCPT ); Sun, 3 Nov 2019 17:27:26 -0500 Received: from pps.filterd (aserp2120.oracle.com [127.0.0.1]) by aserp2120.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MOEgt073203 for ; Sun, 3 Nov 2019 22:27:25 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=subject : from : to : cc : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=corp-2019-08-05; bh=gKB2tWUQv+dTW2omRVVQgqVUC6Fr4MfKhk7GLU1LfnA=; b=ZSYlfbk/WmhECl2yvqyMPrLVgfMAnt87+g8ChqFH6ped7O8FRX2mL127SmNU72BItUH9 sDbOh+f1MnQjembtR8hlF/uurVRZ88v/q9qCi76FhLW9gsWK53RKWt51ay63sTIJNb1m /NOfSEmQix2kv+0Bri7oAB3+qYz0cokHV0LAdwk632Ic4zyN3KS1cHH8buuUg8XGF75k CqedqfGqLZVgpg7Iar6txOM6a9HCdy0X0HM998oFecHUOKJmO92HKYpZ8NYdM04oaVeD O9aG0OSvUc7GzeS8SnTE4U+tpqYmR9R5GRrjVE0cd7RhbpxpQE2sND49CPkzhsRIt5uo Vg== Received: from userp3020.oracle.com (userp3020.oracle.com [156.151.31.79]) by aserp2120.oracle.com with ESMTP id 2w11rpm4b4-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:27:24 +0000 Received: from pps.filterd (userp3020.oracle.com [127.0.0.1]) by userp3020.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MOIcc136742 for ; Sun, 3 Nov 2019 22:25:24 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userp3020.oracle.com with ESMTP id 2w1kxc3ntp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:25:24 +0000 Received: from abhmp0003.oracle.com (abhmp0003.oracle.com [141.146.116.9]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id xA3MPNhe005719 for ; Sun, 3 Nov 2019 22:25:23 GMT Received: from localhost (/67.169.218.210) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sun, 03 Nov 2019 14:25:23 -0800 Subject: [PATCH 06/10] xfs: report symlink block corruption errors to the health system From: "Darrick J. Wong" To: darrick.wong@oracle.com Cc: linux-xfs@vger.kernel.org Date: Sun, 03 Nov 2019 14:25:22 -0800 Message-ID: <157281992200.4152102.11858859069139016629.stgit@magnolia> In-Reply-To: <157281988489.4152102.1632857939932700344.stgit@magnolia> References: <157281988489.4152102.1632857939932700344.stgit@magnolia> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=1 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Whenever we encounter corrupt symbolic link blocks, we should report that to the health monitoring system for later reporting. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_iops.c | 2 ++ fs/xfs/xfs_symlink.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index f18b3167b43e..94068de9cae9 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -21,6 +21,7 @@ #include "xfs_dir2.h" #include "xfs_iomap.h" #include "xfs_error.h" +#include "xfs_health.h" #include #include @@ -482,6 +483,7 @@ xfs_vn_get_link_inline( */ link = ip->i_df.if_u1.if_data; if (XFS_CORRUPT_ON(ip->i_mount, !link)) { + xfs_inode_mark_sick(ip, XFS_SICK_INO_SYMLINK); return ERR_PTR(-EFSCORRUPTED); } return link; diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index ed66fd2de327..9fb6e5eb5920 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -20,6 +20,7 @@ #include "xfs_trans_space.h" #include "xfs_trace.h" #include "xfs_trans.h" +#include "xfs_health.h" /* ----- Kernel only functions below ----- */ int @@ -62,6 +63,8 @@ xfs_readlink_bmap_ilocked( xfs_buf_relse(bp); /* bad CRC means corrupted metadata */ + if (xfs_metadata_is_sick(error)) + xfs_inode_mark_sick(ip, XFS_SICK_INO_SYMLINK); if (error == -EFSBADCRC) error = -EFSCORRUPTED; goto out; @@ -74,6 +77,7 @@ xfs_readlink_bmap_ilocked( if (xfs_sb_version_hascrc(&mp->m_sb)) { if (!xfs_symlink_hdr_ok(ip->i_ino, offset, byte_cnt, bp)) { + xfs_inode_mark_sick(ip, XFS_SICK_INO_SYMLINK); error = -EFSCORRUPTED; xfs_alert(mp, "symlink header does not match required off/len/owner (0x%x/Ox%x,0x%llx)", @@ -129,6 +133,7 @@ xfs_readlink( __func__, (unsigned long long) ip->i_ino, (long long) pathlen); ASSERT(0); + xfs_inode_mark_sick(ip, XFS_SICK_INO_SYMLINK); error = -EFSCORRUPTED; goto out; } @@ -501,6 +506,7 @@ xfs_inactive_symlink( __func__, (unsigned long long)ip->i_ino, pathlen); xfs_iunlock(ip, XFS_ILOCK_EXCL); ASSERT(0); + xfs_inode_mark_sick(ip, XFS_SICK_INO_SYMLINK); return -EFSCORRUPTED; } From patchwork Sun Nov 3 22:25:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 11224781 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 02E0116B1 for ; Sun, 3 Nov 2019 22:25:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D513B21D56 for ; Sun, 3 Nov 2019 22:25:33 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="PJN+4BOC" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728027AbfKCWZd (ORCPT ); Sun, 3 Nov 2019 17:25:33 -0500 Received: from userp2120.oracle.com ([156.151.31.85]:44612 "EHLO userp2120.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728012AbfKCWZd (ORCPT ); Sun, 3 Nov 2019 17:25:33 -0500 Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MOFLa061247 for ; Sun, 3 Nov 2019 22:25:31 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=subject : from : to : cc : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=corp-2019-08-05; bh=g0TtpK/mAo8ialJHCyZTGurrBWemTbpISaESBFdXTeU=; b=PJN+4BOCK9RSs7IgygzEUBN1bszlDIYKictZBDNKKwxdodphl4TU/YHEX/X4HYe5usYt OMpRfAGXZlqYB52MnUlnXgT/3e/LoAi0oxmG+lu4gEYjAZXxzAJoExKv1TyNahpwVP55 7JIX5M3K00KLqwk0nQqswHh2cJQ86ZqP+G6ABxIkzHgC4Ew/LRAyFZHcZoFf5tnCwgHC NUGd1h66EF5YAp6xn7UnOfHab+WEYlhezymTRecgh/7wkTdUfO+SXWQSZUXERzap2Fgy rbjilaHqYMkx/0QaJSCI/7gBOBP7vfKnP5eEVbWincdBkRXWsxADrPau2RICcMlSdJuB jg== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by userp2120.oracle.com with ESMTP id 2w12eqv068-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:25:31 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MOAhE071472 for ; Sun, 3 Nov 2019 22:25:30 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserp3020.oracle.com with ESMTP id 2w1ka8e7re-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:25:30 +0000 Received: from abhmp0003.oracle.com (abhmp0003.oracle.com [141.146.116.9]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id xA3MPTu1005732 for ; Sun, 3 Nov 2019 22:25:29 GMT Received: from localhost (/67.169.218.210) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sun, 03 Nov 2019 14:25:29 -0800 Subject: [PATCH 07/10] xfs: report inode corruption errors to the health system From: "Darrick J. Wong" To: darrick.wong@oracle.com Cc: linux-xfs@vger.kernel.org Date: Sun, 03 Nov 2019 14:25:28 -0800 Message-ID: <157281992801.4152102.7357389240554985478.stgit@magnolia> In-Reply-To: <157281988489.4152102.1632857939932700344.stgit@magnolia> References: <157281988489.4152102.1632857939932700344.stgit@magnolia> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=3 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=3 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Whenever we encounter corrupt inode records, we should report that to the health monitoring system for later reporting. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_inode_buf.c | 5 +++++ fs/xfs/libxfs/xfs_inode_fork.c | 8 ++++++++ fs/xfs/xfs_icache.c | 4 ++++ fs/xfs/xfs_inode.c | 2 ++ 4 files changed, 19 insertions(+) diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index 28ab3c5255e1..d4f0c4948750 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -17,6 +17,7 @@ #include "xfs_trans.h" #include "xfs_ialloc.h" #include "xfs_dir2.h" +#include "xfs_health.h" #include @@ -182,6 +183,9 @@ xfs_imap_to_bp( error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno, (int)imap->im_len, buf_flags, &bp, &xfs_inode_buf_ops); + if (xfs_metadata_is_sick(error)) + xfs_agno_mark_sick(mp, xfs_daddr_to_agno(mp, imap->im_blkno), + XFS_SICK_AG_INOBT); if (error) { if (error == -EAGAIN) { ASSERT(buf_flags & XBF_TRYLOCK); @@ -651,6 +655,7 @@ xfs_iread( if (fa) { xfs_inode_verifier_error(ip, -EFSCORRUPTED, "dinode", dip, sizeof(*dip), fa); + xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE); error = -EFSCORRUPTED; goto out_brelse; } diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 15d6f947620f..6698161b581b 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -23,6 +23,7 @@ #include "xfs_da_btree.h" #include "xfs_dir2_priv.h" #include "xfs_attr_leaf.h" +#include "xfs_health.h" kmem_zone_t *xfs_ifork_zone; @@ -77,6 +78,7 @@ xfs_iformat_fork( default: xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip, sizeof(*dip), __this_address); + xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE); return -EFSCORRUPTED; } break; @@ -84,6 +86,7 @@ xfs_iformat_fork( default: xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip, sizeof(*dip), __this_address); + xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE); return -EFSCORRUPTED; } if (error) @@ -116,6 +119,7 @@ xfs_iformat_fork( default: xfs_inode_verifier_error(ip, error, __func__, dip, sizeof(*dip), __this_address); + xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE); error = -EFSCORRUPTED; break; } @@ -189,6 +193,7 @@ xfs_iformat_local( xfs_inode_verifier_error(ip, -EFSCORRUPTED, "xfs_iformat_local", dip, sizeof(*dip), __this_address); + xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE); return -EFSCORRUPTED; } @@ -226,6 +231,7 @@ xfs_iformat_extents( xfs_inode_verifier_error(ip, -EFSCORRUPTED, "xfs_iformat_extents(1)", dip, sizeof(*dip), __this_address); + xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE); return -EFSCORRUPTED; } @@ -245,6 +251,7 @@ xfs_iformat_extents( xfs_inode_verifier_error(ip, -EFSCORRUPTED, "xfs_iformat_extents(2)", dp, sizeof(*dp), fa); + xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE); return -EFSCORRUPTED; } @@ -304,6 +311,7 @@ xfs_iformat_btree( xfs_inode_verifier_error(ip, -EFSCORRUPTED, "xfs_iformat_btree", dfp, size, __this_address); + xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE); return -EFSCORRUPTED; } diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 944add5ff8e0..655d587f3980 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -22,6 +22,7 @@ #include "xfs_dquot_item.h" #include "xfs_dquot.h" #include "xfs_reflink.h" +#include "xfs_health.h" #include @@ -321,6 +322,7 @@ xfs_iget_check_free_state( xfs_warn(ip->i_mount, "Corruption detected! Free inode 0x%llx not marked free! (mode 0x%x)", ip->i_ino, VFS_I(ip)->i_mode); + xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE); return -EFSCORRUPTED; } @@ -328,6 +330,7 @@ xfs_iget_check_free_state( xfs_warn(ip->i_mount, "Corruption detected! Free inode 0x%llx has blocks allocated!", ip->i_ino); + xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE); return -EFSCORRUPTED; } return 0; @@ -511,6 +514,7 @@ xfs_iget_cache_miss( goto out_destroy; if (!xfs_inode_verify_forks(ip)) { + xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE); error = -EFSCORRUPTED; goto out_destroy; } diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index d02246e2fb21..5167b8ceb219 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -3637,6 +3637,7 @@ xfs_iflush_cluster( xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); /* abort the corrupt inode, as it was not attached to the buffer */ + xfs_inode_mark_sick(cip, XFS_SICK_INO_CORE); xfs_iflush_abort(cip, false); kmem_free(cilist); xfs_perag_put(pag); @@ -3934,6 +3935,7 @@ xfs_iflush_int( return 0; corrupt_out: + xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE); return -EFSCORRUPTED; } From patchwork Sun Nov 3 22:25:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 11224783 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A674616B1 for ; Sun, 3 Nov 2019 22:25:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8519F21A4A for ; Sun, 3 Nov 2019 22:25:38 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="WvgBPdQZ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727574AbfKCWZi (ORCPT ); Sun, 3 Nov 2019 17:25:38 -0500 Received: from userp2120.oracle.com ([156.151.31.85]:44672 "EHLO userp2120.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727503AbfKCWZi (ORCPT ); Sun, 3 Nov 2019 17:25:38 -0500 Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MOPaB061296 for ; Sun, 3 Nov 2019 22:25:37 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=subject : from : to : cc : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=corp-2019-08-05; bh=86qQCwctR1pBqb5Y5qZnHa2DkkU0zoOIh5QwHMM2tv0=; b=WvgBPdQZqNAgeGWZ4Mq6TBeWI3UDwwn2SGdF9y34LlcLJOSwiywO2t1TAiLjDGiBnGrk RBxaDkknKA2jx9eSVsv3DWRusi4rOhpXRnSMyLn4EDOBLlw17JnvzZq5UC6PGW7McKkT R0dNtEKNc77tUqlERPSFnt0OTMTP5IMdJWzG4adS9iVHvYv47rmwyTpnxzeXOhOiK+gJ uXkSEVCNMOCd39AQYW1zbdIZk3kR4eGlAh1KqCLDk7WWUyzMAOrAW+/6MfJ75J1Lcp+T 6l2mxXEhtqEgqM1T+j7QOiQSkRVYUGHaUTB/OztBlF52T3a0174Sez+/1XRVS/K2GitC sQ== Received: from userp3030.oracle.com (userp3030.oracle.com [156.151.31.80]) by userp2120.oracle.com with ESMTP id 2w12eqv06c-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:25:36 +0000 Received: from pps.filterd (userp3030.oracle.com [127.0.0.1]) by userp3030.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MNI5B072684 for ; Sun, 3 Nov 2019 22:25:36 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userp3030.oracle.com with ESMTP id 2w1k8tmu2k-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:25:36 +0000 Received: from abhmp0013.oracle.com (abhmp0013.oracle.com [141.146.116.19]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id xA3MPZ3e005739 for ; Sun, 3 Nov 2019 22:25:36 GMT Received: from localhost (/67.169.218.210) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sun, 03 Nov 2019 14:25:35 -0800 Subject: [PATCH 08/10] xfs: report quota block corruption errors to the health system From: "Darrick J. Wong" To: darrick.wong@oracle.com Cc: linux-xfs@vger.kernel.org Date: Sun, 03 Nov 2019 14:25:34 -0800 Message-ID: <157281993417.4152102.1224062505399137675.stgit@magnolia> In-Reply-To: <157281988489.4152102.1632857939932700344.stgit@magnolia> References: <157281988489.4152102.1632857939932700344.stgit@magnolia> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=1 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Whenever we encounter corrupt quota blocks, we should report that to the health monitoring system for later reporting. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_health.h | 1 + fs/xfs/xfs_dquot.c | 6 ++++++ fs/xfs/xfs_health.c | 15 +++++++++++++++ fs/xfs/xfs_qm.c | 3 +++ 4 files changed, 25 insertions(+) diff --git a/fs/xfs/libxfs/xfs_health.h b/fs/xfs/libxfs/xfs_health.h index d9404cd3d09b..69e7d97ed480 100644 --- a/fs/xfs/libxfs/xfs_health.h +++ b/fs/xfs/libxfs/xfs_health.h @@ -144,6 +144,7 @@ void xfs_bmap_mark_sick(struct xfs_inode *ip, int whichfork); void xfs_btree_mark_sick(struct xfs_btree_cur *cur); void xfs_dirattr_mark_sick(struct xfs_inode *ip, int whichfork); void xfs_da_mark_sick(struct xfs_da_args *args); +void xfs_quota_mark_sick(struct xfs_mount *mp, uint dq_flags); /* Now some helpers. */ diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index bcd4247b5014..cfaab8771f7b 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -23,6 +23,7 @@ #include "xfs_trace.h" #include "xfs_log.h" #include "xfs_bmap_btree.h" +#include "xfs_health.h" /* * Lock order: @@ -419,6 +420,8 @@ xfs_dquot_disk_read( error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dqp->q_blkno, mp->m_quotainfo->qi_dqchunklen, 0, &bp, &xfs_dquot_buf_ops); + if (xfs_metadata_is_sick(error)) + xfs_quota_mark_sick(mp, dqp->dq_flags); if (error) { ASSERT(bp == NULL); return error; @@ -1107,6 +1110,8 @@ xfs_qm_dqflush( error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dqp->q_blkno, mp->m_quotainfo->qi_dqchunklen, 0, &bp, &xfs_dquot_buf_ops); + if (xfs_metadata_is_sick(error)) + xfs_quota_mark_sick(mp, dqp->dq_flags); if (error) goto out_unlock; @@ -1126,6 +1131,7 @@ xfs_qm_dqflush( xfs_buf_relse(bp); xfs_dqfunlock(dqp); xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); + xfs_quota_mark_sick(mp, dqp->dq_flags); return -EFSCORRUPTED; } diff --git a/fs/xfs/xfs_health.c b/fs/xfs/xfs_health.c index c1b6e8fb72ec..2d3da765722e 100644 --- a/fs/xfs/xfs_health.c +++ b/fs/xfs/xfs_health.c @@ -17,6 +17,7 @@ #include "xfs_btree.h" #include "xfs_da_format.h" #include "xfs_da_btree.h" +#include "xfs_quota_defs.h" /* * Warn about metadata corruption that we detected but haven't fixed, and @@ -556,3 +557,17 @@ xfs_da_mark_sick( { xfs_dirattr_mark_sick(args->dp, args->whichfork); } + +/* Record observations of quota corruption with the health tracking system. */ +void +xfs_quota_mark_sick( + struct xfs_mount *mp, + uint dq_flags) +{ + if (dq_flags & XFS_DQ_USER) + xfs_fs_mark_sick(mp, XFS_SICK_FS_UQUOTA); + if (dq_flags & XFS_DQ_GROUP) + xfs_fs_mark_sick(mp, XFS_SICK_FS_GQUOTA); + if (dq_flags & XFS_DQ_PROJ) + xfs_fs_mark_sick(mp, XFS_SICK_FS_PQUOTA); +} diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index b51f3f58eea6..d46519a3c1b3 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -23,6 +23,7 @@ #include "xfs_trace.h" #include "xfs_icache.h" #include "xfs_error.h" +#include "xfs_health.h" /* * The global quota manager. There is only one of these for the entire @@ -757,6 +758,7 @@ xfs_qm_qino_alloc( ino = mp->m_sb.sb_gquotino; if (XFS_CORRUPT_ON(mp, mp->m_sb.sb_pquotino != NULLFSINO)) { + xfs_quota_mark_sick(mp, XFS_DQ_PROJ); return -EFSCORRUPTED; } } else if ((flags & XFS_QMOPT_GQUOTA) && @@ -764,6 +766,7 @@ xfs_qm_qino_alloc( ino = mp->m_sb.sb_pquotino; if (XFS_CORRUPT_ON(mp, mp->m_sb.sb_gquotino != NULLFSINO)) { + xfs_quota_mark_sick(mp, XFS_DQ_GROUP); return -EFSCORRUPTED; } } From patchwork Sun Nov 3 22:25:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 11224785 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 50F7F1390 for ; Sun, 3 Nov 2019 22:25:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2EC6321A4A for ; Sun, 3 Nov 2019 22:25:45 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="AYULAQ0x" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727726AbfKCWZo (ORCPT ); Sun, 3 Nov 2019 17:25:44 -0500 Received: from userp2120.oracle.com ([156.151.31.85]:44754 "EHLO userp2120.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727503AbfKCWZo (ORCPT ); Sun, 3 Nov 2019 17:25:44 -0500 Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MODng061232 for ; Sun, 3 Nov 2019 22:25:43 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=subject : from : to : cc : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=corp-2019-08-05; bh=jcj4UqmpMn9lLg8DyCsidPyuxseN3aJTT9h25IvQBfg=; b=AYULAQ0xzveM7FUsQPGFRx5cRoXpE9yyhhGdwmEZpYOPdlfgoRQGESrkRhrS0b4nE1Ky IO1PqTq2CLHYOkyKX6i5V6L5l6DXocckgGLL3YZIy6Ka4YPg8j2rVHjNxKFBmeDQgDHP +TPy4QCsaGMQtHvFejjRzq8o2F3Sn8yPf1N/9bPPuYm4A2FrYCL6g/sdyDK7AY5GBpfV o2/4bNv0qKtAWLzNQtMbeV6GBrUgOdJIDDnzeTmb4KLGpPlSU/AG63K9BT1Gz1WDSuXE TB3nNOkAjmNNiIsLi+7OfOxdEtLDZRxkiDldpvs1tUon2sIOPuGDMvqdvhd7dMCYBZhL 7g== Received: from aserp3030.oracle.com (aserp3030.oracle.com [141.146.126.71]) by userp2120.oracle.com with ESMTP id 2w12eqv06g-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:25:43 +0000 Received: from pps.filterd (aserp3030.oracle.com [127.0.0.1]) by aserp3030.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MONZO026482 for ; Sun, 3 Nov 2019 22:25:42 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserp3030.oracle.com with ESMTP id 2w1kxk9smg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:25:42 +0000 Received: from abhmp0010.oracle.com (abhmp0010.oracle.com [141.146.116.16]) by aserv0121.oracle.com (8.14.4/8.13.8) with ESMTP id xA3MPfH0032537 for ; Sun, 3 Nov 2019 22:25:41 GMT Received: from localhost (/67.169.218.210) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sun, 03 Nov 2019 14:25:41 -0800 Subject: [PATCH 09/10] xfs: report realtime metadata corruption errors to the health system From: "Darrick J. Wong" To: darrick.wong@oracle.com Cc: linux-xfs@vger.kernel.org Date: Sun, 03 Nov 2019 14:25:40 -0800 Message-ID: <157281994032.4152102.16034331329694844957.stgit@magnolia> In-Reply-To: <157281988489.4152102.1632857939932700344.stgit@magnolia> References: <157281988489.4152102.1632857939932700344.stgit@magnolia> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=1 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Whenever we encounter corrupt realtime metadat blocks, we should report that to the health monitoring system for later reporting. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_rtbitmap.c | 6 ++++++ fs/xfs/xfs_rtalloc.c | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index ba8b2edab6c9..1980ebd53407 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -16,6 +16,7 @@ #include "xfs_trans.h" #include "xfs_rtalloc.h" #include "xfs_error.h" +#include "xfs_health.h" /* * Realtime allocator bitmap functions shared with userspace. @@ -71,6 +72,8 @@ xfs_rtbuf_get( return error; if (XFS_CORRUPT_ON(mp, nmap == 0 || !xfs_bmap_is_real_extent(&map))) { + xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY : + XFS_SICK_RT_BITMAP); return -EFSCORRUPTED; } @@ -78,6 +81,9 @@ xfs_rtbuf_get( error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, XFS_FSB_TO_DADDR(mp, map.br_startblock), mp->m_bsize, 0, &bp, &xfs_rtbuf_ops); + if (xfs_metadata_is_sick(error)) + xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY : + XFS_SICK_RT_BITMAP); if (error) return error; diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index d42b5a2047e0..4ec0fead3177 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -18,7 +18,7 @@ #include "xfs_trans_space.h" #include "xfs_icache.h" #include "xfs_rtalloc.h" - +#include "xfs_health.h" /* * Read and return the summary information for a given extent size, @@ -1235,11 +1235,15 @@ xfs_rtmount_inodes( sbp = &mp->m_sb; error = xfs_iget(mp, NULL, sbp->sb_rbmino, 0, 0, &mp->m_rbmip); + if (xfs_metadata_is_sick(error)) + xfs_rt_mark_sick(mp, XFS_SICK_RT_BITMAP); if (error) return error; ASSERT(mp->m_rbmip != NULL); error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, 0, &mp->m_rsumip); + if (xfs_metadata_is_sick(error)) + xfs_rt_mark_sick(mp, XFS_SICK_RT_SUMMARY); if (error) { xfs_irele(mp->m_rbmip); return error; From patchwork Sun Nov 3 22:25:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 11224787 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6EC9116B1 for ; Sun, 3 Nov 2019 22:26:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1C18C21D56 for ; Sun, 3 Nov 2019 22:26:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="qj6vDki6" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728012AbfKCW0A (ORCPT ); Sun, 3 Nov 2019 17:26:00 -0500 Received: from userp2120.oracle.com ([156.151.31.85]:44800 "EHLO userp2120.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727503AbfKCW0A (ORCPT ); Sun, 3 Nov 2019 17:26:00 -0500 Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MODCN061241 for ; Sun, 3 Nov 2019 22:25:50 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=subject : from : to : cc : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=corp-2019-08-05; bh=M8PpgeI99rK67FDjs+qk3GZRqL89+UBAQwGXCj2nW84=; b=qj6vDki6T/gTZHPHDXmtaYnkbCe5oZ7QBDIH7W50DG9oyLoyg8VBknABatvUOsAwCnjT WegLowGoVeMIt/VmyoniQdqhU5U0j7QLQ1vHjQU3ky34dCbM8gW6SlCdOc5tE1iwZqLH f7Oxwm6/TeCUZvCRWWJTt8CpXmzIluP3BngjlQK2MdBVyT/dC2VwBkMT9IEoRAo4TXs7 jTQwNlZx0dWwg/B/GIT7xGp5qNyK6Nhmk+o+OEDqZWO2u9DJiE6fBTHIP0cCWajbVmg0 itErYXFBr+kvP7oNIeBLrlWlJ3ZcDn1x5+lwQ+YhEAasejWKqx5yUnsMzCh0CA/A9C/3 Cg== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by userp2120.oracle.com with ESMTP id 2w12eqv06m-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:25:49 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xA3MOFxp071850 for ; Sun, 3 Nov 2019 22:25:49 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserp3020.oracle.com with ESMTP id 2w1ka8e80e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Sun, 03 Nov 2019 22:25:48 +0000 Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by aserv0121.oracle.com (8.14.4/8.13.8) with ESMTP id xA3MPmC4032545 for ; Sun, 3 Nov 2019 22:25:48 GMT Received: from localhost (/67.169.218.210) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sun, 03 Nov 2019 14:25:47 -0800 Subject: [PATCH 10/10] xfs: report XFS_CORRUPT_ON errors to the health system From: "Darrick J. Wong" To: darrick.wong@oracle.com Cc: linux-xfs@vger.kernel.org Date: Sun, 03 Nov 2019 14:25:46 -0800 Message-ID: <157281994640.4152102.15370774912529137865.stgit@magnolia> In-Reply-To: <157281988489.4152102.1632857939932700344.stgit@magnolia> References: <157281988489.4152102.1632857939932700344.stgit@magnolia> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=3 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9430 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=3 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-1911030234 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Whenever we encounter XFS_CORRUPT_ON failures, we should report that to the health monitoring system for later reporting. I started with this and massaged everything until it built: @@ expression mp, test; @@ - if (XFS_CORRUPT_ON(mp, test)) return -EFSCORRUPTED; + if (XFS_CORRUPT_ON(mp, test)) { xfs_btree_mark_sick(cur); return -EFSCORRUPTED; } @@ expression mp, test; identifier label, error; @@ - if (XFS_CORRUPT_ON(mp, test)) { error = -EFSCORRUPTED; goto label; } + if (XFS_CORRUPT_ON(mp, test)) { xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto label; } Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc.c | 95 +++++++++++++++++++++++++++++++++++------- fs/xfs/libxfs/xfs_bmap.c | 76 +++++++++++++++++++++++++++++++--- fs/xfs/libxfs/xfs_btree.c | 14 ++++++ fs/xfs/libxfs/xfs_ialloc.c | 52 +++++++++++++++++++---- fs/xfs/libxfs/xfs_refcount.c | 30 +++++++++++++ fs/xfs/libxfs/xfs_rmap.c | 72 +++++++++++++++++++++++++++++++- fs/xfs/xfs_discard.c | 2 + fs/xfs/xfs_iwalk.c | 4 +- 8 files changed, 312 insertions(+), 33 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 742ad359da6b..6c2f3fb68071 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -454,14 +454,18 @@ xfs_alloc_fixup_trees( if ((error = xfs_alloc_get_rec(cnt_cur, &nfbno1, &nflen1, &i))) return error; if (XFS_CORRUPT_ON(mp, - i != 1 || nfbno1 != fbno || nflen1 != flen)) + i != 1 || nfbno1 != fbno || nflen1 != flen)) { + xfs_btree_mark_sick(cnt_cur); return -EFSCORRUPTED; + } #endif } else { if ((error = xfs_alloc_lookup_eq(cnt_cur, fbno, flen, &i))) return error; - if (XFS_CORRUPT_ON(mp, i != 1)) + if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cnt_cur); return -EFSCORRUPTED; + } } /* * Look up the record in the by-block tree if necessary. @@ -471,14 +475,18 @@ xfs_alloc_fixup_trees( if ((error = xfs_alloc_get_rec(bno_cur, &nfbno1, &nflen1, &i))) return error; if (XFS_CORRUPT_ON(mp, - i != 1 || nfbno1 != fbno || nflen1 != flen)) + i != 1 || nfbno1 != fbno || nflen1 != flen)) { + xfs_btree_mark_sick(bno_cur); return -EFSCORRUPTED; + } #endif } else { if ((error = xfs_alloc_lookup_eq(bno_cur, fbno, flen, &i))) return error; - if (XFS_CORRUPT_ON(mp, i != 1)) + if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bno_cur); return -EFSCORRUPTED; + } } #ifdef DEBUG @@ -490,8 +498,10 @@ xfs_alloc_fixup_trees( cntblock = XFS_BUF_TO_BLOCK(cnt_cur->bc_bufs[0]); if (XFS_CORRUPT_ON(mp, - bnoblock->bb_numrecs != cntblock->bb_numrecs)) + bnoblock->bb_numrecs != cntblock->bb_numrecs)) { + xfs_btree_mark_sick(bno_cur); return -EFSCORRUPTED; + } } #endif @@ -521,30 +531,40 @@ xfs_alloc_fixup_trees( */ if ((error = xfs_btree_delete(cnt_cur, &i))) return error; - if (XFS_CORRUPT_ON(mp, i != 1)) + if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cnt_cur); return -EFSCORRUPTED; + } /* * Add new by-size btree entry(s). */ if (nfbno1 != NULLAGBLOCK) { if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno1, nflen1, &i))) return error; - if (XFS_CORRUPT_ON(mp, i != 0)) + if (XFS_CORRUPT_ON(mp, i != 0)) { + xfs_btree_mark_sick(cnt_cur); return -EFSCORRUPTED; + } if ((error = xfs_btree_insert(cnt_cur, &i))) return error; - if (XFS_CORRUPT_ON(mp, i != 1)) + if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cnt_cur); return -EFSCORRUPTED; + } } if (nfbno2 != NULLAGBLOCK) { if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno2, nflen2, &i))) return error; - if (XFS_CORRUPT_ON(mp, i != 0)) + if (XFS_CORRUPT_ON(mp, i != 0)) { + xfs_btree_mark_sick(cnt_cur); return -EFSCORRUPTED; + } if ((error = xfs_btree_insert(cnt_cur, &i))) return error; - if (XFS_CORRUPT_ON(mp, i != 1)) + if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cnt_cur); return -EFSCORRUPTED; + } } /* * Fix up the by-block btree entry(s). @@ -555,8 +575,10 @@ xfs_alloc_fixup_trees( */ if ((error = xfs_btree_delete(bno_cur, &i))) return error; - if (XFS_CORRUPT_ON(mp, i != 1)) + if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bno_cur); return -EFSCORRUPTED; + } } else { /* * Update the by-block entry to start later|be shorter. @@ -570,12 +592,16 @@ xfs_alloc_fixup_trees( */ if ((error = xfs_alloc_lookup_eq(bno_cur, nfbno2, nflen2, &i))) return error; - if (XFS_CORRUPT_ON(mp, i != 0)) + if (XFS_CORRUPT_ON(mp, i != 0)) { + xfs_btree_mark_sick(bno_cur); return -EFSCORRUPTED; + } if ((error = xfs_btree_insert(bno_cur, &i))) return error; - if (XFS_CORRUPT_ON(mp, i != 1)) + if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bno_cur); return -EFSCORRUPTED; + } } return 0; } @@ -839,8 +865,10 @@ xfs_alloc_cur_check( error = xfs_alloc_get_rec(cur, &bno, &len, &i); if (error) return error; - if (XFS_CORRUPT_ON(args->mp, i != 1)) + if (XFS_CORRUPT_ON(args->mp, i != 1)) { + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; + } /* * Check minlen and deactivate a cntbt cursor if out of acceptable size @@ -1046,6 +1074,7 @@ xfs_alloc_ag_vextent_small( if (error) goto error; if (XFS_CORRUPT_ON(args->mp, i != 1)) { + xfs_btree_mark_sick(ccur); error = -EFSCORRUPTED; goto error; } @@ -1072,6 +1101,7 @@ xfs_alloc_ag_vextent_small( bp = xfs_btree_get_bufs(args->mp, args->tp, args->agno, fbno); if (XFS_CORRUPT_ON(args->mp, !bp)) { + xfs_btree_mark_sick(ccur); error = -EFSCORRUPTED; goto error; } @@ -1081,6 +1111,7 @@ xfs_alloc_ag_vextent_small( *flenp = args->len = 1; if (XFS_CORRUPT_ON(args->mp, fbno >= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length))) { + xfs_btree_mark_sick(ccur); error = -EFSCORRUPTED; goto error; } @@ -1239,6 +1270,7 @@ xfs_alloc_ag_vextent_exact( if (error) goto error0; if (XFS_CORRUPT_ON(args->mp, i != 1)) { + xfs_btree_mark_sick(bno_cur); error = -EFSCORRUPTED; goto error0; } @@ -1577,6 +1609,7 @@ xfs_alloc_ag_vextent_near( if (error) goto out; if (XFS_CORRUPT_ON(args->mp, i != 1)) { + xfs_btree_mark_sick(acur.cnt); error = -EFSCORRUPTED; goto out; } @@ -1705,6 +1738,7 @@ xfs_alloc_ag_vextent_size( if (error) goto error0; if (XFS_CORRUPT_ON(args->mp, i != 1)) { + xfs_btree_mark_sick(cnt_cur); error = -EFSCORRUPTED; goto error0; } @@ -1743,6 +1777,7 @@ xfs_alloc_ag_vextent_size( rlen = XFS_EXTLEN_MIN(args->maxlen, rlen); if (XFS_CORRUPT_ON(args->mp, rlen != 0 && (rlen > flen || rbno + rlen > fbno + flen))) { + xfs_btree_mark_sick(cnt_cur); error = -EFSCORRUPTED; goto error0; } @@ -1765,6 +1800,7 @@ xfs_alloc_ag_vextent_size( &i))) goto error0; if (XFS_CORRUPT_ON(args->mp, i != 1)) { + xfs_btree_mark_sick(cnt_cur); error = -EFSCORRUPTED; goto error0; } @@ -1776,6 +1812,7 @@ xfs_alloc_ag_vextent_size( if (XFS_CORRUPT_ON(args->mp, rlen != 0 && (rlen > flen || rbno + rlen > fbno + flen))) { + xfs_btree_mark_sick(cnt_cur); error = -EFSCORRUPTED; goto error0; } @@ -1792,6 +1829,7 @@ xfs_alloc_ag_vextent_size( &i))) goto error0; if (XFS_CORRUPT_ON(args->mp, i != 1)) { + xfs_btree_mark_sick(cnt_cur); error = -EFSCORRUPTED; goto error0; } @@ -1818,6 +1856,7 @@ xfs_alloc_ag_vextent_size( rlen = args->len; if (XFS_CORRUPT_ON(args->mp, rlen > flen)) { + xfs_btree_mark_sick(cnt_cur); error = -EFSCORRUPTED; goto error0; } @@ -1837,6 +1876,7 @@ xfs_alloc_ag_vextent_size( if (XFS_CORRUPT_ON(args->mp, args->agbno + args->len > be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length))) { + xfs_ag_mark_sick(args->pag, XFS_SICK_AG_BNOBT); error = -EFSCORRUPTED; goto error0; } @@ -1912,6 +1952,7 @@ xfs_free_ag_extent( if ((error = xfs_alloc_get_rec(bno_cur, <bno, <len, &i))) goto error0; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bno_cur); error = -EFSCORRUPTED; goto error0; } @@ -1927,6 +1968,7 @@ xfs_free_ag_extent( * Very bad. */ if (XFS_CORRUPT_ON(mp, ltbno + ltlen > bno)) { + xfs_btree_mark_sick(bno_cur); error = -EFSCORRUPTED; goto error0; } @@ -1945,6 +1987,7 @@ xfs_free_ag_extent( if ((error = xfs_alloc_get_rec(bno_cur, >bno, >len, &i))) goto error0; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bno_cur); error = -EFSCORRUPTED; goto error0; } @@ -1960,6 +2003,7 @@ xfs_free_ag_extent( * Very bad. */ if (XFS_CORRUPT_ON(mp, bno + len > gtbno)) { + xfs_btree_mark_sick(bno_cur); error = -EFSCORRUPTED; goto error0; } @@ -1980,12 +2024,14 @@ xfs_free_ag_extent( if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i))) goto error0; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cnt_cur); error = -EFSCORRUPTED; goto error0; } if ((error = xfs_btree_delete(cnt_cur, &i))) goto error0; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cnt_cur); error = -EFSCORRUPTED; goto error0; } @@ -1995,12 +2041,14 @@ xfs_free_ag_extent( if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i))) goto error0; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cnt_cur); error = -EFSCORRUPTED; goto error0; } if ((error = xfs_btree_delete(cnt_cur, &i))) goto error0; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cnt_cur); error = -EFSCORRUPTED; goto error0; } @@ -2010,6 +2058,7 @@ xfs_free_ag_extent( if ((error = xfs_btree_delete(bno_cur, &i))) goto error0; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bno_cur); error = -EFSCORRUPTED; goto error0; } @@ -2019,6 +2068,7 @@ xfs_free_ag_extent( if ((error = xfs_btree_decrement(bno_cur, 0, &i))) goto error0; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bno_cur); error = -EFSCORRUPTED; goto error0; } @@ -2036,6 +2086,7 @@ xfs_free_ag_extent( goto error0; if (XFS_CORRUPT_ON(mp, i != 1 || xxbno != ltbno || xxlen != ltlen)) { + xfs_btree_mark_sick(bno_cur); error = -EFSCORRUPTED; goto error0; } @@ -2060,12 +2111,14 @@ xfs_free_ag_extent( if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i))) goto error0; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cnt_cur); error = -EFSCORRUPTED; goto error0; } if ((error = xfs_btree_delete(cnt_cur, &i))) goto error0; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cnt_cur); error = -EFSCORRUPTED; goto error0; } @@ -2076,6 +2129,7 @@ xfs_free_ag_extent( if ((error = xfs_btree_decrement(bno_cur, 0, &i))) goto error0; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bno_cur); error = -EFSCORRUPTED; goto error0; } @@ -2095,12 +2149,14 @@ xfs_free_ag_extent( if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i))) goto error0; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cnt_cur); error = -EFSCORRUPTED; goto error0; } if ((error = xfs_btree_delete(cnt_cur, &i))) goto error0; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cnt_cur); error = -EFSCORRUPTED; goto error0; } @@ -2123,6 +2179,7 @@ xfs_free_ag_extent( if ((error = xfs_btree_insert(bno_cur, &i))) goto error0; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bno_cur); error = -EFSCORRUPTED; goto error0; } @@ -2135,12 +2192,14 @@ xfs_free_ag_extent( if ((error = xfs_alloc_lookup_eq(cnt_cur, nbno, nlen, &i))) goto error0; if (XFS_CORRUPT_ON(mp, i != 0)) { + xfs_btree_mark_sick(cnt_cur); error = -EFSCORRUPTED; goto error0; } if ((error = xfs_btree_insert(cnt_cur, &i))) goto error0; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cnt_cur); error = -EFSCORRUPTED; goto error0; } @@ -2323,6 +2382,7 @@ xfs_free_agfl_block( bp = xfs_btree_get_bufs(tp->t_mountp, tp, agno, agbno); if (XFS_CORRUPT_ON(tp->t_mountp, !bp)) { + xfs_agno_mark_sick(tp->t_mountp, agno, XFS_SICK_AG_AGFL); return -EFSCORRUPTED; } xfs_trans_binval(tp, bp); @@ -3266,10 +3326,14 @@ __xfs_free_extent( return -EIO; error = xfs_free_extent_fix_freelist(tp, agno, &agbp); - if (error) + if (error) { + if (xfs_metadata_is_sick(error)) + xfs_agno_mark_sick(mp, agno, XFS_SICK_AG_BNOBT); return error; + } if (XFS_CORRUPT_ON(mp, agbno >= mp->m_sb.sb_agblocks)) { + xfs_agno_mark_sick(mp, agno, XFS_SICK_AG_BNOBT); error = -EFSCORRUPTED; goto err; } @@ -3277,6 +3341,7 @@ __xfs_free_extent( /* validate the extent size is legal now we have the agf locked */ if (XFS_CORRUPT_ON(mp, agbno + len > be32_to_cpu(XFS_BUF_TO_AGF(agbp)->agf_length))) { + xfs_agno_mark_sick(mp, agno, XFS_SICK_AG_BNOBT); error = -EFSCORRUPTED; goto err; } diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index f3a6598d364a..b273b804d904 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -387,6 +387,7 @@ xfs_bmap_check_leaf_extents( pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); bno = be64_to_cpu(*pp); if (XFS_CORRUPT_ON(mp, !xfs_verify_fsbno(mp, bno))) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } @@ -618,8 +619,10 @@ xfs_bmap_btree_to_extents( pp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, ifp->if_broot_bytes); cbno = be64_to_cpu(*pp); #ifdef DEBUG - if (XFS_CORRUPT_ON(cur->bc_mp, !xfs_btree_check_lptr(cur, cbno, 1))) + if (XFS_CORRUPT_ON(cur->bc_mp, !xfs_btree_check_lptr(cur, cbno, 1))) { + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; + } #endif error = xfs_btree_read_bufl(mp, tp, cbno, &cbp, XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops); @@ -947,6 +950,7 @@ xfs_bmap_add_attrfork_btree( goto error0; /* must be at least one entry */ if (XFS_CORRUPT_ON(mp, stat != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } @@ -1641,6 +1645,7 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bma->cur); error = -EFSCORRUPTED; goto done; } @@ -1648,6 +1653,7 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bma->cur); error = -EFSCORRUPTED; goto done; } @@ -1655,6 +1661,7 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bma->cur); error = -EFSCORRUPTED; goto done; } @@ -1684,6 +1691,7 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bma->cur); error = -EFSCORRUPTED; goto done; } @@ -1717,6 +1725,7 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bma->cur); error = -EFSCORRUPTED; goto done; } @@ -1745,6 +1754,7 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 0)) { + xfs_btree_mark_sick(bma->cur); error = -EFSCORRUPTED; goto done; } @@ -1752,6 +1762,7 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bma->cur); error = -EFSCORRUPTED; goto done; } @@ -1786,6 +1797,7 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bma->cur); error = -EFSCORRUPTED; goto done; } @@ -1810,6 +1822,7 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 0)) { + xfs_btree_mark_sick(bma->cur); error = -EFSCORRUPTED; goto done; } @@ -1817,6 +1830,7 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bma->cur); error = -EFSCORRUPTED; goto done; } @@ -1861,6 +1875,7 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bma->cur); error = -EFSCORRUPTED; goto done; } @@ -1896,6 +1911,7 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 0)) { + xfs_btree_mark_sick(bma->cur); error = -EFSCORRUPTED; goto done; } @@ -1903,6 +1919,7 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bma->cur); error = -EFSCORRUPTED; goto done; } @@ -1982,6 +1999,7 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 0)) { + xfs_btree_mark_sick(bma->cur); error = -EFSCORRUPTED; goto done; } @@ -1989,6 +2007,7 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(bma->cur); error = -EFSCORRUPTED; goto done; } @@ -2186,30 +2205,35 @@ xfs_bmap_add_extent_unwritten_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } if ((error = xfs_btree_delete(cur, &i))) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } if ((error = xfs_btree_decrement(cur, 0, &i))) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } if ((error = xfs_btree_delete(cur, &i))) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } if ((error = xfs_btree_decrement(cur, 0, &i))) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2239,18 +2263,21 @@ xfs_bmap_add_extent_unwritten_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } if ((error = xfs_btree_delete(cur, &i))) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } if ((error = xfs_btree_decrement(cur, 0, &i))) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2283,18 +2310,21 @@ xfs_bmap_add_extent_unwritten_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } if ((error = xfs_btree_delete(cur, &i))) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } if ((error = xfs_btree_decrement(cur, 0, &i))) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2321,6 +2351,7 @@ xfs_bmap_add_extent_unwritten_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2354,6 +2385,7 @@ xfs_bmap_add_extent_unwritten_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2391,6 +2423,7 @@ xfs_bmap_add_extent_unwritten_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2401,6 +2434,7 @@ xfs_bmap_add_extent_unwritten_real( if ((error = xfs_btree_insert(cur, &i))) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2431,6 +2465,7 @@ xfs_bmap_add_extent_unwritten_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2468,6 +2503,7 @@ xfs_bmap_add_extent_unwritten_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2478,12 +2514,14 @@ xfs_bmap_add_extent_unwritten_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 0)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } if ((error = xfs_btree_insert(cur, &i))) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2521,6 +2559,7 @@ xfs_bmap_add_extent_unwritten_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2533,6 +2572,7 @@ xfs_bmap_add_extent_unwritten_real( if ((error = xfs_btree_insert(cur, &i))) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2545,6 +2585,7 @@ xfs_bmap_add_extent_unwritten_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 0)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2552,6 +2593,7 @@ xfs_bmap_add_extent_unwritten_real( if ((error = xfs_btree_insert(cur, &i))) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2838,6 +2880,7 @@ xfs_bmap_add_extent_hole_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2845,6 +2888,7 @@ xfs_bmap_add_extent_hole_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2852,6 +2896,7 @@ xfs_bmap_add_extent_hole_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2881,6 +2926,7 @@ xfs_bmap_add_extent_hole_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2911,6 +2957,7 @@ xfs_bmap_add_extent_hole_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2937,6 +2984,7 @@ xfs_bmap_add_extent_hole_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 0)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -2944,6 +2992,7 @@ xfs_bmap_add_extent_hole_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -5136,6 +5185,7 @@ xfs_bmap_del_extent_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -5163,6 +5213,7 @@ xfs_bmap_del_extent_real( if ((error = xfs_btree_delete(cur, &i))) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -5237,6 +5288,7 @@ xfs_bmap_del_extent_real( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -5257,6 +5309,7 @@ xfs_bmap_del_extent_real( goto done; } if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -5740,21 +5793,27 @@ xfs_bmse_merge( error = xfs_bmbt_lookup_eq(cur, got, &i); if (error) return error; - if (XFS_CORRUPT_ON(mp, i != 1)) + if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; + } error = xfs_btree_delete(cur, &i); if (error) return error; - if (XFS_CORRUPT_ON(mp, i != 1)) + if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; + } /* lookup and update size of the previous extent */ error = xfs_bmbt_lookup_eq(cur, left, &i); if (error) return error; - if (XFS_CORRUPT_ON(mp, i != 1)) + if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; + } error = xfs_bmbt_update(cur, &new); if (error) @@ -5802,8 +5861,10 @@ xfs_bmap_shift_update_extent( error = xfs_bmbt_lookup_eq(cur, &prev, &i); if (error) return error; - if (XFS_CORRUPT_ON(mp, i != 1)) + if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; + } error = xfs_bmbt_update(cur, got); if (error) @@ -5866,6 +5927,7 @@ xfs_bmap_collapse_extents( goto del_cursor; } if (XFS_CORRUPT_ON(mp, isnullstartblock(got.br_startblock))) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto del_cursor; } @@ -5993,6 +6055,7 @@ xfs_bmap_insert_extents( } } if (XFS_CORRUPT_ON(mp, isnullstartblock(got.br_startblock))) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto del_cursor; } @@ -6102,6 +6165,7 @@ xfs_bmap_split_extent_at( if (error) goto del_cursor; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto del_cursor; } @@ -6130,6 +6194,7 @@ xfs_bmap_split_extent_at( if (error) goto del_cursor; if (XFS_CORRUPT_ON(mp, i != 0)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto del_cursor; } @@ -6137,6 +6202,7 @@ xfs_bmap_split_extent_at( if (error) goto del_cursor; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto del_cursor; } diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index fee1dad5eab9..d5ecd6f84655 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -2000,8 +2000,10 @@ xfs_btree_lookup( error = xfs_btree_increment(cur, 0, &i); if (error) goto error0; - if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) + if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; + } *stat = 1; return 0; } @@ -2457,6 +2459,7 @@ xfs_btree_lshift( goto error0; i = xfs_btree_firstrec(tcur, level); if (XFS_CORRUPT_ON(tcur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } @@ -2627,6 +2630,7 @@ xfs_btree_rshift( goto error0; i = xfs_btree_lastrec(tcur, level); if (XFS_CORRUPT_ON(tcur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } @@ -3484,6 +3488,7 @@ xfs_btree_insert( } if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } @@ -3891,6 +3896,7 @@ xfs_btree_delrec( */ i = xfs_btree_lastrec(tcur, level); if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } @@ -3899,12 +3905,14 @@ xfs_btree_delrec( if (error) goto error0; if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } i = xfs_btree_lastrec(tcur, level); if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } @@ -3952,6 +3960,7 @@ xfs_btree_delrec( if (!xfs_btree_ptr_is_null(cur, &lptr)) { i = xfs_btree_firstrec(tcur, level); if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } @@ -3960,6 +3969,7 @@ xfs_btree_delrec( if (error) goto error0; if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } @@ -3977,6 +3987,7 @@ xfs_btree_delrec( */ i = xfs_btree_firstrec(tcur, level); if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } @@ -3986,6 +3997,7 @@ xfs_btree_delrec( goto error0; i = xfs_btree_firstrec(tcur, level); if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 20d539923b2f..56cccdf6aa63 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -547,6 +547,7 @@ xfs_inobt_insert_sprec( if (error) goto error; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error; } @@ -563,10 +564,12 @@ xfs_inobt_insert_sprec( if (error) goto error; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error; } if (XFS_CORRUPT_ON(mp, rec.ir_startino != nrec->ir_startino)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error; } @@ -576,6 +579,7 @@ xfs_inobt_insert_sprec( * cannot merge, something is seriously wrong. */ if (XFS_CORRUPT_ON(mp, !__xfs_inobt_can_merge(nrec, &rec))) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error; } @@ -1068,8 +1072,10 @@ xfs_ialloc_next_rec( error = xfs_inobt_get_rec(cur, rec, &i); if (error) return error; - if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) + if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; + } } return 0; @@ -1093,8 +1099,10 @@ xfs_ialloc_get_rec( error = xfs_inobt_get_rec(cur, rec, &i); if (error) return error; - if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) + if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; + } } return 0; @@ -1175,6 +1183,7 @@ xfs_dialloc_ag_inobt( if (error) goto error0; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } @@ -1183,6 +1192,7 @@ xfs_dialloc_ag_inobt( if (error) goto error0; if (XFS_CORRUPT_ON(mp, j != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } @@ -1341,6 +1351,7 @@ xfs_dialloc_ag_inobt( if (error) goto error0; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } @@ -1350,6 +1361,7 @@ xfs_dialloc_ag_inobt( if (error) goto error0; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } @@ -1359,6 +1371,7 @@ xfs_dialloc_ag_inobt( if (error) goto error0; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } @@ -1421,8 +1434,10 @@ xfs_dialloc_ag_finobt_near( error = xfs_inobt_get_rec(lcur, rec, &i); if (error) return error; - if (XFS_CORRUPT_ON(lcur->bc_mp, i != 1)) + if (XFS_CORRUPT_ON(lcur->bc_mp, i != 1)) { + xfs_btree_mark_sick(lcur); return -EFSCORRUPTED; + } /* * See if we've landed in the parent inode record. The finobt @@ -1446,12 +1461,14 @@ xfs_dialloc_ag_finobt_near( if (error) goto error_rcur; if (XFS_CORRUPT_ON(lcur->bc_mp, j != 1)) { + xfs_btree_mark_sick(lcur); error = -EFSCORRUPTED; goto error_rcur; } } if (XFS_CORRUPT_ON(lcur->bc_mp, i != 1 && j != 1)) { + xfs_btree_mark_sick(lcur); error = -EFSCORRUPTED; goto error_rcur; } @@ -1507,8 +1524,10 @@ xfs_dialloc_ag_finobt_newino( error = xfs_inobt_get_rec(cur, rec, &i); if (error) return error; - if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) + if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; + } return 0; } } @@ -1519,14 +1538,18 @@ xfs_dialloc_ag_finobt_newino( error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i); if (error) return error; - if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) + if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; + } error = xfs_inobt_get_rec(cur, rec, &i); if (error) return error; - if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) + if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; + } return 0; } @@ -1548,14 +1571,18 @@ xfs_dialloc_ag_update_inobt( error = xfs_inobt_lookup(cur, frec->ir_startino, XFS_LOOKUP_EQ, &i); if (error) return error; - if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) + if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; + } error = xfs_inobt_get_rec(cur, &rec, &i); if (error) return error; - if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) + if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; + } ASSERT((XFS_AGINO_TO_OFFSET(cur->bc_mp, rec.ir_startino) % XFS_INODES_PER_CHUNK) == 0); @@ -1564,8 +1591,10 @@ xfs_dialloc_ag_update_inobt( if (XFS_CORRUPT_ON(cur->bc_mp, rec.ir_free != frec->ir_free || - rec.ir_freecount != frec->ir_freecount)) + rec.ir_freecount != frec->ir_freecount)) { + xfs_btree_mark_sick(cur); return -EFSCORRUPTED; + } return xfs_inobt_update(cur, &rec); } @@ -1976,6 +2005,7 @@ xfs_difree_inobt( goto error0; } if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } @@ -1986,6 +2016,7 @@ xfs_difree_inobt( goto error0; } if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error0; } @@ -2101,6 +2132,7 @@ xfs_difree_finobt( * something is out of sync. */ if (XFS_CORRUPT_ON(mp, ibtrec->ir_freecount != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error; } @@ -2127,6 +2159,7 @@ xfs_difree_finobt( if (error) goto error; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error; } @@ -2137,6 +2170,7 @@ xfs_difree_finobt( if (XFS_CORRUPT_ON(mp, rec.ir_free != ibtrec->ir_free || rec.ir_freecount != ibtrec->ir_freecount)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto error; } diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index 75c4f45e1221..131a65dc9736 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -203,6 +203,7 @@ xfs_refcount_insert( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, *i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -233,12 +234,14 @@ xfs_refcount_delete( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_rec != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } trace_xfs_refcount_delete(cur->bc_mp, cur->bc_private.a.agno, &irec); error = xfs_btree_delete(cur, i); if (XFS_CORRUPT_ON(cur->bc_mp, *i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -361,6 +364,7 @@ xfs_refcount_split_extent( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_rec != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -386,6 +390,7 @@ xfs_refcount_split_extent( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_rec != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -428,6 +433,7 @@ xfs_refcount_merge_center_extents( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_rec != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -436,6 +442,7 @@ xfs_refcount_merge_center_extents( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_rec != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -445,6 +452,7 @@ xfs_refcount_merge_center_extents( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_rec != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -456,6 +464,7 @@ xfs_refcount_merge_center_extents( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_rec != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -498,6 +507,7 @@ xfs_refcount_merge_left_extent( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_rec != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -506,6 +516,7 @@ xfs_refcount_merge_left_extent( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_rec != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -517,6 +528,7 @@ xfs_refcount_merge_left_extent( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_rec != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -562,6 +574,7 @@ xfs_refcount_merge_right_extent( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_rec != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -570,6 +583,7 @@ xfs_refcount_merge_right_extent( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_rec != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -581,6 +595,7 @@ xfs_refcount_merge_right_extent( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_rec != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -630,6 +645,7 @@ xfs_refcount_find_left_extents( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_rec != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -651,6 +667,7 @@ xfs_refcount_find_left_extents( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_rec != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -719,6 +736,7 @@ xfs_refcount_find_right_extents( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_rec != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -740,6 +758,7 @@ xfs_refcount_find_right_extents( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_rec != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -967,6 +986,7 @@ xfs_refcount_adjust_extents( goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_tmp != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -1011,6 +1031,7 @@ xfs_refcount_adjust_extents( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_rec != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -1332,6 +1353,7 @@ xfs_refcount_find_shared( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -1347,6 +1369,7 @@ xfs_refcount_find_shared( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -1378,6 +1401,7 @@ xfs_refcount_find_shared( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -1483,6 +1507,7 @@ xfs_refcount_adjust_cow_extents( /* Adding a CoW reservation, there should be nothing here. */ if (XFS_CORRUPT_ON(cur->bc_mp, agbno + aglen > ext.rc_startblock)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -1498,6 +1523,7 @@ xfs_refcount_adjust_cow_extents( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_tmp != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -1505,14 +1531,17 @@ xfs_refcount_adjust_cow_extents( case XFS_REFCOUNT_ADJUST_COW_FREE: /* Removing a CoW reservation, there should be one extent. */ if (XFS_CORRUPT_ON(cur->bc_mp, ext.rc_startblock != agbno)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } if (XFS_CORRUPT_ON(cur->bc_mp, ext.rc_blockcount != aglen)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } if (XFS_CORRUPT_ON(cur->bc_mp, ext.rc_refcount != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -1524,6 +1553,7 @@ xfs_refcount_adjust_cow_extents( if (error) goto out_error; if (XFS_CORRUPT_ON(cur->bc_mp, found_rec != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index ac579cdcb885..237dcd7d149b 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -115,6 +115,7 @@ xfs_rmap_insert( if (error) goto done; if (XFS_CORRUPT_ON(rcur->bc_mp, i != 0)) { + xfs_btree_mark_sick(rcur); error = -EFSCORRUPTED; goto done; } @@ -128,6 +129,7 @@ xfs_rmap_insert( if (error) goto done; if (XFS_CORRUPT_ON(rcur->bc_mp, i != 1)) { + xfs_btree_mark_sick(rcur); error = -EFSCORRUPTED; goto done; } @@ -157,6 +159,7 @@ xfs_rmap_delete( if (error) goto done; if (XFS_CORRUPT_ON(rcur->bc_mp, i != 1)) { + xfs_btree_mark_sick(rcur); error = -EFSCORRUPTED; goto done; } @@ -165,6 +168,7 @@ xfs_rmap_delete( if (error) goto done; if (XFS_CORRUPT_ON(rcur->bc_mp, i != 1)) { + xfs_btree_mark_sick(rcur); error = -EFSCORRUPTED; goto done; } @@ -412,7 +416,7 @@ xfs_rmap_lookup_le_range( */ static int xfs_rmap_free_check_owner( - struct xfs_mount *mp, + struct xfs_btree_cur *cur, uint64_t ltoff, struct xfs_rmap_irec *rec, xfs_filblks_t len, @@ -420,6 +424,7 @@ xfs_rmap_free_check_owner( uint64_t offset, unsigned int flags) { + struct xfs_mount *mp = cur->bc_mp; int error = 0; if (owner == XFS_RMAP_OWN_UNKNOWN) @@ -429,12 +434,14 @@ xfs_rmap_free_check_owner( if (XFS_CORRUPT_ON(mp, (flags & XFS_RMAP_UNWRITTEN) != (rec->rm_flags & XFS_RMAP_UNWRITTEN))) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out; } /* Make sure the owner matches what we expect to find in the tree. */ if (XFS_CORRUPT_ON(mp, owner != rec->rm_owner)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out; } @@ -446,16 +453,19 @@ xfs_rmap_free_check_owner( if (flags & XFS_RMAP_BMBT_BLOCK) { if (XFS_CORRUPT_ON(mp, !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK))) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out; } } else { if (XFS_CORRUPT_ON(mp, rec->rm_offset > offset)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out; } if (XFS_CORRUPT_ON(mp, offset + len > ltoff + rec->rm_blockcount)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out; } @@ -518,6 +528,7 @@ xfs_rmap_unmap( if (error) goto out_error; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -526,6 +537,7 @@ xfs_rmap_unmap( if (error) goto out_error; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -545,6 +557,7 @@ xfs_rmap_unmap( if (owner == XFS_RMAP_OWN_NULL) { if (XFS_CORRUPT_ON(mp, bno < ltrec.rm_startblock + ltrec.rm_blockcount)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -571,6 +584,7 @@ xfs_rmap_unmap( if (error) goto out_error; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -582,12 +596,13 @@ xfs_rmap_unmap( if (XFS_CORRUPT_ON(mp, ltrec.rm_startblock > bno || ltrec.rm_startblock + ltrec.rm_blockcount < bno + len)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } /* Check owner information. */ - error = xfs_rmap_free_check_owner(mp, ltoff, <rec, len, owner, + error = xfs_rmap_free_check_owner(cur, ltoff, <rec, len, owner, offset, flags); if (error) goto out_error; @@ -602,6 +617,7 @@ xfs_rmap_unmap( if (error) goto out_error; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -797,6 +813,7 @@ xfs_rmap_map( if (error) goto out_error; if (XFS_CORRUPT_ON(mp, have_lt != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -811,6 +828,7 @@ xfs_rmap_map( if (XFS_CORRUPT_ON(mp, have_lt != 0 && ltrec.rm_startblock + ltrec.rm_blockcount > bno)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -828,10 +846,12 @@ xfs_rmap_map( if (error) goto out_error; if (XFS_CORRUPT_ON(mp, have_gt != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } if (XFS_CORRUPT_ON(mp, bno + len > gtrec.rm_startblock)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -885,6 +905,7 @@ xfs_rmap_map( if (error) goto out_error; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -932,6 +953,7 @@ xfs_rmap_map( if (error) goto out_error; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -1027,6 +1049,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1035,6 +1058,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1071,11 +1095,13 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } if (XFS_CORRUPT_ON(mp, LEFT.rm_startblock + LEFT.rm_blockcount > bno)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1098,6 +1124,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1110,10 +1137,12 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } if (XFS_CORRUPT_ON(mp, bno + len > RIGHT.rm_startblock)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1144,6 +1173,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1163,6 +1193,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1174,6 +1205,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1181,6 +1213,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1192,6 +1225,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1199,6 +1233,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1222,6 +1257,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1229,6 +1265,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1248,6 +1285,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1259,6 +1297,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1266,6 +1305,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1336,6 +1376,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1378,6 +1419,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 0)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1393,6 +1435,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1426,6 +1469,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1439,6 +1483,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 0)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1451,6 +1496,7 @@ xfs_rmap_convert( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1523,6 +1569,7 @@ xfs_rmap_convert_shared( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1550,6 +1597,7 @@ xfs_rmap_convert_shared( state |= RMAP_LEFT_VALID; if (XFS_CORRUPT_ON(mp, LEFT.rm_startblock + LEFT.rm_blockcount > bno)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1568,10 +1616,12 @@ xfs_rmap_convert_shared( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } if (XFS_CORRUPT_ON(mp, bno + len > RIGHT.rm_startblock)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1622,6 +1672,7 @@ xfs_rmap_convert_shared( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1648,6 +1699,7 @@ xfs_rmap_convert_shared( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1674,6 +1726,7 @@ xfs_rmap_convert_shared( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1697,6 +1750,7 @@ xfs_rmap_convert_shared( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1732,6 +1786,7 @@ xfs_rmap_convert_shared( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1777,6 +1832,7 @@ xfs_rmap_convert_shared( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1812,6 +1868,7 @@ xfs_rmap_convert_shared( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1850,6 +1907,7 @@ xfs_rmap_convert_shared( if (error) goto done; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto done; } @@ -1939,6 +1997,7 @@ xfs_rmap_unmap_shared( if (error) goto out_error; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -1948,12 +2007,14 @@ xfs_rmap_unmap_shared( if (XFS_CORRUPT_ON(mp, ltrec.rm_startblock > bno || ltrec.rm_startblock + ltrec.rm_blockcount < bno + len)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } /* Make sure the owner matches what we expect to find in the tree. */ if (XFS_CORRUPT_ON(mp, owner != ltrec.rm_owner)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -1962,16 +2023,19 @@ xfs_rmap_unmap_shared( if (XFS_CORRUPT_ON(mp, (flags & XFS_RMAP_UNWRITTEN) != (ltrec.rm_flags & XFS_RMAP_UNWRITTEN))) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } /* Check the offset. */ if (XFS_CORRUPT_ON(mp, ltrec.rm_offset > offset)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } if (XFS_CORRUPT_ON(mp, offset > ltoff + ltrec.rm_blockcount)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -2028,6 +2092,7 @@ xfs_rmap_unmap_shared( if (error) goto out_error; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -2057,6 +2122,7 @@ xfs_rmap_unmap_shared( if (error) goto out_error; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -2136,6 +2202,7 @@ xfs_rmap_map_shared( if (error) goto out_error; if (XFS_CORRUPT_ON(mp, have_gt != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } @@ -2188,6 +2255,7 @@ xfs_rmap_map_shared( if (error) goto out_error; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_error; } diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c index 025af21be953..e131db9a0341 100644 --- a/fs/xfs/xfs_discard.c +++ b/fs/xfs/xfs_discard.c @@ -17,6 +17,7 @@ #include "xfs_extent_busy.h" #include "xfs_trace.h" #include "xfs_log.h" +#include "xfs_health.h" STATIC int xfs_trim_extents( @@ -71,6 +72,7 @@ xfs_trim_extents( if (error) goto out_del_cursor; if (XFS_CORRUPT_ON(mp, i != 1)) { + xfs_btree_mark_sick(cur); error = -EFSCORRUPTED; goto out_del_cursor; } diff --git a/fs/xfs/xfs_iwalk.c b/fs/xfs/xfs_iwalk.c index 9820037be458..c6f0618b1f0d 100644 --- a/fs/xfs/xfs_iwalk.c +++ b/fs/xfs/xfs_iwalk.c @@ -298,8 +298,10 @@ xfs_iwalk_ag_start( error = xfs_inobt_get_rec(*curpp, irec, has_more); if (error) return error; - if (XFS_CORRUPT_ON(mp, *has_more != 1)) + if (XFS_CORRUPT_ON(mp, *has_more != 1)) { + xfs_btree_mark_sick(*curpp); return -EFSCORRUPTED; + } /* * If the LE lookup yielded an inobt record before the cursor position,