.. | .. |
---|
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 | | -#include "xfs_inode.h" |
---|
19 | 16 | #include "xfs_alloc.h" |
---|
20 | 17 | #include "xfs_alloc_btree.h" |
---|
21 | 18 | #include "xfs_ialloc.h" |
---|
22 | 19 | #include "xfs_ialloc_btree.h" |
---|
23 | 20 | #include "xfs_rmap.h" |
---|
24 | 21 | #include "xfs_rmap_btree.h" |
---|
25 | | -#include "xfs_refcount.h" |
---|
26 | 22 | #include "xfs_refcount_btree.h" |
---|
27 | | -#include "scrub/xfs_scrub.h" |
---|
28 | 23 | #include "scrub/scrub.h" |
---|
29 | 24 | #include "scrub/common.h" |
---|
30 | 25 | #include "scrub/trace.h" |
---|
.. | .. |
---|
54 | 49 | |
---|
55 | 50 | /* Copy AG 0's superblock to this one. */ |
---|
56 | 51 | xfs_buf_zero(bp, 0, BBTOB(bp->b_length)); |
---|
57 | | - xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb); |
---|
| 52 | + xfs_sb_to_disk(bp->b_addr, &mp->m_sb); |
---|
58 | 53 | |
---|
59 | 54 | /* Write this to disk. */ |
---|
60 | 55 | xfs_trans_buf_set_type(sc->tp, bp, XFS_BLFT_SB_BUF); |
---|
.. | .. |
---|
145 | 140 | struct xrep_find_ag_btree *fab, |
---|
146 | 141 | struct xfs_buf *agfl_bp) |
---|
147 | 142 | { |
---|
148 | | - struct xfs_agf *old_agf = XFS_BUF_TO_AGF(agf_bp); |
---|
| 143 | + struct xfs_agf *old_agf = agf_bp->b_addr; |
---|
149 | 144 | int error; |
---|
150 | 145 | |
---|
151 | 146 | /* Go find the root data. */ |
---|
.. | .. |
---|
186 | 181 | struct xfs_agf *old_agf) |
---|
187 | 182 | { |
---|
188 | 183 | struct xfs_mount *mp = sc->mp; |
---|
189 | | - struct xfs_agf *agf = XFS_BUF_TO_AGF(agf_bp); |
---|
| 184 | + struct xfs_agf *agf = agf_bp->b_addr; |
---|
190 | 185 | |
---|
191 | 186 | memcpy(old_agf, agf, sizeof(*old_agf)); |
---|
192 | 187 | memset(agf, 0, BBTOB(agf_bp->b_length)); |
---|
.. | .. |
---|
243 | 238 | { |
---|
244 | 239 | struct xrep_agf_allocbt raa = { .sc = sc }; |
---|
245 | 240 | struct xfs_btree_cur *cur = NULL; |
---|
246 | | - struct xfs_agf *agf = XFS_BUF_TO_AGF(agf_bp); |
---|
| 241 | + struct xfs_agf *agf = agf_bp->b_addr; |
---|
247 | 242 | struct xfs_mount *mp = sc->mp; |
---|
248 | 243 | xfs_agblock_t btreeblks; |
---|
249 | 244 | xfs_agblock_t blocks; |
---|
.. | .. |
---|
307 | 302 | struct xfs_buf *agf_bp) |
---|
308 | 303 | { |
---|
309 | 304 | struct xfs_perag *pag; |
---|
310 | | - struct xfs_agf *agf = XFS_BUF_TO_AGF(agf_bp); |
---|
| 305 | + struct xfs_agf *agf = agf_bp->b_addr; |
---|
311 | 306 | |
---|
312 | 307 | /* Trigger fdblocks recalculation */ |
---|
313 | 308 | xfs_force_summary_recalc(sc->mp); |
---|
.. | .. |
---|
341 | 336 | struct xrep_find_ag_btree fab[XREP_AGF_MAX] = { |
---|
342 | 337 | [XREP_AGF_BNOBT] = { |
---|
343 | 338 | .rmap_owner = XFS_RMAP_OWN_AG, |
---|
344 | | - .buf_ops = &xfs_allocbt_buf_ops, |
---|
345 | | - .magic = XFS_ABTB_CRC_MAGIC, |
---|
| 339 | + .buf_ops = &xfs_bnobt_buf_ops, |
---|
346 | 340 | }, |
---|
347 | 341 | [XREP_AGF_CNTBT] = { |
---|
348 | 342 | .rmap_owner = XFS_RMAP_OWN_AG, |
---|
349 | | - .buf_ops = &xfs_allocbt_buf_ops, |
---|
350 | | - .magic = XFS_ABTC_CRC_MAGIC, |
---|
| 343 | + .buf_ops = &xfs_cntbt_buf_ops, |
---|
351 | 344 | }, |
---|
352 | 345 | [XREP_AGF_RMAPBT] = { |
---|
353 | 346 | .rmap_owner = XFS_RMAP_OWN_AG, |
---|
354 | 347 | .buf_ops = &xfs_rmapbt_buf_ops, |
---|
355 | | - .magic = XFS_RMAP_CRC_MAGIC, |
---|
356 | 348 | }, |
---|
357 | 349 | [XREP_AGF_REFCOUNTBT] = { |
---|
358 | 350 | .rmap_owner = XFS_RMAP_OWN_REFC, |
---|
359 | 351 | .buf_ops = &xfs_refcountbt_buf_ops, |
---|
360 | | - .magic = XFS_REFC_CRC_MAGIC, |
---|
361 | 352 | }, |
---|
362 | 353 | [XREP_AGF_END] = { |
---|
363 | 354 | .buf_ops = NULL, |
---|
.. | .. |
---|
385 | 376 | if (error) |
---|
386 | 377 | return error; |
---|
387 | 378 | agf_bp->b_ops = &xfs_agf_buf_ops; |
---|
388 | | - agf = XFS_BUF_TO_AGF(agf_bp); |
---|
| 379 | + agf = agf_bp->b_addr; |
---|
389 | 380 | |
---|
390 | 381 | /* |
---|
391 | 382 | * Load the AGFL so that we can screen out OWN_AG blocks that are on |
---|
.. | .. |
---|
404 | 395 | * Spot-check the AGFL blocks; if they're obviously corrupt then |
---|
405 | 396 | * there's nothing we can do but bail out. |
---|
406 | 397 | */ |
---|
407 | | - error = xfs_agfl_walk(sc->mp, XFS_BUF_TO_AGF(agf_bp), agfl_bp, |
---|
| 398 | + error = xfs_agfl_walk(sc->mp, agf_bp->b_addr, agfl_bp, |
---|
408 | 399 | xrep_agf_check_agfl_block, sc); |
---|
409 | 400 | if (error) |
---|
410 | 401 | return error; |
---|
.. | .. |
---|
438 | 429 | |
---|
439 | 430 | struct xrep_agfl { |
---|
440 | 431 | /* Bitmap of other OWN_AG metadata blocks. */ |
---|
441 | | - struct xfs_bitmap agmetablocks; |
---|
| 432 | + struct xbitmap agmetablocks; |
---|
442 | 433 | |
---|
443 | 434 | /* Bitmap of free space. */ |
---|
444 | | - struct xfs_bitmap *freesp; |
---|
| 435 | + struct xbitmap *freesp; |
---|
445 | 436 | |
---|
446 | 437 | struct xfs_scrub *sc; |
---|
447 | 438 | }; |
---|
.. | .. |
---|
462 | 453 | |
---|
463 | 454 | /* Record all the OWN_AG blocks. */ |
---|
464 | 455 | if (rec->rm_owner == XFS_RMAP_OWN_AG) { |
---|
465 | | - fsb = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_private.a.agno, |
---|
| 456 | + fsb = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_ag.agno, |
---|
466 | 457 | rec->rm_startblock); |
---|
467 | | - error = xfs_bitmap_set(ra->freesp, fsb, rec->rm_blockcount); |
---|
| 458 | + error = xbitmap_set(ra->freesp, fsb, rec->rm_blockcount); |
---|
468 | 459 | if (error) |
---|
469 | 460 | return error; |
---|
470 | 461 | } |
---|
471 | 462 | |
---|
472 | | - return xfs_bitmap_set_btcur_path(&ra->agmetablocks, cur); |
---|
| 463 | + return xbitmap_set_btcur_path(&ra->agmetablocks, cur); |
---|
473 | 464 | } |
---|
474 | 465 | |
---|
475 | 466 | /* |
---|
.. | .. |
---|
485 | 476 | xrep_agfl_collect_blocks( |
---|
486 | 477 | struct xfs_scrub *sc, |
---|
487 | 478 | struct xfs_buf *agf_bp, |
---|
488 | | - struct xfs_bitmap *agfl_extents, |
---|
| 479 | + struct xbitmap *agfl_extents, |
---|
489 | 480 | xfs_agblock_t *flcount) |
---|
490 | 481 | { |
---|
491 | 482 | struct xrep_agfl ra; |
---|
492 | 483 | struct xfs_mount *mp = sc->mp; |
---|
493 | 484 | struct xfs_btree_cur *cur; |
---|
494 | | - struct xfs_bitmap_range *br; |
---|
495 | | - struct xfs_bitmap_range *n; |
---|
496 | 485 | int error; |
---|
497 | 486 | |
---|
498 | 487 | ra.sc = sc; |
---|
499 | 488 | ra.freesp = agfl_extents; |
---|
500 | | - xfs_bitmap_init(&ra.agmetablocks); |
---|
| 489 | + xbitmap_init(&ra.agmetablocks); |
---|
501 | 490 | |
---|
502 | 491 | /* Find all space used by the free space btrees & rmapbt. */ |
---|
503 | 492 | cur = xfs_rmapbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.agno); |
---|
.. | .. |
---|
509 | 498 | /* Find all blocks currently being used by the bnobt. */ |
---|
510 | 499 | cur = xfs_allocbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.agno, |
---|
511 | 500 | XFS_BTNUM_BNO); |
---|
512 | | - error = xfs_bitmap_set_btblocks(&ra.agmetablocks, cur); |
---|
| 501 | + error = xbitmap_set_btblocks(&ra.agmetablocks, cur); |
---|
513 | 502 | if (error) |
---|
514 | 503 | goto err; |
---|
515 | 504 | xfs_btree_del_cursor(cur, error); |
---|
.. | .. |
---|
517 | 506 | /* Find all blocks currently being used by the cntbt. */ |
---|
518 | 507 | cur = xfs_allocbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.agno, |
---|
519 | 508 | XFS_BTNUM_CNT); |
---|
520 | | - error = xfs_bitmap_set_btblocks(&ra.agmetablocks, cur); |
---|
| 509 | + error = xbitmap_set_btblocks(&ra.agmetablocks, cur); |
---|
521 | 510 | if (error) |
---|
522 | 511 | goto err; |
---|
523 | 512 | |
---|
.. | .. |
---|
527 | 516 | * Drop the freesp meta blocks that are in use by btrees. |
---|
528 | 517 | * The remaining blocks /should/ be AGFL blocks. |
---|
529 | 518 | */ |
---|
530 | | - error = xfs_bitmap_disunion(agfl_extents, &ra.agmetablocks); |
---|
531 | | - xfs_bitmap_destroy(&ra.agmetablocks); |
---|
| 519 | + error = xbitmap_disunion(agfl_extents, &ra.agmetablocks); |
---|
| 520 | + xbitmap_destroy(&ra.agmetablocks); |
---|
532 | 521 | if (error) |
---|
533 | 522 | return error; |
---|
534 | 523 | |
---|
.. | .. |
---|
536 | 525 | * Calculate the new AGFL size. If we found more blocks than fit in |
---|
537 | 526 | * the AGFL we'll free them later. |
---|
538 | 527 | */ |
---|
539 | | - *flcount = 0; |
---|
540 | | - for_each_xfs_bitmap_extent(br, n, agfl_extents) { |
---|
541 | | - *flcount += br->len; |
---|
542 | | - if (*flcount > xfs_agfl_size(mp)) |
---|
543 | | - break; |
---|
544 | | - } |
---|
545 | | - if (*flcount > xfs_agfl_size(mp)) |
---|
546 | | - *flcount = xfs_agfl_size(mp); |
---|
| 528 | + *flcount = min_t(uint64_t, xbitmap_hweight(agfl_extents), |
---|
| 529 | + xfs_agfl_size(mp)); |
---|
547 | 530 | return 0; |
---|
548 | 531 | |
---|
549 | 532 | err: |
---|
550 | | - xfs_bitmap_destroy(&ra.agmetablocks); |
---|
| 533 | + xbitmap_destroy(&ra.agmetablocks); |
---|
551 | 534 | xfs_btree_del_cursor(cur, error); |
---|
552 | 535 | return error; |
---|
553 | 536 | } |
---|
.. | .. |
---|
559 | 542 | struct xfs_buf *agf_bp, |
---|
560 | 543 | xfs_agblock_t flcount) |
---|
561 | 544 | { |
---|
562 | | - struct xfs_agf *agf = XFS_BUF_TO_AGF(agf_bp); |
---|
| 545 | + struct xfs_agf *agf = agf_bp->b_addr; |
---|
563 | 546 | |
---|
564 | 547 | ASSERT(flcount <= xfs_agfl_size(sc->mp)); |
---|
565 | 548 | |
---|
.. | .. |
---|
582 | 565 | xrep_agfl_init_header( |
---|
583 | 566 | struct xfs_scrub *sc, |
---|
584 | 567 | struct xfs_buf *agfl_bp, |
---|
585 | | - struct xfs_bitmap *agfl_extents, |
---|
| 568 | + struct xbitmap *agfl_extents, |
---|
586 | 569 | xfs_agblock_t flcount) |
---|
587 | 570 | { |
---|
588 | 571 | struct xfs_mount *mp = sc->mp; |
---|
589 | 572 | __be32 *agfl_bno; |
---|
590 | | - struct xfs_bitmap_range *br; |
---|
591 | | - struct xfs_bitmap_range *n; |
---|
| 573 | + struct xbitmap_range *br; |
---|
| 574 | + struct xbitmap_range *n; |
---|
592 | 575 | struct xfs_agfl *agfl; |
---|
593 | 576 | xfs_agblock_t agbno; |
---|
594 | 577 | unsigned int fl_off; |
---|
.. | .. |
---|
611 | 594 | * step. |
---|
612 | 595 | */ |
---|
613 | 596 | fl_off = 0; |
---|
614 | | - agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agfl_bp); |
---|
615 | | - for_each_xfs_bitmap_extent(br, n, agfl_extents) { |
---|
| 597 | + agfl_bno = xfs_buf_to_agfl_bno(agfl_bp); |
---|
| 598 | + for_each_xbitmap_extent(br, n, agfl_extents) { |
---|
616 | 599 | agbno = XFS_FSB_TO_AGBNO(mp, br->start); |
---|
617 | 600 | |
---|
618 | 601 | trace_xrep_agfl_insert(mp, sc->sa.agno, agbno, br->len); |
---|
.. | .. |
---|
646 | 629 | xrep_agfl( |
---|
647 | 630 | struct xfs_scrub *sc) |
---|
648 | 631 | { |
---|
649 | | - struct xfs_owner_info oinfo; |
---|
650 | | - struct xfs_bitmap agfl_extents; |
---|
| 632 | + struct xbitmap agfl_extents; |
---|
651 | 633 | struct xfs_mount *mp = sc->mp; |
---|
652 | 634 | struct xfs_buf *agf_bp; |
---|
653 | 635 | struct xfs_buf *agfl_bp; |
---|
.. | .. |
---|
659 | 641 | return -EOPNOTSUPP; |
---|
660 | 642 | |
---|
661 | 643 | xchk_perag_get(sc->mp, &sc->sa); |
---|
662 | | - xfs_bitmap_init(&agfl_extents); |
---|
| 644 | + xbitmap_init(&agfl_extents); |
---|
663 | 645 | |
---|
664 | 646 | /* |
---|
665 | 647 | * Read the AGF so that we can query the rmapbt. We hope that there's |
---|
.. | .. |
---|
669 | 651 | error = xfs_alloc_read_agf(mp, sc->tp, sc->sa.agno, 0, &agf_bp); |
---|
670 | 652 | if (error) |
---|
671 | 653 | return error; |
---|
672 | | - if (!agf_bp) |
---|
673 | | - return -ENOMEM; |
---|
674 | 654 | |
---|
675 | 655 | /* |
---|
676 | 656 | * Make sure we have the AGFL buffer, as scrub might have decided it |
---|
.. | .. |
---|
708 | 688 | goto err; |
---|
709 | 689 | |
---|
710 | 690 | /* Dump any AGFL overflow. */ |
---|
711 | | - xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG); |
---|
712 | | - return xrep_reap_extents(sc, &agfl_extents, &oinfo, XFS_AG_RESV_AGFL); |
---|
| 691 | + error = xrep_reap_extents(sc, &agfl_extents, &XFS_RMAP_OINFO_AG, |
---|
| 692 | + XFS_AG_RESV_AGFL); |
---|
713 | 693 | err: |
---|
714 | | - xfs_bitmap_destroy(&agfl_extents); |
---|
| 694 | + xbitmap_destroy(&agfl_extents); |
---|
715 | 695 | return error; |
---|
716 | 696 | } |
---|
717 | 697 | |
---|
.. | .. |
---|
745 | 725 | error = xfs_alloc_read_agf(mp, sc->tp, sc->sa.agno, 0, &agf_bp); |
---|
746 | 726 | if (error) |
---|
747 | 727 | return error; |
---|
748 | | - if (!agf_bp) |
---|
749 | | - return -ENOMEM; |
---|
750 | 728 | |
---|
751 | 729 | /* Find the btree roots. */ |
---|
752 | 730 | error = xrep_find_ag_btree_roots(sc, agf_bp, fab, NULL); |
---|
.. | .. |
---|
775 | 753 | struct xfs_buf *agi_bp, |
---|
776 | 754 | struct xfs_agi *old_agi) |
---|
777 | 755 | { |
---|
778 | | - struct xfs_agi *agi = XFS_BUF_TO_AGI(agi_bp); |
---|
| 756 | + struct xfs_agi *agi = agi_bp->b_addr; |
---|
779 | 757 | struct xfs_mount *mp = sc->mp; |
---|
780 | 758 | |
---|
781 | 759 | memcpy(old_agi, agi, sizeof(*old_agi)); |
---|
.. | .. |
---|
821 | 799 | struct xfs_buf *agi_bp) |
---|
822 | 800 | { |
---|
823 | 801 | struct xfs_btree_cur *cur; |
---|
824 | | - struct xfs_agi *agi = XFS_BUF_TO_AGI(agi_bp); |
---|
| 802 | + struct xfs_agi *agi = agi_bp->b_addr; |
---|
825 | 803 | struct xfs_mount *mp = sc->mp; |
---|
826 | 804 | xfs_agino_t count; |
---|
827 | 805 | xfs_agino_t freecount; |
---|
.. | .. |
---|
832 | 810 | error = xfs_ialloc_count_inodes(cur, &count, &freecount); |
---|
833 | 811 | if (error) |
---|
834 | 812 | goto err; |
---|
| 813 | + if (xfs_sb_version_hasinobtcounts(&mp->m_sb)) { |
---|
| 814 | + xfs_agblock_t blocks; |
---|
| 815 | + |
---|
| 816 | + error = xfs_btree_count_blocks(cur, &blocks); |
---|
| 817 | + if (error) |
---|
| 818 | + goto err; |
---|
| 819 | + agi->agi_iblocks = cpu_to_be32(blocks); |
---|
| 820 | + } |
---|
835 | 821 | xfs_btree_del_cursor(cur, error); |
---|
836 | 822 | |
---|
837 | 823 | agi->agi_count = cpu_to_be32(count); |
---|
838 | 824 | agi->agi_freecount = cpu_to_be32(freecount); |
---|
| 825 | + |
---|
| 826 | + if (xfs_sb_version_hasfinobt(&mp->m_sb) && |
---|
| 827 | + xfs_sb_version_hasinobtcounts(&mp->m_sb)) { |
---|
| 828 | + xfs_agblock_t blocks; |
---|
| 829 | + |
---|
| 830 | + cur = xfs_inobt_init_cursor(mp, sc->tp, agi_bp, sc->sa.agno, |
---|
| 831 | + XFS_BTNUM_FINO); |
---|
| 832 | + if (error) |
---|
| 833 | + goto err; |
---|
| 834 | + error = xfs_btree_count_blocks(cur, &blocks); |
---|
| 835 | + if (error) |
---|
| 836 | + goto err; |
---|
| 837 | + xfs_btree_del_cursor(cur, error); |
---|
| 838 | + agi->agi_fblocks = cpu_to_be32(blocks); |
---|
| 839 | + } |
---|
| 840 | + |
---|
839 | 841 | return 0; |
---|
840 | 842 | err: |
---|
841 | 843 | xfs_btree_del_cursor(cur, error); |
---|
.. | .. |
---|
849 | 851 | struct xfs_buf *agi_bp) |
---|
850 | 852 | { |
---|
851 | 853 | struct xfs_perag *pag; |
---|
852 | | - struct xfs_agi *agi = XFS_BUF_TO_AGI(agi_bp); |
---|
| 854 | + struct xfs_agi *agi = agi_bp->b_addr; |
---|
853 | 855 | |
---|
854 | 856 | /* Trigger inode count recalculation */ |
---|
855 | 857 | xfs_force_summary_recalc(sc->mp); |
---|
.. | .. |
---|
876 | 878 | [XREP_AGI_INOBT] = { |
---|
877 | 879 | .rmap_owner = XFS_RMAP_OWN_INOBT, |
---|
878 | 880 | .buf_ops = &xfs_inobt_buf_ops, |
---|
879 | | - .magic = XFS_IBT_CRC_MAGIC, |
---|
880 | 881 | }, |
---|
881 | 882 | [XREP_AGI_FINOBT] = { |
---|
882 | 883 | .rmap_owner = XFS_RMAP_OWN_INOBT, |
---|
883 | | - .buf_ops = &xfs_inobt_buf_ops, |
---|
884 | | - .magic = XFS_FIBT_CRC_MAGIC, |
---|
| 884 | + .buf_ops = &xfs_finobt_buf_ops, |
---|
885 | 885 | }, |
---|
886 | 886 | [XREP_AGI_END] = { |
---|
887 | 887 | .buf_ops = NULL |
---|
.. | .. |
---|
908 | 908 | if (error) |
---|
909 | 909 | return error; |
---|
910 | 910 | agi_bp->b_ops = &xfs_agi_buf_ops; |
---|
911 | | - agi = XFS_BUF_TO_AGI(agi_bp); |
---|
| 911 | + agi = agi_bp->b_addr; |
---|
912 | 912 | |
---|
913 | 913 | /* Find the AGI btree roots. */ |
---|
914 | 914 | error = xrep_agi_find_btrees(sc, fab); |
---|