hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/xfs/scrub/common.c
....@@ -9,22 +9,16 @@
99 #include "xfs_format.h"
1010 #include "xfs_trans_resv.h"
1111 #include "xfs_mount.h"
12
-#include "xfs_defer.h"
1312 #include "xfs_btree.h"
14
-#include "xfs_bit.h"
1513 #include "xfs_log_format.h"
1614 #include "xfs_trans.h"
1715 #include "xfs_sb.h"
1816 #include "xfs_inode.h"
1917 #include "xfs_icache.h"
20
-#include "xfs_itable.h"
2118 #include "xfs_alloc.h"
2219 #include "xfs_alloc_btree.h"
23
-#include "xfs_bmap.h"
24
-#include "xfs_bmap_btree.h"
2520 #include "xfs_ialloc.h"
2621 #include "xfs_ialloc_btree.h"
27
-#include "xfs_refcount.h"
2822 #include "xfs_refcount_btree.h"
2923 #include "xfs_rmap.h"
3024 #include "xfs_rmap_btree.h"
....@@ -32,12 +26,11 @@
3226 #include "xfs_trans_priv.h"
3327 #include "xfs_attr.h"
3428 #include "xfs_reflink.h"
35
-#include "scrub/xfs_scrub.h"
3629 #include "scrub/scrub.h"
3730 #include "scrub/common.h"
3831 #include "scrub/trace.h"
39
-#include "scrub/btree.h"
4032 #include "scrub/repair.h"
33
+#include "scrub/health.h"
4134
4235 /* Common code for the metadata scrubbers. */
4336
....@@ -208,6 +201,15 @@
208201 trace_xchk_ino_preen(sc, ino, __return_address);
209202 }
210203
204
+/* Record something being wrong with the filesystem primary superblock. */
205
+void
206
+xchk_set_corrupt(
207
+ struct xfs_scrub *sc)
208
+{
209
+ sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
210
+ trace_xchk_fs_error(sc, 0, __return_address);
211
+}
212
+
211213 /* Record a corrupt block. */
212214 void
213215 xchk_block_set_corrupt(
....@@ -313,8 +315,8 @@
313315 */
314316
315317 struct xchk_rmap_ownedby_info {
316
- struct xfs_owner_info *oinfo;
317
- xfs_filblks_t *blocks;
318
+ const struct xfs_owner_info *oinfo;
319
+ xfs_filblks_t *blocks;
318320 };
319321
320322 STATIC int
....@@ -347,15 +349,15 @@
347349 xchk_count_rmap_ownedby_ag(
348350 struct xfs_scrub *sc,
349351 struct xfs_btree_cur *cur,
350
- struct xfs_owner_info *oinfo,
352
+ const struct xfs_owner_info *oinfo,
351353 xfs_filblks_t *blocks)
352354 {
353
- struct xchk_rmap_ownedby_info sroi;
355
+ struct xchk_rmap_ownedby_info sroi = {
356
+ .oinfo = oinfo,
357
+ .blocks = blocks,
358
+ };
354359
355
- sroi.oinfo = oinfo;
356360 *blocks = 0;
357
- sroi.blocks = blocks;
358
-
359361 return xfs_rmap_query_all(cur, xchk_count_rmap_ownedby_irec,
360362 &sroi);
361363 }
....@@ -458,13 +460,18 @@
458460 struct xfs_mount *mp = sc->mp;
459461 xfs_agnumber_t agno = sa->agno;
460462
461
- if (sa->agf_bp) {
463
+ xchk_perag_get(sc->mp, sa);
464
+ if (sa->agf_bp &&
465
+ xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_BNO)) {
462466 /* Set up a bnobt cursor for cross-referencing. */
463467 sa->bno_cur = xfs_allocbt_init_cursor(mp, sc->tp, sa->agf_bp,
464468 agno, XFS_BTNUM_BNO);
465469 if (!sa->bno_cur)
466470 goto err;
471
+ }
467472
473
+ if (sa->agf_bp &&
474
+ xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_CNT)) {
468475 /* Set up a cntbt cursor for cross-referencing. */
469476 sa->cnt_cur = xfs_allocbt_init_cursor(mp, sc->tp, sa->agf_bp,
470477 agno, XFS_BTNUM_CNT);
....@@ -473,7 +480,8 @@
473480 }
474481
475482 /* Set up a inobt cursor for cross-referencing. */
476
- if (sa->agi_bp) {
483
+ if (sa->agi_bp &&
484
+ xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_INO)) {
477485 sa->ino_cur = xfs_inobt_init_cursor(mp, sc->tp, sa->agi_bp,
478486 agno, XFS_BTNUM_INO);
479487 if (!sa->ino_cur)
....@@ -481,7 +489,8 @@
481489 }
482490
483491 /* Set up a finobt cursor for cross-referencing. */
484
- if (sa->agi_bp && xfs_sb_version_hasfinobt(&mp->m_sb)) {
492
+ if (sa->agi_bp && xfs_sb_version_hasfinobt(&mp->m_sb) &&
493
+ xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_FINO)) {
485494 sa->fino_cur = xfs_inobt_init_cursor(mp, sc->tp, sa->agi_bp,
486495 agno, XFS_BTNUM_FINO);
487496 if (!sa->fino_cur)
....@@ -489,7 +498,8 @@
489498 }
490499
491500 /* Set up a rmapbt cursor for cross-referencing. */
492
- if (sa->agf_bp && xfs_sb_version_hasrmapbt(&mp->m_sb)) {
501
+ if (sa->agf_bp && xfs_sb_version_hasrmapbt(&mp->m_sb) &&
502
+ xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_RMAP)) {
493503 sa->rmap_cur = xfs_rmapbt_init_cursor(mp, sc->tp, sa->agf_bp,
494504 agno);
495505 if (!sa->rmap_cur)
....@@ -497,7 +507,8 @@
497507 }
498508
499509 /* Set up a refcountbt cursor for cross-referencing. */
500
- if (sa->agf_bp && xfs_sb_version_hasreflink(&mp->m_sb)) {
510
+ if (sa->agf_bp && xfs_sb_version_hasreflink(&mp->m_sb) &&
511
+ xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_REFC)) {
501512 sa->refc_cur = xfs_refcountbt_init_cursor(mp, sc->tp,
502513 sa->agf_bp, agno);
503514 if (!sa->refc_cur)
....@@ -884,3 +895,21 @@
884895 }
885896 return -EDEADLOCK;
886897 }
898
+
899
+/* Pause background reaping of resources. */
900
+void
901
+xchk_stop_reaping(
902
+ struct xfs_scrub *sc)
903
+{
904
+ sc->flags |= XCHK_REAPING_DISABLED;
905
+ xfs_stop_block_reaping(sc->mp);
906
+}
907
+
908
+/* Restart background reaping of resources. */
909
+void
910
+xchk_start_reaping(
911
+ struct xfs_scrub *sc)
912
+{
913
+ xfs_start_block_reaping(sc->mp);
914
+ sc->flags &= ~XCHK_REAPING_DISABLED;
915
+}