162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2019 Oracle.  All Rights Reserved.
462306a36Sopenharmony_ci * Author: Darrick J. Wong <darrick.wong@oracle.com>
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci#ifndef __XFS_HEALTH_H__
762306a36Sopenharmony_ci#define __XFS_HEALTH_H__
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci/*
1062306a36Sopenharmony_ci * In-Core Filesystem Health Assessments
1162306a36Sopenharmony_ci * =====================================
1262306a36Sopenharmony_ci *
1362306a36Sopenharmony_ci * We'd like to be able to summarize the current health status of the
1462306a36Sopenharmony_ci * filesystem so that the administrator knows when it's necessary to schedule
1562306a36Sopenharmony_ci * some downtime for repairs.  Until then, we would also like to avoid abrupt
1662306a36Sopenharmony_ci * shutdowns due to corrupt metadata.
1762306a36Sopenharmony_ci *
1862306a36Sopenharmony_ci * The online scrub feature evaluates the health of all filesystem metadata.
1962306a36Sopenharmony_ci * When scrub detects corruption in a piece of metadata it will set the
2062306a36Sopenharmony_ci * corresponding sickness flag, and repair will clear it if successful.  If
2162306a36Sopenharmony_ci * problems remain at unmount time, we can also request manual intervention by
2262306a36Sopenharmony_ci * logging a notice to run xfs_repair.
2362306a36Sopenharmony_ci *
2462306a36Sopenharmony_ci * Each health tracking group uses a pair of fields for reporting.  The
2562306a36Sopenharmony_ci * "checked" field tell us if a given piece of metadata has ever been examined,
2662306a36Sopenharmony_ci * and the "sick" field tells us if that piece was found to need repairs.
2762306a36Sopenharmony_ci * Therefore we can conclude that for a given sick flag value:
2862306a36Sopenharmony_ci *
2962306a36Sopenharmony_ci *  - checked && sick  => metadata needs repair
3062306a36Sopenharmony_ci *  - checked && !sick => metadata is ok
3162306a36Sopenharmony_ci *  - !checked         => has not been examined since mount
3262306a36Sopenharmony_ci */
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cistruct xfs_mount;
3562306a36Sopenharmony_cistruct xfs_perag;
3662306a36Sopenharmony_cistruct xfs_inode;
3762306a36Sopenharmony_cistruct xfs_fsop_geom;
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci/* Observable health issues for metadata spanning the entire filesystem. */
4062306a36Sopenharmony_ci#define XFS_SICK_FS_COUNTERS	(1 << 0)  /* summary counters */
4162306a36Sopenharmony_ci#define XFS_SICK_FS_UQUOTA	(1 << 1)  /* user quota */
4262306a36Sopenharmony_ci#define XFS_SICK_FS_GQUOTA	(1 << 2)  /* group quota */
4362306a36Sopenharmony_ci#define XFS_SICK_FS_PQUOTA	(1 << 3)  /* project quota */
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci/* Observable health issues for realtime volume metadata. */
4662306a36Sopenharmony_ci#define XFS_SICK_RT_BITMAP	(1 << 0)  /* realtime bitmap */
4762306a36Sopenharmony_ci#define XFS_SICK_RT_SUMMARY	(1 << 1)  /* realtime summary */
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci/* Observable health issues for AG metadata. */
5062306a36Sopenharmony_ci#define XFS_SICK_AG_SB		(1 << 0)  /* superblock */
5162306a36Sopenharmony_ci#define XFS_SICK_AG_AGF		(1 << 1)  /* AGF header */
5262306a36Sopenharmony_ci#define XFS_SICK_AG_AGFL	(1 << 2)  /* AGFL header */
5362306a36Sopenharmony_ci#define XFS_SICK_AG_AGI		(1 << 3)  /* AGI header */
5462306a36Sopenharmony_ci#define XFS_SICK_AG_BNOBT	(1 << 4)  /* free space by block */
5562306a36Sopenharmony_ci#define XFS_SICK_AG_CNTBT	(1 << 5)  /* free space by length */
5662306a36Sopenharmony_ci#define XFS_SICK_AG_INOBT	(1 << 6)  /* inode index */
5762306a36Sopenharmony_ci#define XFS_SICK_AG_FINOBT	(1 << 7)  /* free inode index */
5862306a36Sopenharmony_ci#define XFS_SICK_AG_RMAPBT	(1 << 8)  /* reverse mappings */
5962306a36Sopenharmony_ci#define XFS_SICK_AG_REFCNTBT	(1 << 9)  /* reference counts */
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci/* Observable health issues for inode metadata. */
6262306a36Sopenharmony_ci#define XFS_SICK_INO_CORE	(1 << 0)  /* inode core */
6362306a36Sopenharmony_ci#define XFS_SICK_INO_BMBTD	(1 << 1)  /* data fork */
6462306a36Sopenharmony_ci#define XFS_SICK_INO_BMBTA	(1 << 2)  /* attr fork */
6562306a36Sopenharmony_ci#define XFS_SICK_INO_BMBTC	(1 << 3)  /* cow fork */
6662306a36Sopenharmony_ci#define XFS_SICK_INO_DIR	(1 << 4)  /* directory */
6762306a36Sopenharmony_ci#define XFS_SICK_INO_XATTR	(1 << 5)  /* extended attributes */
6862306a36Sopenharmony_ci#define XFS_SICK_INO_SYMLINK	(1 << 6)  /* symbolic link remote target */
6962306a36Sopenharmony_ci#define XFS_SICK_INO_PARENT	(1 << 7)  /* parent pointers */
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci/* Primary evidence of health problems in a given group. */
7262306a36Sopenharmony_ci#define XFS_SICK_FS_PRIMARY	(XFS_SICK_FS_COUNTERS | \
7362306a36Sopenharmony_ci				 XFS_SICK_FS_UQUOTA | \
7462306a36Sopenharmony_ci				 XFS_SICK_FS_GQUOTA | \
7562306a36Sopenharmony_ci				 XFS_SICK_FS_PQUOTA)
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci#define XFS_SICK_RT_PRIMARY	(XFS_SICK_RT_BITMAP | \
7862306a36Sopenharmony_ci				 XFS_SICK_RT_SUMMARY)
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci#define XFS_SICK_AG_PRIMARY	(XFS_SICK_AG_SB | \
8162306a36Sopenharmony_ci				 XFS_SICK_AG_AGF | \
8262306a36Sopenharmony_ci				 XFS_SICK_AG_AGFL | \
8362306a36Sopenharmony_ci				 XFS_SICK_AG_AGI | \
8462306a36Sopenharmony_ci				 XFS_SICK_AG_BNOBT | \
8562306a36Sopenharmony_ci				 XFS_SICK_AG_CNTBT | \
8662306a36Sopenharmony_ci				 XFS_SICK_AG_INOBT | \
8762306a36Sopenharmony_ci				 XFS_SICK_AG_FINOBT | \
8862306a36Sopenharmony_ci				 XFS_SICK_AG_RMAPBT | \
8962306a36Sopenharmony_ci				 XFS_SICK_AG_REFCNTBT)
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci#define XFS_SICK_INO_PRIMARY	(XFS_SICK_INO_CORE | \
9262306a36Sopenharmony_ci				 XFS_SICK_INO_BMBTD | \
9362306a36Sopenharmony_ci				 XFS_SICK_INO_BMBTA | \
9462306a36Sopenharmony_ci				 XFS_SICK_INO_BMBTC | \
9562306a36Sopenharmony_ci				 XFS_SICK_INO_DIR | \
9662306a36Sopenharmony_ci				 XFS_SICK_INO_XATTR | \
9762306a36Sopenharmony_ci				 XFS_SICK_INO_SYMLINK | \
9862306a36Sopenharmony_ci				 XFS_SICK_INO_PARENT)
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci/* These functions must be provided by the xfs implementation. */
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_civoid xfs_fs_mark_sick(struct xfs_mount *mp, unsigned int mask);
10362306a36Sopenharmony_civoid xfs_fs_mark_healthy(struct xfs_mount *mp, unsigned int mask);
10462306a36Sopenharmony_civoid xfs_fs_measure_sickness(struct xfs_mount *mp, unsigned int *sick,
10562306a36Sopenharmony_ci		unsigned int *checked);
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_civoid xfs_rt_mark_sick(struct xfs_mount *mp, unsigned int mask);
10862306a36Sopenharmony_civoid xfs_rt_mark_healthy(struct xfs_mount *mp, unsigned int mask);
10962306a36Sopenharmony_civoid xfs_rt_measure_sickness(struct xfs_mount *mp, unsigned int *sick,
11062306a36Sopenharmony_ci		unsigned int *checked);
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_civoid xfs_ag_mark_sick(struct xfs_perag *pag, unsigned int mask);
11362306a36Sopenharmony_civoid xfs_ag_mark_healthy(struct xfs_perag *pag, unsigned int mask);
11462306a36Sopenharmony_civoid xfs_ag_measure_sickness(struct xfs_perag *pag, unsigned int *sick,
11562306a36Sopenharmony_ci		unsigned int *checked);
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_civoid xfs_inode_mark_sick(struct xfs_inode *ip, unsigned int mask);
11862306a36Sopenharmony_civoid xfs_inode_mark_healthy(struct xfs_inode *ip, unsigned int mask);
11962306a36Sopenharmony_civoid xfs_inode_measure_sickness(struct xfs_inode *ip, unsigned int *sick,
12062306a36Sopenharmony_ci		unsigned int *checked);
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_civoid xfs_health_unmount(struct xfs_mount *mp);
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci/* Now some helpers. */
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_cistatic inline bool
12762306a36Sopenharmony_cixfs_fs_has_sickness(struct xfs_mount *mp, unsigned int mask)
12862306a36Sopenharmony_ci{
12962306a36Sopenharmony_ci	unsigned int	sick, checked;
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci	xfs_fs_measure_sickness(mp, &sick, &checked);
13262306a36Sopenharmony_ci	return sick & mask;
13362306a36Sopenharmony_ci}
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_cistatic inline bool
13662306a36Sopenharmony_cixfs_rt_has_sickness(struct xfs_mount *mp, unsigned int mask)
13762306a36Sopenharmony_ci{
13862306a36Sopenharmony_ci	unsigned int	sick, checked;
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	xfs_rt_measure_sickness(mp, &sick, &checked);
14162306a36Sopenharmony_ci	return sick & mask;
14262306a36Sopenharmony_ci}
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_cistatic inline bool
14562306a36Sopenharmony_cixfs_ag_has_sickness(struct xfs_perag *pag, unsigned int mask)
14662306a36Sopenharmony_ci{
14762306a36Sopenharmony_ci	unsigned int	sick, checked;
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci	xfs_ag_measure_sickness(pag, &sick, &checked);
15062306a36Sopenharmony_ci	return sick & mask;
15162306a36Sopenharmony_ci}
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_cistatic inline bool
15462306a36Sopenharmony_cixfs_inode_has_sickness(struct xfs_inode *ip, unsigned int mask)
15562306a36Sopenharmony_ci{
15662306a36Sopenharmony_ci	unsigned int	sick, checked;
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci	xfs_inode_measure_sickness(ip, &sick, &checked);
15962306a36Sopenharmony_ci	return sick & mask;
16062306a36Sopenharmony_ci}
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_cistatic inline bool
16362306a36Sopenharmony_cixfs_fs_is_healthy(struct xfs_mount *mp)
16462306a36Sopenharmony_ci{
16562306a36Sopenharmony_ci	return !xfs_fs_has_sickness(mp, -1U);
16662306a36Sopenharmony_ci}
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_cistatic inline bool
16962306a36Sopenharmony_cixfs_rt_is_healthy(struct xfs_mount *mp)
17062306a36Sopenharmony_ci{
17162306a36Sopenharmony_ci	return !xfs_rt_has_sickness(mp, -1U);
17262306a36Sopenharmony_ci}
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_cistatic inline bool
17562306a36Sopenharmony_cixfs_ag_is_healthy(struct xfs_perag *pag)
17662306a36Sopenharmony_ci{
17762306a36Sopenharmony_ci	return !xfs_ag_has_sickness(pag, -1U);
17862306a36Sopenharmony_ci}
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_cistatic inline bool
18162306a36Sopenharmony_cixfs_inode_is_healthy(struct xfs_inode *ip)
18262306a36Sopenharmony_ci{
18362306a36Sopenharmony_ci	return !xfs_inode_has_sickness(ip, -1U);
18462306a36Sopenharmony_ci}
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_civoid xfs_fsop_geom_health(struct xfs_mount *mp, struct xfs_fsop_geom *geo);
18762306a36Sopenharmony_civoid xfs_ag_geom_health(struct xfs_perag *pag, struct xfs_ag_geometry *ageo);
18862306a36Sopenharmony_civoid xfs_bulkstat_health(struct xfs_inode *ip, struct xfs_bulkstat *bs);
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci#endif	/* __XFS_HEALTH_H__ */
191