forked from Minki/linux
7035f9724f
Introduce a new version of the in-core bulkstat structure that supports our new v5 format features. This structure also fills the gaps in the previous structure. We leave wiring up the ioctls for the next patch. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Allison Collins <allison.henderson@oracle.com> Reviewed-by: Brian Foster <bfoster@redhat.com>
191 lines
6.2 KiB
C
191 lines
6.2 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* Copyright (C) 2019 Oracle. All Rights Reserved.
|
|
* Author: Darrick J. Wong <darrick.wong@oracle.com>
|
|
*/
|
|
#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 => has not been examined since mount
|
|
*/
|
|
|
|
struct xfs_mount;
|
|
struct xfs_perag;
|
|
struct xfs_inode;
|
|
struct xfs_fsop_geom;
|
|
|
|
/* Observable health issues for metadata spanning the entire filesystem. */
|
|
#define XFS_SICK_FS_COUNTERS (1 << 0) /* summary counters */
|
|
#define XFS_SICK_FS_UQUOTA (1 << 1) /* user quota */
|
|
#define XFS_SICK_FS_GQUOTA (1 << 2) /* group quota */
|
|
#define XFS_SICK_FS_PQUOTA (1 << 3) /* project quota */
|
|
|
|
/* Observable health issues for realtime volume metadata. */
|
|
#define XFS_SICK_RT_BITMAP (1 << 0) /* realtime bitmap */
|
|
#define XFS_SICK_RT_SUMMARY (1 << 1) /* realtime summary */
|
|
|
|
/* Observable health issues for AG metadata. */
|
|
#define XFS_SICK_AG_SB (1 << 0) /* superblock */
|
|
#define XFS_SICK_AG_AGF (1 << 1) /* AGF header */
|
|
#define XFS_SICK_AG_AGFL (1 << 2) /* AGFL header */
|
|
#define XFS_SICK_AG_AGI (1 << 3) /* AGI header */
|
|
#define XFS_SICK_AG_BNOBT (1 << 4) /* free space by block */
|
|
#define XFS_SICK_AG_CNTBT (1 << 5) /* free space by length */
|
|
#define XFS_SICK_AG_INOBT (1 << 6) /* inode index */
|
|
#define XFS_SICK_AG_FINOBT (1 << 7) /* free inode index */
|
|
#define XFS_SICK_AG_RMAPBT (1 << 8) /* reverse mappings */
|
|
#define XFS_SICK_AG_REFCNTBT (1 << 9) /* reference counts */
|
|
|
|
/* Observable health issues for inode metadata. */
|
|
#define XFS_SICK_INO_CORE (1 << 0) /* inode core */
|
|
#define XFS_SICK_INO_BMBTD (1 << 1) /* data fork */
|
|
#define XFS_SICK_INO_BMBTA (1 << 2) /* attr fork */
|
|
#define XFS_SICK_INO_BMBTC (1 << 3) /* cow fork */
|
|
#define XFS_SICK_INO_DIR (1 << 4) /* directory */
|
|
#define XFS_SICK_INO_XATTR (1 << 5) /* extended attributes */
|
|
#define XFS_SICK_INO_SYMLINK (1 << 6) /* symbolic link remote target */
|
|
#define XFS_SICK_INO_PARENT (1 << 7) /* parent pointers */
|
|
|
|
/* Primary evidence of health problems in a given group. */
|
|
#define XFS_SICK_FS_PRIMARY (XFS_SICK_FS_COUNTERS | \
|
|
XFS_SICK_FS_UQUOTA | \
|
|
XFS_SICK_FS_GQUOTA | \
|
|
XFS_SICK_FS_PQUOTA)
|
|
|
|
#define XFS_SICK_RT_PRIMARY (XFS_SICK_RT_BITMAP | \
|
|
XFS_SICK_RT_SUMMARY)
|
|
|
|
#define XFS_SICK_AG_PRIMARY (XFS_SICK_AG_SB | \
|
|
XFS_SICK_AG_AGF | \
|
|
XFS_SICK_AG_AGFL | \
|
|
XFS_SICK_AG_AGI | \
|
|
XFS_SICK_AG_BNOBT | \
|
|
XFS_SICK_AG_CNTBT | \
|
|
XFS_SICK_AG_INOBT | \
|
|
XFS_SICK_AG_FINOBT | \
|
|
XFS_SICK_AG_RMAPBT | \
|
|
XFS_SICK_AG_REFCNTBT)
|
|
|
|
#define XFS_SICK_INO_PRIMARY (XFS_SICK_INO_CORE | \
|
|
XFS_SICK_INO_BMBTD | \
|
|
XFS_SICK_INO_BMBTA | \
|
|
XFS_SICK_INO_BMBTC | \
|
|
XFS_SICK_INO_DIR | \
|
|
XFS_SICK_INO_XATTR | \
|
|
XFS_SICK_INO_SYMLINK | \
|
|
XFS_SICK_INO_PARENT)
|
|
|
|
/* These functions must be provided by the xfs implementation. */
|
|
|
|
void xfs_fs_mark_sick(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_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_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_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);
|
|
|
|
/* Now some helpers. */
|
|
|
|
static inline bool
|
|
xfs_fs_has_sickness(struct xfs_mount *mp, unsigned int mask)
|
|
{
|
|
unsigned int sick, checked;
|
|
|
|
xfs_fs_measure_sickness(mp, &sick, &checked);
|
|
return sick & mask;
|
|
}
|
|
|
|
static inline bool
|
|
xfs_rt_has_sickness(struct xfs_mount *mp, unsigned int mask)
|
|
{
|
|
unsigned int sick, checked;
|
|
|
|
xfs_rt_measure_sickness(mp, &sick, &checked);
|
|
return sick & mask;
|
|
}
|
|
|
|
static inline bool
|
|
xfs_ag_has_sickness(struct xfs_perag *pag, unsigned int mask)
|
|
{
|
|
unsigned int sick, checked;
|
|
|
|
xfs_ag_measure_sickness(pag, &sick, &checked);
|
|
return sick & mask;
|
|
}
|
|
|
|
static inline bool
|
|
xfs_inode_has_sickness(struct xfs_inode *ip, unsigned int mask)
|
|
{
|
|
unsigned int sick, checked;
|
|
|
|
xfs_inode_measure_sickness(ip, &sick, &checked);
|
|
return sick & mask;
|
|
}
|
|
|
|
static inline bool
|
|
xfs_fs_is_healthy(struct xfs_mount *mp)
|
|
{
|
|
return !xfs_fs_has_sickness(mp, -1U);
|
|
}
|
|
|
|
static inline bool
|
|
xfs_rt_is_healthy(struct xfs_mount *mp)
|
|
{
|
|
return !xfs_rt_has_sickness(mp, -1U);
|
|
}
|
|
|
|
static inline bool
|
|
xfs_ag_is_healthy(struct xfs_perag *pag)
|
|
{
|
|
return !xfs_ag_has_sickness(pag, -1U);
|
|
}
|
|
|
|
static inline bool
|
|
xfs_inode_is_healthy(struct xfs_inode *ip)
|
|
{
|
|
return !xfs_inode_has_sickness(ip, -1U);
|
|
}
|
|
|
|
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);
|
|
|
|
#endif /* __XFS_HEALTH_H__ */
|