LCOV - code coverage report
Current view: top level - fs/xfs/libxfs - xfs_health.h (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsx @ Mon Jul 31 20:08:34 PDT 2023 Lines: 9 9 100.0 %
Date: 2023-07-31 20:08:34 Functions: 0 0 -

          Line data    Source code
       1             : /* SPDX-License-Identifier: GPL-2.0+ */
       2             : /*
       3             :  * Copyright (C) 2019 Oracle.  All Rights Reserved.
       4             :  * Author: Darrick J. Wong <darrick.wong@oracle.com>
       5             :  */
       6             : #ifndef __XFS_HEALTH_H__
       7             : #define __XFS_HEALTH_H__
       8             : 
       9             : /*
      10             :  * In-Core Filesystem Health Assessments
      11             :  * =====================================
      12             :  *
      13             :  * We'd like to be able to summarize the current health status of the
      14             :  * filesystem so that the administrator knows when it's necessary to schedule
      15             :  * some downtime for repairs.  Until then, we would also like to avoid abrupt
      16             :  * shutdowns due to corrupt metadata.
      17             :  *
      18             :  * The online scrub feature evaluates the health of all filesystem metadata.
      19             :  * When scrub detects corruption in a piece of metadata it will set the
      20             :  * corresponding sickness flag, and repair will clear it if successful.  If
      21             :  * problems remain at unmount time, we can also request manual intervention by
      22             :  * logging a notice to run xfs_repair.
      23             :  *
      24             :  * Each health tracking group uses a pair of fields for reporting.  The
      25             :  * "checked" field tell us if a given piece of metadata has ever been examined,
      26             :  * and the "sick" field tells us if that piece was found to need repairs.
      27             :  * Therefore we can conclude that for a given sick flag value:
      28             :  *
      29             :  *  - checked && sick   => metadata needs repair
      30             :  *  - checked && !sick  => metadata is ok
      31             :  *  - !checked && sick  => errors have been observed during normal operation,
      32             :  *                         but the metadata has not been checked thoroughly
      33             :  *  - !checked && !sick => has not been examined since mount
      34             :  *
      35             :  * Evidence of health problems can be sorted into three basic categories:
      36             :  *
      37             :  * a) Primary evidence, which signals that something is defective within the
      38             :  *    general grouping of metadata.
      39             :  *
      40             :  * b) Secondary evidence, which are side effects of primary problem but are
      41             :  *    not themselves problems.  These can be forgotten when the primary
      42             :  *    health problems are addressed.
      43             :  *
      44             :  * c) Indirect evidence, which points to something being wrong in another
      45             :  *    group, but we had to release resources and this is all that's left of
      46             :  *    that state.
      47             :  */
      48             : 
      49             : struct xfs_mount;
      50             : struct xfs_perag;
      51             : struct xfs_inode;
      52             : struct xfs_fsop_geom;
      53             : struct xfs_btree_cur;
      54             : struct xfs_da_args;
      55             : struct xfs_rtgroup;
      56             : 
      57             : /* Observable health issues for metadata spanning the entire filesystem. */
      58             : #define XFS_SICK_FS_COUNTERS    (1 << 0)  /* summary counters */
      59             : #define XFS_SICK_FS_UQUOTA      (1 << 1)  /* user quota */
      60             : #define XFS_SICK_FS_GQUOTA      (1 << 2)  /* group quota */
      61             : #define XFS_SICK_FS_PQUOTA      (1 << 3)  /* project quota */
      62             : #define XFS_SICK_FS_QUOTACHECK  (1 << 4)  /* quota counts */
      63             : #define XFS_SICK_FS_NLINKS      (1 << 5)  /* inode link counts */
      64             : #define XFS_SICK_FS_METADIR     (1 << 6)  /* metadata directory tree */
      65             : 
      66             : /* Observable health issues for realtime volume metadata. */
      67             : #define XFS_SICK_RT_BITMAP      (1 << 0)  /* realtime bitmap */
      68             : #define XFS_SICK_RT_SUMMARY     (1 << 1)  /* realtime summary */
      69             : #define XFS_SICK_RT_SUPER       (1 << 2)  /* rt group superblock */
      70             : #define XFS_SICK_RT_RMAPBT      (1 << 3)  /* reverse mappings */
      71             : #define XFS_SICK_RT_REFCNTBT    (1 << 4)  /* reference counts */
      72             : 
      73             : /* Observable health issues for AG metadata. */
      74             : #define XFS_SICK_AG_SB          (1 << 0)  /* superblock */
      75             : #define XFS_SICK_AG_AGF         (1 << 1)  /* AGF header */
      76             : #define XFS_SICK_AG_AGFL        (1 << 2)  /* AGFL header */
      77             : #define XFS_SICK_AG_AGI         (1 << 3)  /* AGI header */
      78             : #define XFS_SICK_AG_BNOBT       (1 << 4)  /* free space by block */
      79             : #define XFS_SICK_AG_CNTBT       (1 << 5)  /* free space by length */
      80             : #define XFS_SICK_AG_INOBT       (1 << 6)  /* inode index */
      81             : #define XFS_SICK_AG_FINOBT      (1 << 7)  /* free inode index */
      82             : #define XFS_SICK_AG_RMAPBT      (1 << 8)  /* reverse mappings */
      83             : #define XFS_SICK_AG_REFCNTBT    (1 << 9)  /* reference counts */
      84             : #define XFS_SICK_AG_INODES      (1 << 10) /* inactivated bad inodes */
      85             : 
      86             : /* Observable health issues for inode metadata. */
      87             : #define XFS_SICK_INO_CORE       (1 << 0)  /* inode core */
      88             : #define XFS_SICK_INO_BMBTD      (1 << 1)  /* data fork */
      89             : #define XFS_SICK_INO_BMBTA      (1 << 2)  /* attr fork */
      90             : #define XFS_SICK_INO_BMBTC      (1 << 3)  /* cow fork */
      91             : #define XFS_SICK_INO_DIR        (1 << 4)  /* directory */
      92             : #define XFS_SICK_INO_XATTR      (1 << 5)  /* extended attributes */
      93             : #define XFS_SICK_INO_SYMLINK    (1 << 6)  /* symbolic link remote target */
      94             : #define XFS_SICK_INO_PARENT     (1 << 7)  /* parent pointers */
      95             : /* Don't propagate sick status to ag health summary during inactivation */
      96             : #define XFS_SICK_INO_FORGET     (1 << 8)
      97             : #define XFS_SICK_INO_DIRTREE    (1 << 9)  /* directory tree structure */
      98             : 
      99             : /* Primary evidence of health problems in a given group. */
     100             : #define XFS_SICK_FS_PRIMARY     (XFS_SICK_FS_COUNTERS | \
     101             :                                  XFS_SICK_FS_UQUOTA | \
     102             :                                  XFS_SICK_FS_GQUOTA | \
     103             :                                  XFS_SICK_FS_PQUOTA | \
     104             :                                  XFS_SICK_FS_QUOTACHECK | \
     105             :                                  XFS_SICK_FS_NLINKS | \
     106             :                                  XFS_SICK_FS_METADIR)
     107             : 
     108             : #define XFS_SICK_RT_PRIMARY     (XFS_SICK_RT_BITMAP | \
     109             :                                  XFS_SICK_RT_SUMMARY | \
     110             :                                  XFS_SICK_RT_SUPER | \
     111             :                                  XFS_SICK_RT_RMAPBT | \
     112             :                                  XFS_SICK_RT_REFCNTBT)
     113             : 
     114             : #define XFS_SICK_AG_PRIMARY     (XFS_SICK_AG_SB | \
     115             :                                  XFS_SICK_AG_AGF | \
     116             :                                  XFS_SICK_AG_AGFL | \
     117             :                                  XFS_SICK_AG_AGI | \
     118             :                                  XFS_SICK_AG_BNOBT | \
     119             :                                  XFS_SICK_AG_CNTBT | \
     120             :                                  XFS_SICK_AG_INOBT | \
     121             :                                  XFS_SICK_AG_FINOBT | \
     122             :                                  XFS_SICK_AG_RMAPBT | \
     123             :                                  XFS_SICK_AG_REFCNTBT)
     124             : 
     125             : #define XFS_SICK_INO_PRIMARY    (XFS_SICK_INO_CORE | \
     126             :                                  XFS_SICK_INO_BMBTD | \
     127             :                                  XFS_SICK_INO_BMBTA | \
     128             :                                  XFS_SICK_INO_BMBTC | \
     129             :                                  XFS_SICK_INO_DIR | \
     130             :                                  XFS_SICK_INO_XATTR | \
     131             :                                  XFS_SICK_INO_SYMLINK | \
     132             :                                  XFS_SICK_INO_PARENT | \
     133             :                                  XFS_SICK_INO_DIRTREE)
     134             : 
     135             : /* Secondary state related to (but not primary evidence of) health problems. */
     136             : #define XFS_SICK_FS_SECONDARY   (0)
     137             : #define XFS_SICK_RT_SECONDARY   (0)
     138             : #define XFS_SICK_AG_SECONDARY   (0)
     139             : #define XFS_SICK_INO_SECONDARY  (XFS_SICK_INO_FORGET)
     140             : 
     141             : /* Evidence of health problems elsewhere. */
     142             : #define XFS_SICK_FS_INDIRECT    (0)
     143             : #define XFS_SICK_RT_INDIRECT    (0)
     144             : #define XFS_SICK_AG_INDIRECT    (XFS_SICK_AG_INODES)
     145             : #define XFS_SICK_INO_INDIRECT   (0)
     146             : 
     147             : /* All health masks. */
     148             : #define XFS_SICK_FS_ALL (XFS_SICK_FS_PRIMARY | \
     149             :                                  XFS_SICK_FS_SECONDARY | \
     150             :                                  XFS_SICK_FS_INDIRECT)
     151             : 
     152             : #define XFS_SICK_RT_ALL (XFS_SICK_RT_PRIMARY | \
     153             :                                  XFS_SICK_RT_SECONDARY | \
     154             :                                  XFS_SICK_RT_INDIRECT)
     155             : 
     156             : #define XFS_SICK_AG_ALL (XFS_SICK_AG_PRIMARY | \
     157             :                                  XFS_SICK_AG_SECONDARY | \
     158             :                                  XFS_SICK_AG_INDIRECT)
     159             : 
     160             : #define XFS_SICK_INO_ALL        (XFS_SICK_INO_PRIMARY | \
     161             :                                  XFS_SICK_INO_SECONDARY | \
     162             :                                  XFS_SICK_INO_INDIRECT)
     163             : 
     164             : /*
     165             :  * These functions must be provided by the xfs implementation.  Function
     166             :  * behavior with respect to the first argument should be as follows:
     167             :  *
     168             :  * xfs_*_mark_sick:    set the sick flags and do not set checked flags.
     169             :  * xfs_*_mark_checked: set the checked flags.
     170             :  * xfs_*_mark_healthy: clear the sick flags and set the checked flags.
     171             :  *
     172             :  * xfs_*_measure_sickness: return the sick and check status in the provided
     173             :  * out parameters.
     174             :  */
     175             : 
     176             : void xfs_fs_mark_sick(struct xfs_mount *mp, unsigned int mask);
     177             : void xfs_fs_mark_checked(struct xfs_mount *mp, unsigned int mask);
     178             : void xfs_fs_mark_healthy(struct xfs_mount *mp, unsigned int mask);
     179             : void xfs_fs_measure_sickness(struct xfs_mount *mp, unsigned int *sick,
     180             :                 unsigned int *checked);
     181             : 
     182             : void xfs_rt_mark_sick(struct xfs_mount *mp, unsigned int mask);
     183             : void xfs_rt_mark_checked(struct xfs_mount *mp, unsigned int mask);
     184             : void xfs_rt_mark_healthy(struct xfs_mount *mp, unsigned int mask);
     185             : void xfs_rt_measure_sickness(struct xfs_mount *mp, unsigned int *sick,
     186             :                 unsigned int *checked);
     187             : 
     188             : void xfs_rgno_mark_sick(struct xfs_mount *mp, xfs_rgnumber_t rgno,
     189             :                 unsigned int mask);
     190             : void xfs_rtgroup_mark_sick(struct xfs_rtgroup *rtg, unsigned int mask);
     191             : void xfs_rtgroup_mark_checked(struct xfs_rtgroup *rtg, unsigned int mask);
     192             : void xfs_rtgroup_mark_healthy(struct xfs_rtgroup *rtg, unsigned int mask);
     193             : void xfs_rtgroup_measure_sickness(struct xfs_rtgroup *rtg, unsigned int *sick,
     194             :                 unsigned int *checked);
     195             : 
     196             : void xfs_agno_mark_sick(struct xfs_mount *mp, xfs_agnumber_t agno,
     197             :                 unsigned int mask);
     198             : void xfs_ag_mark_sick(struct xfs_perag *pag, unsigned int mask);
     199             : void xfs_ag_mark_checked(struct xfs_perag *pag, unsigned int mask);
     200             : void xfs_ag_mark_healthy(struct xfs_perag *pag, unsigned int mask);
     201             : void xfs_ag_measure_sickness(struct xfs_perag *pag, unsigned int *sick,
     202             :                 unsigned int *checked);
     203             : 
     204             : void xfs_inode_mark_sick(struct xfs_inode *ip, unsigned int mask);
     205             : void xfs_inode_mark_checked(struct xfs_inode *ip, unsigned int mask);
     206             : void xfs_inode_mark_healthy(struct xfs_inode *ip, unsigned int mask);
     207             : void xfs_inode_measure_sickness(struct xfs_inode *ip, unsigned int *sick,
     208             :                 unsigned int *checked);
     209             : 
     210             : void xfs_health_unmount(struct xfs_mount *mp);
     211             : void xfs_bmap_mark_sick(struct xfs_inode *ip, int whichfork);
     212             : void xfs_btree_mark_sick(struct xfs_btree_cur *cur);
     213             : void xfs_dirattr_mark_sick(struct xfs_inode *ip, int whichfork);
     214             : void xfs_da_mark_sick(struct xfs_da_args *args);
     215             : 
     216             : /* Now some helpers. */
     217             : 
     218             : static inline bool
     219             : xfs_fs_has_sickness(struct xfs_mount *mp, unsigned int mask)
     220             : {
     221      109421 :         unsigned int    sick, checked;
     222             : 
     223      109421 :         xfs_fs_measure_sickness(mp, &sick, &checked);
     224      109421 :         return sick & mask;
     225             : }
     226             : 
     227             : static inline bool
     228             : xfs_rt_has_sickness(struct xfs_mount *mp, unsigned int mask)
     229             : {
     230             :         unsigned int    sick, checked;
     231             : 
     232             :         xfs_rt_measure_sickness(mp, &sick, &checked);
     233             :         return sick & mask;
     234             : }
     235             : 
     236             : static inline bool
     237             : xfs_ag_has_sickness(struct xfs_perag *pag, unsigned int mask)
     238             : {
     239  4480726073 :         unsigned int    sick, checked;
     240             : 
     241  4480726073 :         xfs_ag_measure_sickness(pag, &sick, &checked);
     242  4482033642 :         return sick & mask;
     243             : }
     244             : 
     245             : static inline bool
     246             : xfs_rtgroup_has_sickness(struct xfs_rtgroup *rtg, unsigned int mask)
     247             : {
     248             :         unsigned int    sick, checked;
     249             : 
     250             :         xfs_rtgroup_measure_sickness(rtg, &sick, &checked);
     251             :         return sick & mask;
     252             : }
     253             : 
     254             : static inline bool
     255             : xfs_inode_has_sickness(struct xfs_inode *ip, unsigned int mask)
     256             : {
     257      401087 :         unsigned int    sick, checked;
     258             : 
     259      401087 :         xfs_inode_measure_sickness(ip, &sick, &checked);
     260      401098 :         return sick & mask;
     261             : }
     262             : 
     263             : static inline bool
     264             : xfs_fs_is_healthy(struct xfs_mount *mp)
     265             : {
     266             :         return !xfs_fs_has_sickness(mp, -1U);
     267             : }
     268             : 
     269             : static inline bool
     270             : xfs_rt_is_healthy(struct xfs_mount *mp)
     271             : {
     272             :         return !xfs_rt_has_sickness(mp, -1U);
     273             : }
     274             : 
     275             : static inline bool
     276             : xfs_rtgroup_is_healthy(struct xfs_rtgroup *rtg)
     277             : {
     278             :         return !xfs_rtgroup_has_sickness(rtg, -1U);
     279             : }
     280             : 
     281             : static inline bool
     282             : xfs_ag_is_healthy(struct xfs_perag *pag)
     283             : {
     284             :         return !xfs_ag_has_sickness(pag, -1U);
     285             : }
     286             : 
     287             : static inline bool
     288             : xfs_inode_is_healthy(struct xfs_inode *ip)
     289             : {
     290             :         return !xfs_inode_has_sickness(ip, -1U);
     291             : }
     292             : 
     293             : void xfs_fsop_geom_health(struct xfs_mount *mp, struct xfs_fsop_geom *geo);
     294             : void xfs_ag_geom_health(struct xfs_perag *pag, struct xfs_ag_geometry *ageo);
     295             : void xfs_rtgroup_geom_health(struct xfs_rtgroup *rtg,
     296             :                 struct xfs_rtgroup_geometry *rgeo);
     297             : void xfs_bulkstat_health(struct xfs_inode *ip, struct xfs_bulkstat *bs);
     298             : 
     299             : #define xfs_metadata_is_sick(error) \
     300             :         (unlikely((error) == -EFSCORRUPTED || (error) == -EFSBADCRC))
     301             : 
     302             : #endif  /* __XFS_HEALTH_H__ */

Generated by: LCOV version 1.14