xref: /OK3568_Linux_fs/kernel/fs/xfs/xfs_health.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2019 Oracle.  All Rights Reserved.
4*4882a593Smuzhiyun  * Author: Darrick J. Wong <darrick.wong@oracle.com>
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun #include "xfs.h"
7*4882a593Smuzhiyun #include "xfs_fs.h"
8*4882a593Smuzhiyun #include "xfs_shared.h"
9*4882a593Smuzhiyun #include "xfs_format.h"
10*4882a593Smuzhiyun #include "xfs_log_format.h"
11*4882a593Smuzhiyun #include "xfs_trans_resv.h"
12*4882a593Smuzhiyun #include "xfs_sb.h"
13*4882a593Smuzhiyun #include "xfs_mount.h"
14*4882a593Smuzhiyun #include "xfs_inode.h"
15*4882a593Smuzhiyun #include "xfs_trace.h"
16*4882a593Smuzhiyun #include "xfs_health.h"
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun /*
19*4882a593Smuzhiyun  * Warn about metadata corruption that we detected but haven't fixed, and
20*4882a593Smuzhiyun  * make sure we're not sitting on anything that would get in the way of
21*4882a593Smuzhiyun  * recovery.
22*4882a593Smuzhiyun  */
23*4882a593Smuzhiyun void
xfs_health_unmount(struct xfs_mount * mp)24*4882a593Smuzhiyun xfs_health_unmount(
25*4882a593Smuzhiyun 	struct xfs_mount	*mp)
26*4882a593Smuzhiyun {
27*4882a593Smuzhiyun 	struct xfs_perag	*pag;
28*4882a593Smuzhiyun 	xfs_agnumber_t		agno;
29*4882a593Smuzhiyun 	unsigned int		sick = 0;
30*4882a593Smuzhiyun 	unsigned int		checked = 0;
31*4882a593Smuzhiyun 	bool			warn = false;
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun 	if (XFS_FORCED_SHUTDOWN(mp))
34*4882a593Smuzhiyun 		return;
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun 	/* Measure AG corruption levels. */
37*4882a593Smuzhiyun 	for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
38*4882a593Smuzhiyun 		pag = xfs_perag_get(mp, agno);
39*4882a593Smuzhiyun 		xfs_ag_measure_sickness(pag, &sick, &checked);
40*4882a593Smuzhiyun 		if (sick) {
41*4882a593Smuzhiyun 			trace_xfs_ag_unfixed_corruption(mp, agno, sick);
42*4882a593Smuzhiyun 			warn = true;
43*4882a593Smuzhiyun 		}
44*4882a593Smuzhiyun 		xfs_perag_put(pag);
45*4882a593Smuzhiyun 	}
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun 	/* Measure realtime volume corruption levels. */
48*4882a593Smuzhiyun 	xfs_rt_measure_sickness(mp, &sick, &checked);
49*4882a593Smuzhiyun 	if (sick) {
50*4882a593Smuzhiyun 		trace_xfs_rt_unfixed_corruption(mp, sick);
51*4882a593Smuzhiyun 		warn = true;
52*4882a593Smuzhiyun 	}
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	/*
55*4882a593Smuzhiyun 	 * Measure fs corruption and keep the sample around for the warning.
56*4882a593Smuzhiyun 	 * See the note below for why we exempt FS_COUNTERS.
57*4882a593Smuzhiyun 	 */
58*4882a593Smuzhiyun 	xfs_fs_measure_sickness(mp, &sick, &checked);
59*4882a593Smuzhiyun 	if (sick & ~XFS_SICK_FS_COUNTERS) {
60*4882a593Smuzhiyun 		trace_xfs_fs_unfixed_corruption(mp, sick);
61*4882a593Smuzhiyun 		warn = true;
62*4882a593Smuzhiyun 	}
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 	if (warn) {
65*4882a593Smuzhiyun 		xfs_warn(mp,
66*4882a593Smuzhiyun "Uncorrected metadata errors detected; please run xfs_repair.");
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun 		/*
69*4882a593Smuzhiyun 		 * We discovered uncorrected metadata problems at some point
70*4882a593Smuzhiyun 		 * during this filesystem mount and have advised the
71*4882a593Smuzhiyun 		 * administrator to run repair once the unmount completes.
72*4882a593Smuzhiyun 		 *
73*4882a593Smuzhiyun 		 * However, we must be careful -- when FSCOUNTERS are flagged
74*4882a593Smuzhiyun 		 * unhealthy, the unmount procedure omits writing the clean
75*4882a593Smuzhiyun 		 * unmount record to the log so that the next mount will run
76*4882a593Smuzhiyun 		 * recovery and recompute the summary counters.  In other
77*4882a593Smuzhiyun 		 * words, we leave a dirty log to get the counters fixed.
78*4882a593Smuzhiyun 		 *
79*4882a593Smuzhiyun 		 * Unfortunately, xfs_repair cannot recover dirty logs, so if
80*4882a593Smuzhiyun 		 * there were filesystem problems, FSCOUNTERS was flagged, and
81*4882a593Smuzhiyun 		 * the administrator takes our advice to run xfs_repair,
82*4882a593Smuzhiyun 		 * they'll have to zap the log before repairing structures.
83*4882a593Smuzhiyun 		 * We don't really want to encourage this, so we mark the
84*4882a593Smuzhiyun 		 * FSCOUNTERS healthy so that a subsequent repair run won't see
85*4882a593Smuzhiyun 		 * a dirty log.
86*4882a593Smuzhiyun 		 */
87*4882a593Smuzhiyun 		if (sick & XFS_SICK_FS_COUNTERS)
88*4882a593Smuzhiyun 			xfs_fs_mark_healthy(mp, XFS_SICK_FS_COUNTERS);
89*4882a593Smuzhiyun 	}
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun /* Mark unhealthy per-fs metadata. */
93*4882a593Smuzhiyun void
xfs_fs_mark_sick(struct xfs_mount * mp,unsigned int mask)94*4882a593Smuzhiyun xfs_fs_mark_sick(
95*4882a593Smuzhiyun 	struct xfs_mount	*mp,
96*4882a593Smuzhiyun 	unsigned int		mask)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun 	ASSERT(!(mask & ~XFS_SICK_FS_PRIMARY));
99*4882a593Smuzhiyun 	trace_xfs_fs_mark_sick(mp, mask);
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	spin_lock(&mp->m_sb_lock);
102*4882a593Smuzhiyun 	mp->m_fs_sick |= mask;
103*4882a593Smuzhiyun 	mp->m_fs_checked |= mask;
104*4882a593Smuzhiyun 	spin_unlock(&mp->m_sb_lock);
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun /* Mark a per-fs metadata healed. */
108*4882a593Smuzhiyun void
xfs_fs_mark_healthy(struct xfs_mount * mp,unsigned int mask)109*4882a593Smuzhiyun xfs_fs_mark_healthy(
110*4882a593Smuzhiyun 	struct xfs_mount	*mp,
111*4882a593Smuzhiyun 	unsigned int		mask)
112*4882a593Smuzhiyun {
113*4882a593Smuzhiyun 	ASSERT(!(mask & ~XFS_SICK_FS_PRIMARY));
114*4882a593Smuzhiyun 	trace_xfs_fs_mark_healthy(mp, mask);
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	spin_lock(&mp->m_sb_lock);
117*4882a593Smuzhiyun 	mp->m_fs_sick &= ~mask;
118*4882a593Smuzhiyun 	mp->m_fs_checked |= mask;
119*4882a593Smuzhiyun 	spin_unlock(&mp->m_sb_lock);
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun /* Sample which per-fs metadata are unhealthy. */
123*4882a593Smuzhiyun void
xfs_fs_measure_sickness(struct xfs_mount * mp,unsigned int * sick,unsigned int * checked)124*4882a593Smuzhiyun xfs_fs_measure_sickness(
125*4882a593Smuzhiyun 	struct xfs_mount	*mp,
126*4882a593Smuzhiyun 	unsigned int		*sick,
127*4882a593Smuzhiyun 	unsigned int		*checked)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun 	spin_lock(&mp->m_sb_lock);
130*4882a593Smuzhiyun 	*sick = mp->m_fs_sick;
131*4882a593Smuzhiyun 	*checked = mp->m_fs_checked;
132*4882a593Smuzhiyun 	spin_unlock(&mp->m_sb_lock);
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun /* Mark unhealthy realtime metadata. */
136*4882a593Smuzhiyun void
xfs_rt_mark_sick(struct xfs_mount * mp,unsigned int mask)137*4882a593Smuzhiyun xfs_rt_mark_sick(
138*4882a593Smuzhiyun 	struct xfs_mount	*mp,
139*4882a593Smuzhiyun 	unsigned int		mask)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun 	ASSERT(!(mask & ~XFS_SICK_RT_PRIMARY));
142*4882a593Smuzhiyun 	trace_xfs_rt_mark_sick(mp, mask);
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 	spin_lock(&mp->m_sb_lock);
145*4882a593Smuzhiyun 	mp->m_rt_sick |= mask;
146*4882a593Smuzhiyun 	mp->m_rt_checked |= mask;
147*4882a593Smuzhiyun 	spin_unlock(&mp->m_sb_lock);
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun /* Mark a realtime metadata healed. */
151*4882a593Smuzhiyun void
xfs_rt_mark_healthy(struct xfs_mount * mp,unsigned int mask)152*4882a593Smuzhiyun xfs_rt_mark_healthy(
153*4882a593Smuzhiyun 	struct xfs_mount	*mp,
154*4882a593Smuzhiyun 	unsigned int		mask)
155*4882a593Smuzhiyun {
156*4882a593Smuzhiyun 	ASSERT(!(mask & ~XFS_SICK_RT_PRIMARY));
157*4882a593Smuzhiyun 	trace_xfs_rt_mark_healthy(mp, mask);
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	spin_lock(&mp->m_sb_lock);
160*4882a593Smuzhiyun 	mp->m_rt_sick &= ~mask;
161*4882a593Smuzhiyun 	mp->m_rt_checked |= mask;
162*4882a593Smuzhiyun 	spin_unlock(&mp->m_sb_lock);
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun /* Sample which realtime metadata are unhealthy. */
166*4882a593Smuzhiyun void
xfs_rt_measure_sickness(struct xfs_mount * mp,unsigned int * sick,unsigned int * checked)167*4882a593Smuzhiyun xfs_rt_measure_sickness(
168*4882a593Smuzhiyun 	struct xfs_mount	*mp,
169*4882a593Smuzhiyun 	unsigned int		*sick,
170*4882a593Smuzhiyun 	unsigned int		*checked)
171*4882a593Smuzhiyun {
172*4882a593Smuzhiyun 	spin_lock(&mp->m_sb_lock);
173*4882a593Smuzhiyun 	*sick = mp->m_rt_sick;
174*4882a593Smuzhiyun 	*checked = mp->m_rt_checked;
175*4882a593Smuzhiyun 	spin_unlock(&mp->m_sb_lock);
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun /* Mark unhealthy per-ag metadata. */
179*4882a593Smuzhiyun void
xfs_ag_mark_sick(struct xfs_perag * pag,unsigned int mask)180*4882a593Smuzhiyun xfs_ag_mark_sick(
181*4882a593Smuzhiyun 	struct xfs_perag	*pag,
182*4882a593Smuzhiyun 	unsigned int		mask)
183*4882a593Smuzhiyun {
184*4882a593Smuzhiyun 	ASSERT(!(mask & ~XFS_SICK_AG_PRIMARY));
185*4882a593Smuzhiyun 	trace_xfs_ag_mark_sick(pag->pag_mount, pag->pag_agno, mask);
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 	spin_lock(&pag->pag_state_lock);
188*4882a593Smuzhiyun 	pag->pag_sick |= mask;
189*4882a593Smuzhiyun 	pag->pag_checked |= mask;
190*4882a593Smuzhiyun 	spin_unlock(&pag->pag_state_lock);
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun /* Mark per-ag metadata ok. */
194*4882a593Smuzhiyun void
xfs_ag_mark_healthy(struct xfs_perag * pag,unsigned int mask)195*4882a593Smuzhiyun xfs_ag_mark_healthy(
196*4882a593Smuzhiyun 	struct xfs_perag	*pag,
197*4882a593Smuzhiyun 	unsigned int		mask)
198*4882a593Smuzhiyun {
199*4882a593Smuzhiyun 	ASSERT(!(mask & ~XFS_SICK_AG_PRIMARY));
200*4882a593Smuzhiyun 	trace_xfs_ag_mark_healthy(pag->pag_mount, pag->pag_agno, mask);
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	spin_lock(&pag->pag_state_lock);
203*4882a593Smuzhiyun 	pag->pag_sick &= ~mask;
204*4882a593Smuzhiyun 	pag->pag_checked |= mask;
205*4882a593Smuzhiyun 	spin_unlock(&pag->pag_state_lock);
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun /* Sample which per-ag metadata are unhealthy. */
209*4882a593Smuzhiyun void
xfs_ag_measure_sickness(struct xfs_perag * pag,unsigned int * sick,unsigned int * checked)210*4882a593Smuzhiyun xfs_ag_measure_sickness(
211*4882a593Smuzhiyun 	struct xfs_perag	*pag,
212*4882a593Smuzhiyun 	unsigned int		*sick,
213*4882a593Smuzhiyun 	unsigned int		*checked)
214*4882a593Smuzhiyun {
215*4882a593Smuzhiyun 	spin_lock(&pag->pag_state_lock);
216*4882a593Smuzhiyun 	*sick = pag->pag_sick;
217*4882a593Smuzhiyun 	*checked = pag->pag_checked;
218*4882a593Smuzhiyun 	spin_unlock(&pag->pag_state_lock);
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun /* Mark the unhealthy parts of an inode. */
222*4882a593Smuzhiyun void
xfs_inode_mark_sick(struct xfs_inode * ip,unsigned int mask)223*4882a593Smuzhiyun xfs_inode_mark_sick(
224*4882a593Smuzhiyun 	struct xfs_inode	*ip,
225*4882a593Smuzhiyun 	unsigned int		mask)
226*4882a593Smuzhiyun {
227*4882a593Smuzhiyun 	ASSERT(!(mask & ~XFS_SICK_INO_PRIMARY));
228*4882a593Smuzhiyun 	trace_xfs_inode_mark_sick(ip, mask);
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	spin_lock(&ip->i_flags_lock);
231*4882a593Smuzhiyun 	ip->i_sick |= mask;
232*4882a593Smuzhiyun 	ip->i_checked |= mask;
233*4882a593Smuzhiyun 	spin_unlock(&ip->i_flags_lock);
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun /* Mark parts of an inode healed. */
237*4882a593Smuzhiyun void
xfs_inode_mark_healthy(struct xfs_inode * ip,unsigned int mask)238*4882a593Smuzhiyun xfs_inode_mark_healthy(
239*4882a593Smuzhiyun 	struct xfs_inode	*ip,
240*4882a593Smuzhiyun 	unsigned int		mask)
241*4882a593Smuzhiyun {
242*4882a593Smuzhiyun 	ASSERT(!(mask & ~XFS_SICK_INO_PRIMARY));
243*4882a593Smuzhiyun 	trace_xfs_inode_mark_healthy(ip, mask);
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	spin_lock(&ip->i_flags_lock);
246*4882a593Smuzhiyun 	ip->i_sick &= ~mask;
247*4882a593Smuzhiyun 	ip->i_checked |= mask;
248*4882a593Smuzhiyun 	spin_unlock(&ip->i_flags_lock);
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun /* Sample which parts of an inode are unhealthy. */
252*4882a593Smuzhiyun void
xfs_inode_measure_sickness(struct xfs_inode * ip,unsigned int * sick,unsigned int * checked)253*4882a593Smuzhiyun xfs_inode_measure_sickness(
254*4882a593Smuzhiyun 	struct xfs_inode	*ip,
255*4882a593Smuzhiyun 	unsigned int		*sick,
256*4882a593Smuzhiyun 	unsigned int		*checked)
257*4882a593Smuzhiyun {
258*4882a593Smuzhiyun 	spin_lock(&ip->i_flags_lock);
259*4882a593Smuzhiyun 	*sick = ip->i_sick;
260*4882a593Smuzhiyun 	*checked = ip->i_checked;
261*4882a593Smuzhiyun 	spin_unlock(&ip->i_flags_lock);
262*4882a593Smuzhiyun }
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun /* Mappings between internal sick masks and ioctl sick masks. */
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun struct ioctl_sick_map {
267*4882a593Smuzhiyun 	unsigned int		sick_mask;
268*4882a593Smuzhiyun 	unsigned int		ioctl_mask;
269*4882a593Smuzhiyun };
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun static const struct ioctl_sick_map fs_map[] = {
272*4882a593Smuzhiyun 	{ XFS_SICK_FS_COUNTERS,	XFS_FSOP_GEOM_SICK_COUNTERS},
273*4882a593Smuzhiyun 	{ XFS_SICK_FS_UQUOTA,	XFS_FSOP_GEOM_SICK_UQUOTA },
274*4882a593Smuzhiyun 	{ XFS_SICK_FS_GQUOTA,	XFS_FSOP_GEOM_SICK_GQUOTA },
275*4882a593Smuzhiyun 	{ XFS_SICK_FS_PQUOTA,	XFS_FSOP_GEOM_SICK_PQUOTA },
276*4882a593Smuzhiyun 	{ 0, 0 },
277*4882a593Smuzhiyun };
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun static const struct ioctl_sick_map rt_map[] = {
280*4882a593Smuzhiyun 	{ XFS_SICK_RT_BITMAP,	XFS_FSOP_GEOM_SICK_RT_BITMAP },
281*4882a593Smuzhiyun 	{ XFS_SICK_RT_SUMMARY,	XFS_FSOP_GEOM_SICK_RT_SUMMARY },
282*4882a593Smuzhiyun 	{ 0, 0 },
283*4882a593Smuzhiyun };
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun static inline void
xfgeo_health_tick(struct xfs_fsop_geom * geo,unsigned int sick,unsigned int checked,const struct ioctl_sick_map * m)286*4882a593Smuzhiyun xfgeo_health_tick(
287*4882a593Smuzhiyun 	struct xfs_fsop_geom		*geo,
288*4882a593Smuzhiyun 	unsigned int			sick,
289*4882a593Smuzhiyun 	unsigned int			checked,
290*4882a593Smuzhiyun 	const struct ioctl_sick_map	*m)
291*4882a593Smuzhiyun {
292*4882a593Smuzhiyun 	if (checked & m->sick_mask)
293*4882a593Smuzhiyun 		geo->checked |= m->ioctl_mask;
294*4882a593Smuzhiyun 	if (sick & m->sick_mask)
295*4882a593Smuzhiyun 		geo->sick |= m->ioctl_mask;
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun /* Fill out fs geometry health info. */
299*4882a593Smuzhiyun void
xfs_fsop_geom_health(struct xfs_mount * mp,struct xfs_fsop_geom * geo)300*4882a593Smuzhiyun xfs_fsop_geom_health(
301*4882a593Smuzhiyun 	struct xfs_mount		*mp,
302*4882a593Smuzhiyun 	struct xfs_fsop_geom		*geo)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun 	const struct ioctl_sick_map	*m;
305*4882a593Smuzhiyun 	unsigned int			sick;
306*4882a593Smuzhiyun 	unsigned int			checked;
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun 	geo->sick = 0;
309*4882a593Smuzhiyun 	geo->checked = 0;
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	xfs_fs_measure_sickness(mp, &sick, &checked);
312*4882a593Smuzhiyun 	for (m = fs_map; m->sick_mask; m++)
313*4882a593Smuzhiyun 		xfgeo_health_tick(geo, sick, checked, m);
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 	xfs_rt_measure_sickness(mp, &sick, &checked);
316*4882a593Smuzhiyun 	for (m = rt_map; m->sick_mask; m++)
317*4882a593Smuzhiyun 		xfgeo_health_tick(geo, sick, checked, m);
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun static const struct ioctl_sick_map ag_map[] = {
321*4882a593Smuzhiyun 	{ XFS_SICK_AG_SB,	XFS_AG_GEOM_SICK_SB },
322*4882a593Smuzhiyun 	{ XFS_SICK_AG_AGF,	XFS_AG_GEOM_SICK_AGF },
323*4882a593Smuzhiyun 	{ XFS_SICK_AG_AGFL,	XFS_AG_GEOM_SICK_AGFL },
324*4882a593Smuzhiyun 	{ XFS_SICK_AG_AGI,	XFS_AG_GEOM_SICK_AGI },
325*4882a593Smuzhiyun 	{ XFS_SICK_AG_BNOBT,	XFS_AG_GEOM_SICK_BNOBT },
326*4882a593Smuzhiyun 	{ XFS_SICK_AG_CNTBT,	XFS_AG_GEOM_SICK_CNTBT },
327*4882a593Smuzhiyun 	{ XFS_SICK_AG_INOBT,	XFS_AG_GEOM_SICK_INOBT },
328*4882a593Smuzhiyun 	{ XFS_SICK_AG_FINOBT,	XFS_AG_GEOM_SICK_FINOBT },
329*4882a593Smuzhiyun 	{ XFS_SICK_AG_RMAPBT,	XFS_AG_GEOM_SICK_RMAPBT },
330*4882a593Smuzhiyun 	{ XFS_SICK_AG_REFCNTBT,	XFS_AG_GEOM_SICK_REFCNTBT },
331*4882a593Smuzhiyun 	{ 0, 0 },
332*4882a593Smuzhiyun };
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun /* Fill out ag geometry health info. */
335*4882a593Smuzhiyun void
xfs_ag_geom_health(struct xfs_perag * pag,struct xfs_ag_geometry * ageo)336*4882a593Smuzhiyun xfs_ag_geom_health(
337*4882a593Smuzhiyun 	struct xfs_perag		*pag,
338*4882a593Smuzhiyun 	struct xfs_ag_geometry		*ageo)
339*4882a593Smuzhiyun {
340*4882a593Smuzhiyun 	const struct ioctl_sick_map	*m;
341*4882a593Smuzhiyun 	unsigned int			sick;
342*4882a593Smuzhiyun 	unsigned int			checked;
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun 	ageo->ag_sick = 0;
345*4882a593Smuzhiyun 	ageo->ag_checked = 0;
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	xfs_ag_measure_sickness(pag, &sick, &checked);
348*4882a593Smuzhiyun 	for (m = ag_map; m->sick_mask; m++) {
349*4882a593Smuzhiyun 		if (checked & m->sick_mask)
350*4882a593Smuzhiyun 			ageo->ag_checked |= m->ioctl_mask;
351*4882a593Smuzhiyun 		if (sick & m->sick_mask)
352*4882a593Smuzhiyun 			ageo->ag_sick |= m->ioctl_mask;
353*4882a593Smuzhiyun 	}
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun static const struct ioctl_sick_map ino_map[] = {
357*4882a593Smuzhiyun 	{ XFS_SICK_INO_CORE,	XFS_BS_SICK_INODE },
358*4882a593Smuzhiyun 	{ XFS_SICK_INO_BMBTD,	XFS_BS_SICK_BMBTD },
359*4882a593Smuzhiyun 	{ XFS_SICK_INO_BMBTA,	XFS_BS_SICK_BMBTA },
360*4882a593Smuzhiyun 	{ XFS_SICK_INO_BMBTC,	XFS_BS_SICK_BMBTC },
361*4882a593Smuzhiyun 	{ XFS_SICK_INO_DIR,	XFS_BS_SICK_DIR },
362*4882a593Smuzhiyun 	{ XFS_SICK_INO_XATTR,	XFS_BS_SICK_XATTR },
363*4882a593Smuzhiyun 	{ XFS_SICK_INO_SYMLINK,	XFS_BS_SICK_SYMLINK },
364*4882a593Smuzhiyun 	{ XFS_SICK_INO_PARENT,	XFS_BS_SICK_PARENT },
365*4882a593Smuzhiyun 	{ 0, 0 },
366*4882a593Smuzhiyun };
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun /* Fill out bulkstat health info. */
369*4882a593Smuzhiyun void
xfs_bulkstat_health(struct xfs_inode * ip,struct xfs_bulkstat * bs)370*4882a593Smuzhiyun xfs_bulkstat_health(
371*4882a593Smuzhiyun 	struct xfs_inode		*ip,
372*4882a593Smuzhiyun 	struct xfs_bulkstat		*bs)
373*4882a593Smuzhiyun {
374*4882a593Smuzhiyun 	const struct ioctl_sick_map	*m;
375*4882a593Smuzhiyun 	unsigned int			sick;
376*4882a593Smuzhiyun 	unsigned int			checked;
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 	bs->bs_sick = 0;
379*4882a593Smuzhiyun 	bs->bs_checked = 0;
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun 	xfs_inode_measure_sickness(ip, &sick, &checked);
382*4882a593Smuzhiyun 	for (m = ino_map; m->sick_mask; m++) {
383*4882a593Smuzhiyun 		if (checked & m->sick_mask)
384*4882a593Smuzhiyun 			bs->bs_checked |= m->ioctl_mask;
385*4882a593Smuzhiyun 		if (sick & m->sick_mask)
386*4882a593Smuzhiyun 			bs->bs_sick |= m->ioctl_mask;
387*4882a593Smuzhiyun 	}
388*4882a593Smuzhiyun }
389