.. | .. |
---|
9 | 9 | #include "xfs_format.h" |
---|
10 | 10 | #include "xfs_trans_resv.h" |
---|
11 | 11 | #include "xfs_mount.h" |
---|
12 | | -#include "xfs_defer.h" |
---|
13 | 12 | #include "xfs_btree.h" |
---|
14 | | -#include "xfs_bit.h" |
---|
15 | 13 | #include "xfs_log_format.h" |
---|
16 | 14 | #include "xfs_trans.h" |
---|
17 | 15 | #include "xfs_sb.h" |
---|
18 | 16 | #include "xfs_inode.h" |
---|
19 | 17 | #include "xfs_icache.h" |
---|
20 | | -#include "xfs_itable.h" |
---|
21 | 18 | #include "xfs_alloc.h" |
---|
22 | 19 | #include "xfs_alloc_btree.h" |
---|
23 | | -#include "xfs_bmap.h" |
---|
24 | | -#include "xfs_bmap_btree.h" |
---|
25 | 20 | #include "xfs_ialloc.h" |
---|
26 | 21 | #include "xfs_ialloc_btree.h" |
---|
27 | | -#include "xfs_refcount.h" |
---|
28 | 22 | #include "xfs_refcount_btree.h" |
---|
29 | 23 | #include "xfs_rmap.h" |
---|
30 | 24 | #include "xfs_rmap_btree.h" |
---|
.. | .. |
---|
32 | 26 | #include "xfs_trans_priv.h" |
---|
33 | 27 | #include "xfs_attr.h" |
---|
34 | 28 | #include "xfs_reflink.h" |
---|
35 | | -#include "scrub/xfs_scrub.h" |
---|
36 | 29 | #include "scrub/scrub.h" |
---|
37 | 30 | #include "scrub/common.h" |
---|
38 | 31 | #include "scrub/trace.h" |
---|
39 | | -#include "scrub/btree.h" |
---|
40 | 32 | #include "scrub/repair.h" |
---|
| 33 | +#include "scrub/health.h" |
---|
41 | 34 | |
---|
42 | 35 | /* Common code for the metadata scrubbers. */ |
---|
43 | 36 | |
---|
.. | .. |
---|
208 | 201 | trace_xchk_ino_preen(sc, ino, __return_address); |
---|
209 | 202 | } |
---|
210 | 203 | |
---|
| 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 | + |
---|
211 | 213 | /* Record a corrupt block. */ |
---|
212 | 214 | void |
---|
213 | 215 | xchk_block_set_corrupt( |
---|
.. | .. |
---|
313 | 315 | */ |
---|
314 | 316 | |
---|
315 | 317 | 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; |
---|
318 | 320 | }; |
---|
319 | 321 | |
---|
320 | 322 | STATIC int |
---|
.. | .. |
---|
347 | 349 | xchk_count_rmap_ownedby_ag( |
---|
348 | 350 | struct xfs_scrub *sc, |
---|
349 | 351 | struct xfs_btree_cur *cur, |
---|
350 | | - struct xfs_owner_info *oinfo, |
---|
| 352 | + const struct xfs_owner_info *oinfo, |
---|
351 | 353 | xfs_filblks_t *blocks) |
---|
352 | 354 | { |
---|
353 | | - struct xchk_rmap_ownedby_info sroi; |
---|
| 355 | + struct xchk_rmap_ownedby_info sroi = { |
---|
| 356 | + .oinfo = oinfo, |
---|
| 357 | + .blocks = blocks, |
---|
| 358 | + }; |
---|
354 | 359 | |
---|
355 | | - sroi.oinfo = oinfo; |
---|
356 | 360 | *blocks = 0; |
---|
357 | | - sroi.blocks = blocks; |
---|
358 | | - |
---|
359 | 361 | return xfs_rmap_query_all(cur, xchk_count_rmap_ownedby_irec, |
---|
360 | 362 | &sroi); |
---|
361 | 363 | } |
---|
.. | .. |
---|
458 | 460 | struct xfs_mount *mp = sc->mp; |
---|
459 | 461 | xfs_agnumber_t agno = sa->agno; |
---|
460 | 462 | |
---|
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)) { |
---|
462 | 466 | /* Set up a bnobt cursor for cross-referencing. */ |
---|
463 | 467 | sa->bno_cur = xfs_allocbt_init_cursor(mp, sc->tp, sa->agf_bp, |
---|
464 | 468 | agno, XFS_BTNUM_BNO); |
---|
465 | 469 | if (!sa->bno_cur) |
---|
466 | 470 | goto err; |
---|
| 471 | + } |
---|
467 | 472 | |
---|
| 473 | + if (sa->agf_bp && |
---|
| 474 | + xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_CNT)) { |
---|
468 | 475 | /* Set up a cntbt cursor for cross-referencing. */ |
---|
469 | 476 | sa->cnt_cur = xfs_allocbt_init_cursor(mp, sc->tp, sa->agf_bp, |
---|
470 | 477 | agno, XFS_BTNUM_CNT); |
---|
.. | .. |
---|
473 | 480 | } |
---|
474 | 481 | |
---|
475 | 482 | /* 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)) { |
---|
477 | 485 | sa->ino_cur = xfs_inobt_init_cursor(mp, sc->tp, sa->agi_bp, |
---|
478 | 486 | agno, XFS_BTNUM_INO); |
---|
479 | 487 | if (!sa->ino_cur) |
---|
.. | .. |
---|
481 | 489 | } |
---|
482 | 490 | |
---|
483 | 491 | /* 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)) { |
---|
485 | 494 | sa->fino_cur = xfs_inobt_init_cursor(mp, sc->tp, sa->agi_bp, |
---|
486 | 495 | agno, XFS_BTNUM_FINO); |
---|
487 | 496 | if (!sa->fino_cur) |
---|
.. | .. |
---|
489 | 498 | } |
---|
490 | 499 | |
---|
491 | 500 | /* 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)) { |
---|
493 | 503 | sa->rmap_cur = xfs_rmapbt_init_cursor(mp, sc->tp, sa->agf_bp, |
---|
494 | 504 | agno); |
---|
495 | 505 | if (!sa->rmap_cur) |
---|
.. | .. |
---|
497 | 507 | } |
---|
498 | 508 | |
---|
499 | 509 | /* 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)) { |
---|
501 | 512 | sa->refc_cur = xfs_refcountbt_init_cursor(mp, sc->tp, |
---|
502 | 513 | sa->agf_bp, agno); |
---|
503 | 514 | if (!sa->refc_cur) |
---|
.. | .. |
---|
884 | 895 | } |
---|
885 | 896 | return -EDEADLOCK; |
---|
886 | 897 | } |
---|
| 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 | +} |
---|