linux/fs/xfs/libxfs/xfs_health.h

/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * Copyright (C) 2019 Oracle.  All Rights Reserved.
 * Author: Darrick J. Wong <[email protected]>
 */
#ifndef __XFS_HEALTH_H__
#define __XFS_HEALTH_H__

/*
 * In-Core Filesystem Health Assessments
 * =====================================
 *
 * We'd like to be able to summarize the current health status of the
 * filesystem so that the administrator knows when it's necessary to schedule
 * some downtime for repairs.  Until then, we would also like to avoid abrupt
 * shutdowns due to corrupt metadata.
 *
 * The online scrub feature evaluates the health of all filesystem metadata.
 * When scrub detects corruption in a piece of metadata it will set the
 * corresponding sickness flag, and repair will clear it if successful.  If
 * problems remain at unmount time, we can also request manual intervention by
 * logging a notice to run xfs_repair.
 *
 * Each health tracking group uses a pair of fields for reporting.  The
 * "checked" field tell us if a given piece of metadata has ever been examined,
 * 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 && sick  => errors have been observed during normal operation,
 *                         but the metadata has not been checked thoroughly
 *  - !checked && !sick => has not been examined since mount
 *
 * Evidence of health problems can be sorted into three basic categories:
 *
 * a) Primary evidence, which signals that something is defective within the
 *    general grouping of metadata.
 *
 * b) Secondary evidence, which are side effects of primary problem but are
 *    not themselves problems.  These can be forgotten when the primary
 *    health problems are addressed.
 *
 * c) Indirect evidence, which points to something being wrong in another
 *    group, but we had to release resources and this is all that's left of
 *    that state.
 */

struct xfs_mount;
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
#define XFS_SICK_FS_UQUOTA
#define XFS_SICK_FS_GQUOTA
#define XFS_SICK_FS_PQUOTA
#define XFS_SICK_FS_QUOTACHECK
#define XFS_SICK_FS_NLINKS

/* Observable health issues for realtime volume metadata. */
#define XFS_SICK_RT_BITMAP
#define XFS_SICK_RT_SUMMARY

/* Observable health issues for AG metadata. */
#define XFS_SICK_AG_SB
#define XFS_SICK_AG_AGF
#define XFS_SICK_AG_AGFL
#define XFS_SICK_AG_AGI
#define XFS_SICK_AG_BNOBT
#define XFS_SICK_AG_CNTBT
#define XFS_SICK_AG_INOBT
#define XFS_SICK_AG_FINOBT
#define XFS_SICK_AG_RMAPBT
#define XFS_SICK_AG_REFCNTBT
#define XFS_SICK_AG_INODES

/* Observable health issues for inode metadata. */
#define XFS_SICK_INO_CORE
#define XFS_SICK_INO_BMBTD
#define XFS_SICK_INO_BMBTA
#define XFS_SICK_INO_BMBTC
#define XFS_SICK_INO_DIR
#define XFS_SICK_INO_XATTR
#define XFS_SICK_INO_SYMLINK
#define XFS_SICK_INO_PARENT

#define XFS_SICK_INO_BMBTD_ZAPPED
#define XFS_SICK_INO_BMBTA_ZAPPED
#define XFS_SICK_INO_DIR_ZAPPED
#define XFS_SICK_INO_SYMLINK_ZAPPED

/* Don't propagate sick status to ag health summary during inactivation */
#define XFS_SICK_INO_FORGET
#define XFS_SICK_INO_DIRTREE

/* Primary evidence of health problems in a given group. */
#define XFS_SICK_FS_PRIMARY

#define XFS_SICK_RT_PRIMARY

#define XFS_SICK_AG_PRIMARY

#define XFS_SICK_INO_PRIMARY

#define XFS_SICK_INO_ZAPPED

/* Secondary state related to (but not primary evidence of) health problems. */
#define XFS_SICK_FS_SECONDARY
#define XFS_SICK_RT_SECONDARY
#define XFS_SICK_AG_SECONDARY
#define XFS_SICK_INO_SECONDARY

/* Evidence of health problems elsewhere. */
#define XFS_SICK_FS_INDIRECT
#define XFS_SICK_RT_INDIRECT
#define XFS_SICK_AG_INDIRECT
#define XFS_SICK_INO_INDIRECT

/* All health masks. */
#define XFS_SICK_FS_ALL

#define XFS_SICK_RT_ALL

#define XFS_SICK_AG_ALL

#define XFS_SICK_INO_ALL

/*
 * 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.
 *                         Runtime code should call this upon encountering
 *                         a corruption.
 *
 * xfs_*_mark_corrupt:     Set the sick and checked flags simultaneously.
 *                         Fsck tools should call this when corruption is
 *                         found.
 *
 * xfs_*_mark_healthy:     Clear the sick flags and set the checked flags.
 *                         Fsck tools should call this after correcting errors.
 *
 * 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_corrupt(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_corrupt(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_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_corrupt(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_corrupt(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);

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. */

static inline bool
xfs_fs_has_sickness(struct xfs_mount *mp, unsigned int mask)
{}

static inline bool
xfs_rt_has_sickness(struct xfs_mount *mp, unsigned int mask)
{}

static inline bool
xfs_ag_has_sickness(struct xfs_perag *pag, unsigned int mask)
{}

static inline bool
xfs_inode_has_sickness(struct xfs_inode *ip, unsigned int mask)
{}

static inline bool
xfs_fs_is_healthy(struct xfs_mount *mp)
{}

static inline bool
xfs_rt_is_healthy(struct xfs_mount *mp)
{}

static inline bool
xfs_ag_is_healthy(struct xfs_perag *pag)
{}

static inline bool
xfs_inode_is_healthy(struct xfs_inode *ip)
{}

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)

#endif	/* __XFS_HEALTH_H__ */