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