hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/xfs/scrub/agheader.c
....@@ -9,20 +9,13 @@
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"
15
-#include "xfs_log_format.h"
16
-#include "xfs_trans.h"
1713 #include "xfs_sb.h"
18
-#include "xfs_inode.h"
1914 #include "xfs_alloc.h"
2015 #include "xfs_ialloc.h"
2116 #include "xfs_rmap.h"
22
-#include "scrub/xfs_scrub.h"
2317 #include "scrub/scrub.h"
2418 #include "scrub/common.h"
25
-#include "scrub/trace.h"
2619
2720 /* Superblock */
2821
....@@ -32,7 +25,6 @@
3225 struct xfs_scrub *sc,
3326 struct xfs_buf *bp)
3427 {
35
- struct xfs_owner_info oinfo;
3628 struct xfs_mount *mp = sc->mp;
3729 xfs_agnumber_t agno = sc->sm->sm_agno;
3830 xfs_agblock_t agbno;
....@@ -49,8 +41,7 @@
4941
5042 xchk_xref_is_used_space(sc, agbno, 1);
5143 xchk_xref_is_not_inode_chunk(sc, agbno, 1);
52
- xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_FS);
53
- xchk_xref_is_owned_by(sc, agbno, 1, &oinfo);
44
+ xchk_xref_is_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_FS);
5445 xchk_xref_is_not_shared(sc, agbno, 1);
5546
5647 /* scrub teardown will take care of sc->sa for us */
....@@ -101,7 +92,7 @@
10192 if (!xchk_process_error(sc, agno, XFS_SB_BLOCK(mp), &error))
10293 return error;
10394
104
- sb = XFS_BUF_TO_SBP(bp);
95
+ sb = bp->b_addr;
10596
10697 /*
10798 * Verify the geometries match. Fields that are permanently
....@@ -367,7 +358,7 @@
367358 xchk_agf_xref_freeblks(
368359 struct xfs_scrub *sc)
369360 {
370
- struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp);
361
+ struct xfs_agf *agf = sc->sa.agf_bp->b_addr;
371362 xfs_extlen_t blocks = 0;
372363 int error;
373364
....@@ -387,7 +378,7 @@
387378 xchk_agf_xref_cntbt(
388379 struct xfs_scrub *sc)
389380 {
390
- struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp);
381
+ struct xfs_agf *agf = sc->sa.agf_bp->b_addr;
391382 xfs_agblock_t agbno;
392383 xfs_extlen_t blocks;
393384 int have;
....@@ -401,7 +392,7 @@
401392 if (!xchk_should_check_xref(sc, &error, &sc->sa.cnt_cur))
402393 return;
403394 if (!have) {
404
- if (agf->agf_freeblks != be32_to_cpu(0))
395
+ if (agf->agf_freeblks != cpu_to_be32(0))
405396 xchk_block_xref_set_corrupt(sc, sc->sa.agf_bp);
406397 return;
407398 }
....@@ -419,7 +410,7 @@
419410 xchk_agf_xref_btreeblks(
420411 struct xfs_scrub *sc)
421412 {
422
- struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp);
413
+ struct xfs_agf *agf = sc->sa.agf_bp->b_addr;
423414 struct xfs_mount *mp = sc->mp;
424415 xfs_agblock_t blocks;
425416 xfs_agblock_t btreeblks;
....@@ -465,7 +456,7 @@
465456 xchk_agf_xref_refcblks(
466457 struct xfs_scrub *sc)
467458 {
468
- struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp);
459
+ struct xfs_agf *agf = sc->sa.agf_bp->b_addr;
469460 xfs_agblock_t blocks;
470461 int error;
471462
....@@ -484,7 +475,6 @@
484475 xchk_agf_xref(
485476 struct xfs_scrub *sc)
486477 {
487
- struct xfs_owner_info oinfo;
488478 struct xfs_mount *mp = sc->mp;
489479 xfs_agblock_t agbno;
490480 int error;
....@@ -502,8 +492,7 @@
502492 xchk_agf_xref_freeblks(sc);
503493 xchk_agf_xref_cntbt(sc);
504494 xchk_xref_is_not_inode_chunk(sc, agbno, 1);
505
- xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_FS);
506
- xchk_xref_is_owned_by(sc, agbno, 1, &oinfo);
495
+ xchk_xref_is_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_FS);
507496 xchk_agf_xref_btreeblks(sc);
508497 xchk_xref_is_not_shared(sc, agbno, 1);
509498 xchk_agf_xref_refcblks(sc);
....@@ -518,6 +507,7 @@
518507 {
519508 struct xfs_mount *mp = sc->mp;
520509 struct xfs_agf *agf;
510
+ struct xfs_perag *pag;
521511 xfs_agnumber_t agno;
522512 xfs_agblock_t agbno;
523513 xfs_agblock_t eoag;
....@@ -535,7 +525,7 @@
535525 goto out;
536526 xchk_buffer_recheck(sc, sc->sa.agf_bp);
537527
538
- agf = XFS_BUF_TO_AGF(sc->sa.agf_bp);
528
+ agf = sc->sa.agf_bp->b_addr;
539529
540530 /* Check the AG length */
541531 eoag = be32_to_cpu(agf->agf_length);
....@@ -590,6 +580,16 @@
590580 if (agfl_count != 0 && fl_count != agfl_count)
591581 xchk_block_set_corrupt(sc, sc->sa.agf_bp);
592582
583
+ /* Do the incore counters match? */
584
+ pag = xfs_perag_get(mp, agno);
585
+ if (pag->pagf_freeblks != be32_to_cpu(agf->agf_freeblks))
586
+ xchk_block_set_corrupt(sc, sc->sa.agf_bp);
587
+ if (pag->pagf_flcount != be32_to_cpu(agf->agf_flcount))
588
+ xchk_block_set_corrupt(sc, sc->sa.agf_bp);
589
+ if (pag->pagf_btreeblks != be32_to_cpu(agf->agf_btreeblks))
590
+ xchk_block_set_corrupt(sc, sc->sa.agf_bp);
591
+ xfs_perag_put(pag);
592
+
593593 xchk_agf_xref(sc);
594594 out:
595595 return error;
....@@ -598,7 +598,6 @@
598598 /* AGFL */
599599
600600 struct xchk_agfl_info {
601
- struct xfs_owner_info oinfo;
602601 unsigned int sz_entries;
603602 unsigned int nr_entries;
604603 xfs_agblock_t *entries;
....@@ -609,15 +608,14 @@
609608 STATIC void
610609 xchk_agfl_block_xref(
611610 struct xfs_scrub *sc,
612
- xfs_agblock_t agbno,
613
- struct xfs_owner_info *oinfo)
611
+ xfs_agblock_t agbno)
614612 {
615613 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
616614 return;
617615
618616 xchk_xref_is_used_space(sc, agbno, 1);
619617 xchk_xref_is_not_inode_chunk(sc, agbno, 1);
620
- xchk_xref_is_owned_by(sc, agbno, 1, oinfo);
618
+ xchk_xref_is_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_AG);
621619 xchk_xref_is_not_shared(sc, agbno, 1);
622620 }
623621
....@@ -638,10 +636,10 @@
638636 else
639637 xchk_block_set_corrupt(sc, sc->sa.agfl_bp);
640638
641
- xchk_agfl_block_xref(sc, agbno, priv);
639
+ xchk_agfl_block_xref(sc, agbno);
642640
643641 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
644
- return XFS_BTREE_QUERY_RANGE_ABORT;
642
+ return -ECANCELED;
645643
646644 return 0;
647645 }
....@@ -662,7 +660,6 @@
662660 xchk_agfl_xref(
663661 struct xfs_scrub *sc)
664662 {
665
- struct xfs_owner_info oinfo;
666663 struct xfs_mount *mp = sc->mp;
667664 xfs_agblock_t agbno;
668665 int error;
....@@ -678,8 +675,7 @@
678675
679676 xchk_xref_is_used_space(sc, agbno, 1);
680677 xchk_xref_is_not_inode_chunk(sc, agbno, 1);
681
- xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_FS);
682
- xchk_xref_is_owned_by(sc, agbno, 1, &oinfo);
678
+ xchk_xref_is_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_FS);
683679 xchk_xref_is_not_shared(sc, agbno, 1);
684680
685681 /*
....@@ -715,7 +711,7 @@
715711 goto out;
716712
717713 /* Allocate buffer to ensure uniqueness of AGFL entries. */
718
- agf = XFS_BUF_TO_AGF(sc->sa.agf_bp);
714
+ agf = sc->sa.agf_bp->b_addr;
719715 agflcount = be32_to_cpu(agf->agf_flcount);
720716 if (agflcount > xfs_agfl_size(sc->mp)) {
721717 xchk_block_set_corrupt(sc, sc->sa.agf_bp);
....@@ -732,10 +728,9 @@
732728 }
733729
734730 /* Check the blocks in the AGFL. */
735
- xfs_rmap_ag_owner(&sai.oinfo, XFS_RMAP_OWN_AG);
736
- error = xfs_agfl_walk(sc->mp, XFS_BUF_TO_AGF(sc->sa.agf_bp),
731
+ error = xfs_agfl_walk(sc->mp, sc->sa.agf_bp->b_addr,
737732 sc->sa.agfl_bp, xchk_agfl_block, &sai);
738
- if (error == XFS_BTREE_QUERY_RANGE_ABORT) {
733
+ if (error == -ECANCELED) {
739734 error = 0;
740735 goto out_free;
741736 }
....@@ -770,7 +765,7 @@
770765 xchk_agi_xref_icounts(
771766 struct xfs_scrub *sc)
772767 {
773
- struct xfs_agi *agi = XFS_BUF_TO_AGI(sc->sa.agi_bp);
768
+ struct xfs_agi *agi = sc->sa.agi_bp->b_addr;
774769 xfs_agino_t icount;
775770 xfs_agino_t freecount;
776771 int error;
....@@ -786,12 +781,40 @@
786781 xchk_block_xref_set_corrupt(sc, sc->sa.agi_bp);
787782 }
788783
784
+/* Check agi_[fi]blocks against tree size */
785
+static inline void
786
+xchk_agi_xref_fiblocks(
787
+ struct xfs_scrub *sc)
788
+{
789
+ struct xfs_agi *agi = sc->sa.agi_bp->b_addr;
790
+ xfs_agblock_t blocks;
791
+ int error = 0;
792
+
793
+ if (!xfs_sb_version_hasinobtcounts(&sc->mp->m_sb))
794
+ return;
795
+
796
+ if (sc->sa.ino_cur) {
797
+ error = xfs_btree_count_blocks(sc->sa.ino_cur, &blocks);
798
+ if (!xchk_should_check_xref(sc, &error, &sc->sa.ino_cur))
799
+ return;
800
+ if (blocks != be32_to_cpu(agi->agi_iblocks))
801
+ xchk_block_xref_set_corrupt(sc, sc->sa.agi_bp);
802
+ }
803
+
804
+ if (sc->sa.fino_cur) {
805
+ error = xfs_btree_count_blocks(sc->sa.fino_cur, &blocks);
806
+ if (!xchk_should_check_xref(sc, &error, &sc->sa.fino_cur))
807
+ return;
808
+ if (blocks != be32_to_cpu(agi->agi_fblocks))
809
+ xchk_block_xref_set_corrupt(sc, sc->sa.agi_bp);
810
+ }
811
+}
812
+
789813 /* Cross-reference with the other btrees. */
790814 STATIC void
791815 xchk_agi_xref(
792816 struct xfs_scrub *sc)
793817 {
794
- struct xfs_owner_info oinfo;
795818 struct xfs_mount *mp = sc->mp;
796819 xfs_agblock_t agbno;
797820 int error;
....@@ -808,9 +831,9 @@
808831 xchk_xref_is_used_space(sc, agbno, 1);
809832 xchk_xref_is_not_inode_chunk(sc, agbno, 1);
810833 xchk_agi_xref_icounts(sc);
811
- xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_FS);
812
- xchk_xref_is_owned_by(sc, agbno, 1, &oinfo);
834
+ xchk_xref_is_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_FS);
813835 xchk_xref_is_not_shared(sc, agbno, 1);
836
+ xchk_agi_xref_fiblocks(sc);
814837
815838 /* scrub teardown will take care of sc->sa for us */
816839 }
....@@ -822,6 +845,7 @@
822845 {
823846 struct xfs_mount *mp = sc->mp;
824847 struct xfs_agi *agi;
848
+ struct xfs_perag *pag;
825849 xfs_agnumber_t agno;
826850 xfs_agblock_t agbno;
827851 xfs_agblock_t eoag;
....@@ -840,7 +864,7 @@
840864 goto out;
841865 xchk_buffer_recheck(sc, sc->sa.agi_bp);
842866
843
- agi = XFS_BUF_TO_AGI(sc->sa.agi_bp);
867
+ agi = sc->sa.agi_bp->b_addr;
844868
845869 /* Check the AG length */
846870 eoag = be32_to_cpu(agi->agi_length);
....@@ -875,25 +899,31 @@
875899
876900 /* Check inode pointers */
877901 agino = be32_to_cpu(agi->agi_newino);
878
- if (agino != NULLAGINO && !xfs_verify_agino(mp, agno, agino))
902
+ if (!xfs_verify_agino_or_null(mp, agno, agino))
879903 xchk_block_set_corrupt(sc, sc->sa.agi_bp);
880904
881905 agino = be32_to_cpu(agi->agi_dirino);
882
- if (agino != NULLAGINO && !xfs_verify_agino(mp, agno, agino))
906
+ if (!xfs_verify_agino_or_null(mp, agno, agino))
883907 xchk_block_set_corrupt(sc, sc->sa.agi_bp);
884908
885909 /* Check unlinked inode buckets */
886910 for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) {
887911 agino = be32_to_cpu(agi->agi_unlinked[i]);
888
- if (agino == NULLAGINO)
889
- continue;
890
- if (!xfs_verify_agino(mp, agno, agino))
912
+ if (!xfs_verify_agino_or_null(mp, agno, agino))
891913 xchk_block_set_corrupt(sc, sc->sa.agi_bp);
892914 }
893915
894916 if (agi->agi_pad32 != cpu_to_be32(0))
895917 xchk_block_set_corrupt(sc, sc->sa.agi_bp);
896918
919
+ /* Do the incore counters match? */
920
+ pag = xfs_perag_get(mp, agno);
921
+ if (pag->pagi_count != be32_to_cpu(agi->agi_count))
922
+ xchk_block_set_corrupt(sc, sc->sa.agi_bp);
923
+ if (pag->pagi_freecount != be32_to_cpu(agi->agi_freecount))
924
+ xchk_block_set_corrupt(sc, sc->sa.agi_bp);
925
+ xfs_perag_put(pag);
926
+
897927 xchk_agi_xref(sc);
898928 out:
899929 return error;