]>
Commit | Line | Data |
---|---|---|
f866934a DW |
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 => has not been examined since mount | |
32 | */ | |
33 | ||
34 | struct xfs_mount; | |
35 | struct xfs_perag; | |
36 | struct xfs_inode; | |
69423ead | 37 | struct xfs_fsop_geom; |
f866934a DW |
38 | |
39 | /* Observable health issues for metadata spanning the entire filesystem. */ | |
40 | #define XFS_SICK_FS_COUNTERS (1 << 0) /* summary counters */ | |
41 | #define XFS_SICK_FS_UQUOTA (1 << 1) /* user quota */ | |
42 | #define XFS_SICK_FS_GQUOTA (1 << 2) /* group quota */ | |
43 | #define XFS_SICK_FS_PQUOTA (1 << 3) /* project quota */ | |
44 | ||
45 | /* Observable health issues for realtime volume metadata. */ | |
46 | #define XFS_SICK_RT_BITMAP (1 << 0) /* realtime bitmap */ | |
47 | #define XFS_SICK_RT_SUMMARY (1 << 1) /* realtime summary */ | |
48 | ||
49 | /* Observable health issues for AG metadata. */ | |
50 | #define XFS_SICK_AG_SB (1 << 0) /* superblock */ | |
51 | #define XFS_SICK_AG_AGF (1 << 1) /* AGF header */ | |
52 | #define XFS_SICK_AG_AGFL (1 << 2) /* AGFL header */ | |
53 | #define XFS_SICK_AG_AGI (1 << 3) /* AGI header */ | |
54 | #define XFS_SICK_AG_BNOBT (1 << 4) /* free space by block */ | |
55 | #define XFS_SICK_AG_CNTBT (1 << 5) /* free space by length */ | |
56 | #define XFS_SICK_AG_INOBT (1 << 6) /* inode index */ | |
57 | #define XFS_SICK_AG_FINOBT (1 << 7) /* free inode index */ | |
58 | #define XFS_SICK_AG_RMAPBT (1 << 8) /* reverse mappings */ | |
59 | #define XFS_SICK_AG_REFCNTBT (1 << 9) /* reference counts */ | |
60 | ||
61 | /* Observable health issues for inode metadata. */ | |
62 | #define XFS_SICK_INO_CORE (1 << 0) /* inode core */ | |
63 | #define XFS_SICK_INO_BMBTD (1 << 1) /* data fork */ | |
64 | #define XFS_SICK_INO_BMBTA (1 << 2) /* attr fork */ | |
65 | #define XFS_SICK_INO_BMBTC (1 << 3) /* cow fork */ | |
66 | #define XFS_SICK_INO_DIR (1 << 4) /* directory */ | |
67 | #define XFS_SICK_INO_XATTR (1 << 5) /* extended attributes */ | |
68 | #define XFS_SICK_INO_SYMLINK (1 << 6) /* symbolic link remote target */ | |
69 | #define XFS_SICK_INO_PARENT (1 << 7) /* parent pointers */ | |
70 | ||
71 | /* Primary evidence of health problems in a given group. */ | |
72 | #define XFS_SICK_FS_PRIMARY (XFS_SICK_FS_COUNTERS | \ | |
73 | XFS_SICK_FS_UQUOTA | \ | |
74 | XFS_SICK_FS_GQUOTA | \ | |
75 | XFS_SICK_FS_PQUOTA) | |
76 | ||
77 | #define XFS_SICK_RT_PRIMARY (XFS_SICK_RT_BITMAP | \ | |
78 | XFS_SICK_RT_SUMMARY) | |
79 | ||
80 | #define XFS_SICK_AG_PRIMARY (XFS_SICK_AG_SB | \ | |
81 | XFS_SICK_AG_AGF | \ | |
82 | XFS_SICK_AG_AGFL | \ | |
83 | XFS_SICK_AG_AGI | \ | |
84 | XFS_SICK_AG_BNOBT | \ | |
85 | XFS_SICK_AG_CNTBT | \ | |
86 | XFS_SICK_AG_INOBT | \ | |
87 | XFS_SICK_AG_FINOBT | \ | |
88 | XFS_SICK_AG_RMAPBT | \ | |
89 | XFS_SICK_AG_REFCNTBT) | |
90 | ||
91 | #define XFS_SICK_INO_PRIMARY (XFS_SICK_INO_CORE | \ | |
92 | XFS_SICK_INO_BMBTD | \ | |
93 | XFS_SICK_INO_BMBTA | \ | |
94 | XFS_SICK_INO_BMBTC | \ | |
95 | XFS_SICK_INO_DIR | \ | |
96 | XFS_SICK_INO_XATTR | \ | |
97 | XFS_SICK_INO_SYMLINK | \ | |
98 | XFS_SICK_INO_PARENT) | |
99 | ||
100 | /* These functions must be provided by the xfs implementation. */ | |
101 | ||
102 | void xfs_fs_mark_sick(struct xfs_mount *mp, unsigned int mask); | |
103 | void xfs_fs_mark_healthy(struct xfs_mount *mp, unsigned int mask); | |
104 | void xfs_fs_measure_sickness(struct xfs_mount *mp, unsigned int *sick, | |
105 | unsigned int *checked); | |
106 | ||
107 | void xfs_rt_mark_sick(struct xfs_mount *mp, unsigned int mask); | |
108 | void xfs_rt_mark_healthy(struct xfs_mount *mp, unsigned int mask); | |
109 | void xfs_rt_measure_sickness(struct xfs_mount *mp, unsigned int *sick, | |
110 | unsigned int *checked); | |
111 | ||
112 | void xfs_ag_mark_sick(struct xfs_perag *pag, unsigned int mask); | |
113 | void xfs_ag_mark_healthy(struct xfs_perag *pag, unsigned int mask); | |
114 | void xfs_ag_measure_sickness(struct xfs_perag *pag, unsigned int *sick, | |
115 | unsigned int *checked); | |
116 | ||
117 | void xfs_inode_mark_sick(struct xfs_inode *ip, unsigned int mask); | |
118 | void xfs_inode_mark_healthy(struct xfs_inode *ip, unsigned int mask); | |
119 | void xfs_inode_measure_sickness(struct xfs_inode *ip, unsigned int *sick, | |
120 | unsigned int *checked); | |
121 | ||
25b8487b DW |
122 | void xfs_health_unmount(struct xfs_mount *mp); |
123 | ||
f866934a DW |
124 | /* Now some helpers. */ |
125 | ||
126 | static inline bool | |
127 | xfs_fs_has_sickness(struct xfs_mount *mp, unsigned int mask) | |
128 | { | |
129 | unsigned int sick, checked; | |
130 | ||
131 | xfs_fs_measure_sickness(mp, &sick, &checked); | |
132 | return sick & mask; | |
133 | } | |
134 | ||
135 | static inline bool | |
136 | xfs_rt_has_sickness(struct xfs_mount *mp, unsigned int mask) | |
137 | { | |
138 | unsigned int sick, checked; | |
139 | ||
140 | xfs_rt_measure_sickness(mp, &sick, &checked); | |
141 | return sick & mask; | |
142 | } | |
143 | ||
144 | static inline bool | |
145 | xfs_ag_has_sickness(struct xfs_perag *pag, unsigned int mask) | |
146 | { | |
147 | unsigned int sick, checked; | |
148 | ||
149 | xfs_ag_measure_sickness(pag, &sick, &checked); | |
150 | return sick & mask; | |
151 | } | |
152 | ||
153 | static inline bool | |
154 | xfs_inode_has_sickness(struct xfs_inode *ip, unsigned int mask) | |
155 | { | |
156 | unsigned int sick, checked; | |
157 | ||
158 | xfs_inode_measure_sickness(ip, &sick, &checked); | |
159 | return sick & mask; | |
160 | } | |
161 | ||
162 | static inline bool | |
163 | xfs_fs_is_healthy(struct xfs_mount *mp) | |
164 | { | |
165 | return !xfs_fs_has_sickness(mp, -1U); | |
166 | } | |
167 | ||
168 | static inline bool | |
169 | xfs_rt_is_healthy(struct xfs_mount *mp) | |
170 | { | |
171 | return !xfs_rt_has_sickness(mp, -1U); | |
172 | } | |
173 | ||
174 | static inline bool | |
175 | xfs_ag_is_healthy(struct xfs_perag *pag) | |
176 | { | |
177 | return !xfs_ag_has_sickness(pag, -1U); | |
178 | } | |
179 | ||
180 | static inline bool | |
181 | xfs_inode_is_healthy(struct xfs_inode *ip) | |
182 | { | |
183 | return !xfs_inode_has_sickness(ip, -1U); | |
184 | } | |
185 | ||
69423ead | 186 | void xfs_fsop_geom_health(struct xfs_mount *mp, struct xfs_fsop_geom *geo); |
378d9e6d | 187 | void xfs_ag_geom_health(struct xfs_perag *pag, struct xfs_ag_geometry *ageo); |
79671ab5 | 188 | void xfs_bulkstat_health(struct xfs_inode *ip, struct xfs_bulkstat *bs); |
69423ead | 189 | |
f866934a | 190 | #endif /* __XFS_HEALTH_H__ */ |