0001
0002
0003
0004
0005
0006 #include "xfs.h"
0007 #include "xfs_fs.h"
0008 #include "xfs_shared.h"
0009 #include "xfs_format.h"
0010 #include "xfs_log_format.h"
0011 #include "xfs_trans_resv.h"
0012 #include "xfs_mount.h"
0013 #include "xfs_inode.h"
0014 #include "xfs_trace.h"
0015 #include "xfs_health.h"
0016 #include "xfs_ag.h"
0017
0018
0019
0020
0021
0022
0023 void
0024 xfs_health_unmount(
0025 struct xfs_mount *mp)
0026 {
0027 struct xfs_perag *pag;
0028 xfs_agnumber_t agno;
0029 unsigned int sick = 0;
0030 unsigned int checked = 0;
0031 bool warn = false;
0032
0033 if (xfs_is_shutdown(mp))
0034 return;
0035
0036
0037 for_each_perag(mp, agno, pag) {
0038 xfs_ag_measure_sickness(pag, &sick, &checked);
0039 if (sick) {
0040 trace_xfs_ag_unfixed_corruption(mp, agno, sick);
0041 warn = true;
0042 }
0043 }
0044
0045
0046 xfs_rt_measure_sickness(mp, &sick, &checked);
0047 if (sick) {
0048 trace_xfs_rt_unfixed_corruption(mp, sick);
0049 warn = true;
0050 }
0051
0052
0053
0054
0055
0056 xfs_fs_measure_sickness(mp, &sick, &checked);
0057 if (sick & ~XFS_SICK_FS_COUNTERS) {
0058 trace_xfs_fs_unfixed_corruption(mp, sick);
0059 warn = true;
0060 }
0061
0062 if (warn) {
0063 xfs_warn(mp,
0064 "Uncorrected metadata errors detected; please run xfs_repair.");
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085 if (sick & XFS_SICK_FS_COUNTERS)
0086 xfs_fs_mark_healthy(mp, XFS_SICK_FS_COUNTERS);
0087 }
0088 }
0089
0090
0091 void
0092 xfs_fs_mark_sick(
0093 struct xfs_mount *mp,
0094 unsigned int mask)
0095 {
0096 ASSERT(!(mask & ~XFS_SICK_FS_PRIMARY));
0097 trace_xfs_fs_mark_sick(mp, mask);
0098
0099 spin_lock(&mp->m_sb_lock);
0100 mp->m_fs_sick |= mask;
0101 mp->m_fs_checked |= mask;
0102 spin_unlock(&mp->m_sb_lock);
0103 }
0104
0105
0106 void
0107 xfs_fs_mark_healthy(
0108 struct xfs_mount *mp,
0109 unsigned int mask)
0110 {
0111 ASSERT(!(mask & ~XFS_SICK_FS_PRIMARY));
0112 trace_xfs_fs_mark_healthy(mp, mask);
0113
0114 spin_lock(&mp->m_sb_lock);
0115 mp->m_fs_sick &= ~mask;
0116 mp->m_fs_checked |= mask;
0117 spin_unlock(&mp->m_sb_lock);
0118 }
0119
0120
0121 void
0122 xfs_fs_measure_sickness(
0123 struct xfs_mount *mp,
0124 unsigned int *sick,
0125 unsigned int *checked)
0126 {
0127 spin_lock(&mp->m_sb_lock);
0128 *sick = mp->m_fs_sick;
0129 *checked = mp->m_fs_checked;
0130 spin_unlock(&mp->m_sb_lock);
0131 }
0132
0133
0134 void
0135 xfs_rt_mark_sick(
0136 struct xfs_mount *mp,
0137 unsigned int mask)
0138 {
0139 ASSERT(!(mask & ~XFS_SICK_RT_PRIMARY));
0140 trace_xfs_rt_mark_sick(mp, mask);
0141
0142 spin_lock(&mp->m_sb_lock);
0143 mp->m_rt_sick |= mask;
0144 mp->m_rt_checked |= mask;
0145 spin_unlock(&mp->m_sb_lock);
0146 }
0147
0148
0149 void
0150 xfs_rt_mark_healthy(
0151 struct xfs_mount *mp,
0152 unsigned int mask)
0153 {
0154 ASSERT(!(mask & ~XFS_SICK_RT_PRIMARY));
0155 trace_xfs_rt_mark_healthy(mp, mask);
0156
0157 spin_lock(&mp->m_sb_lock);
0158 mp->m_rt_sick &= ~mask;
0159 mp->m_rt_checked |= mask;
0160 spin_unlock(&mp->m_sb_lock);
0161 }
0162
0163
0164 void
0165 xfs_rt_measure_sickness(
0166 struct xfs_mount *mp,
0167 unsigned int *sick,
0168 unsigned int *checked)
0169 {
0170 spin_lock(&mp->m_sb_lock);
0171 *sick = mp->m_rt_sick;
0172 *checked = mp->m_rt_checked;
0173 spin_unlock(&mp->m_sb_lock);
0174 }
0175
0176
0177 void
0178 xfs_ag_mark_sick(
0179 struct xfs_perag *pag,
0180 unsigned int mask)
0181 {
0182 ASSERT(!(mask & ~XFS_SICK_AG_PRIMARY));
0183 trace_xfs_ag_mark_sick(pag->pag_mount, pag->pag_agno, mask);
0184
0185 spin_lock(&pag->pag_state_lock);
0186 pag->pag_sick |= mask;
0187 pag->pag_checked |= mask;
0188 spin_unlock(&pag->pag_state_lock);
0189 }
0190
0191
0192 void
0193 xfs_ag_mark_healthy(
0194 struct xfs_perag *pag,
0195 unsigned int mask)
0196 {
0197 ASSERT(!(mask & ~XFS_SICK_AG_PRIMARY));
0198 trace_xfs_ag_mark_healthy(pag->pag_mount, pag->pag_agno, mask);
0199
0200 spin_lock(&pag->pag_state_lock);
0201 pag->pag_sick &= ~mask;
0202 pag->pag_checked |= mask;
0203 spin_unlock(&pag->pag_state_lock);
0204 }
0205
0206
0207 void
0208 xfs_ag_measure_sickness(
0209 struct xfs_perag *pag,
0210 unsigned int *sick,
0211 unsigned int *checked)
0212 {
0213 spin_lock(&pag->pag_state_lock);
0214 *sick = pag->pag_sick;
0215 *checked = pag->pag_checked;
0216 spin_unlock(&pag->pag_state_lock);
0217 }
0218
0219
0220 void
0221 xfs_inode_mark_sick(
0222 struct xfs_inode *ip,
0223 unsigned int mask)
0224 {
0225 ASSERT(!(mask & ~XFS_SICK_INO_PRIMARY));
0226 trace_xfs_inode_mark_sick(ip, mask);
0227
0228 spin_lock(&ip->i_flags_lock);
0229 ip->i_sick |= mask;
0230 ip->i_checked |= mask;
0231 spin_unlock(&ip->i_flags_lock);
0232
0233
0234
0235
0236
0237
0238 spin_lock(&VFS_I(ip)->i_lock);
0239 VFS_I(ip)->i_state &= ~I_DONTCACHE;
0240 spin_unlock(&VFS_I(ip)->i_lock);
0241 }
0242
0243
0244 void
0245 xfs_inode_mark_healthy(
0246 struct xfs_inode *ip,
0247 unsigned int mask)
0248 {
0249 ASSERT(!(mask & ~XFS_SICK_INO_PRIMARY));
0250 trace_xfs_inode_mark_healthy(ip, mask);
0251
0252 spin_lock(&ip->i_flags_lock);
0253 ip->i_sick &= ~mask;
0254 ip->i_checked |= mask;
0255 spin_unlock(&ip->i_flags_lock);
0256 }
0257
0258
0259 void
0260 xfs_inode_measure_sickness(
0261 struct xfs_inode *ip,
0262 unsigned int *sick,
0263 unsigned int *checked)
0264 {
0265 spin_lock(&ip->i_flags_lock);
0266 *sick = ip->i_sick;
0267 *checked = ip->i_checked;
0268 spin_unlock(&ip->i_flags_lock);
0269 }
0270
0271
0272
0273 struct ioctl_sick_map {
0274 unsigned int sick_mask;
0275 unsigned int ioctl_mask;
0276 };
0277
0278 static const struct ioctl_sick_map fs_map[] = {
0279 { XFS_SICK_FS_COUNTERS, XFS_FSOP_GEOM_SICK_COUNTERS},
0280 { XFS_SICK_FS_UQUOTA, XFS_FSOP_GEOM_SICK_UQUOTA },
0281 { XFS_SICK_FS_GQUOTA, XFS_FSOP_GEOM_SICK_GQUOTA },
0282 { XFS_SICK_FS_PQUOTA, XFS_FSOP_GEOM_SICK_PQUOTA },
0283 { 0, 0 },
0284 };
0285
0286 static const struct ioctl_sick_map rt_map[] = {
0287 { XFS_SICK_RT_BITMAP, XFS_FSOP_GEOM_SICK_RT_BITMAP },
0288 { XFS_SICK_RT_SUMMARY, XFS_FSOP_GEOM_SICK_RT_SUMMARY },
0289 { 0, 0 },
0290 };
0291
0292 static inline void
0293 xfgeo_health_tick(
0294 struct xfs_fsop_geom *geo,
0295 unsigned int sick,
0296 unsigned int checked,
0297 const struct ioctl_sick_map *m)
0298 {
0299 if (checked & m->sick_mask)
0300 geo->checked |= m->ioctl_mask;
0301 if (sick & m->sick_mask)
0302 geo->sick |= m->ioctl_mask;
0303 }
0304
0305
0306 void
0307 xfs_fsop_geom_health(
0308 struct xfs_mount *mp,
0309 struct xfs_fsop_geom *geo)
0310 {
0311 const struct ioctl_sick_map *m;
0312 unsigned int sick;
0313 unsigned int checked;
0314
0315 geo->sick = 0;
0316 geo->checked = 0;
0317
0318 xfs_fs_measure_sickness(mp, &sick, &checked);
0319 for (m = fs_map; m->sick_mask; m++)
0320 xfgeo_health_tick(geo, sick, checked, m);
0321
0322 xfs_rt_measure_sickness(mp, &sick, &checked);
0323 for (m = rt_map; m->sick_mask; m++)
0324 xfgeo_health_tick(geo, sick, checked, m);
0325 }
0326
0327 static const struct ioctl_sick_map ag_map[] = {
0328 { XFS_SICK_AG_SB, XFS_AG_GEOM_SICK_SB },
0329 { XFS_SICK_AG_AGF, XFS_AG_GEOM_SICK_AGF },
0330 { XFS_SICK_AG_AGFL, XFS_AG_GEOM_SICK_AGFL },
0331 { XFS_SICK_AG_AGI, XFS_AG_GEOM_SICK_AGI },
0332 { XFS_SICK_AG_BNOBT, XFS_AG_GEOM_SICK_BNOBT },
0333 { XFS_SICK_AG_CNTBT, XFS_AG_GEOM_SICK_CNTBT },
0334 { XFS_SICK_AG_INOBT, XFS_AG_GEOM_SICK_INOBT },
0335 { XFS_SICK_AG_FINOBT, XFS_AG_GEOM_SICK_FINOBT },
0336 { XFS_SICK_AG_RMAPBT, XFS_AG_GEOM_SICK_RMAPBT },
0337 { XFS_SICK_AG_REFCNTBT, XFS_AG_GEOM_SICK_REFCNTBT },
0338 { 0, 0 },
0339 };
0340
0341
0342 void
0343 xfs_ag_geom_health(
0344 struct xfs_perag *pag,
0345 struct xfs_ag_geometry *ageo)
0346 {
0347 const struct ioctl_sick_map *m;
0348 unsigned int sick;
0349 unsigned int checked;
0350
0351 ageo->ag_sick = 0;
0352 ageo->ag_checked = 0;
0353
0354 xfs_ag_measure_sickness(pag, &sick, &checked);
0355 for (m = ag_map; m->sick_mask; m++) {
0356 if (checked & m->sick_mask)
0357 ageo->ag_checked |= m->ioctl_mask;
0358 if (sick & m->sick_mask)
0359 ageo->ag_sick |= m->ioctl_mask;
0360 }
0361 }
0362
0363 static const struct ioctl_sick_map ino_map[] = {
0364 { XFS_SICK_INO_CORE, XFS_BS_SICK_INODE },
0365 { XFS_SICK_INO_BMBTD, XFS_BS_SICK_BMBTD },
0366 { XFS_SICK_INO_BMBTA, XFS_BS_SICK_BMBTA },
0367 { XFS_SICK_INO_BMBTC, XFS_BS_SICK_BMBTC },
0368 { XFS_SICK_INO_DIR, XFS_BS_SICK_DIR },
0369 { XFS_SICK_INO_XATTR, XFS_BS_SICK_XATTR },
0370 { XFS_SICK_INO_SYMLINK, XFS_BS_SICK_SYMLINK },
0371 { XFS_SICK_INO_PARENT, XFS_BS_SICK_PARENT },
0372 { 0, 0 },
0373 };
0374
0375
0376 void
0377 xfs_bulkstat_health(
0378 struct xfs_inode *ip,
0379 struct xfs_bulkstat *bs)
0380 {
0381 const struct ioctl_sick_map *m;
0382 unsigned int sick;
0383 unsigned int checked;
0384
0385 bs->bs_sick = 0;
0386 bs->bs_checked = 0;
0387
0388 xfs_inode_measure_sickness(ip, &sick, &checked);
0389 for (m = ino_map; m->sick_mask; m++) {
0390 if (checked & m->sick_mask)
0391 bs->bs_checked |= m->ioctl_mask;
0392 if (sick & m->sick_mask)
0393 bs->bs_sick |= m->ioctl_mask;
0394 }
0395 }