]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - repair/scan.c
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "err_protos.h"
32 extern int verify_set_agheader(xfs_mount_t
*mp
, xfs_buf_t
*sbuf
, xfs_sb_t
*sb
,
33 xfs_agf_t
*agf
, xfs_agi_t
*agi
, xfs_agnumber_t i
);
35 static xfs_mount_t
*mp
= NULL
;
38 set_mp(xfs_mount_t
*mpp
)
40 libxfs_bcache_purge();
50 void (*func
)(struct xfs_btree_block
*block
,
60 bp
= libxfs_readbuf(mp
->m_dev
, XFS_AGB_TO_DADDR(mp
, agno
, root
),
61 XFS_FSB_TO_BB(mp
, 1), 0);
63 do_error(_("can't read btree block %d/%d\n"), agno
, root
);
66 (*func
)(XFS_BUF_TO_BLOCK(bp
), nlevels
- 1, root
, agno
, suspect
, isroot
);
71 * returns 1 on bad news (inode needs to be cleared), 0 on good
77 int (*func
)(struct xfs_btree_block
*block
,
86 bmap_cursor_t
*bm_cursor
,
96 bmap_cursor_t
*bm_cursor
,
104 bp
= libxfs_readbuf(mp
->m_dev
, XFS_FSB_TO_DADDR(mp
, root
),
105 XFS_FSB_TO_BB(mp
, 1), 0);
107 do_error(_("can't read btree block %d/%d\n"),
108 XFS_FSB_TO_AGNO(mp
, root
),
109 XFS_FSB_TO_AGBNO(mp
, root
));
112 err
= (*func
)(XFS_BUF_TO_BLOCK(bp
), nlevels
- 1,
113 type
, whichfork
, root
, ino
, tot
, nex
, blkmapp
,
114 bm_cursor
, isroot
, check_dups
, &dirty
);
116 ASSERT(dirty
== 0 || (dirty
&& !no_modify
));
118 if (dirty
&& !no_modify
)
119 libxfs_writebuf(bp
, 0);
128 struct xfs_btree_block
*block
,
137 bmap_cursor_t
*bm_cursor
,
145 xfs_bmbt_key_t
*pkey
;
147 xfs_dfiloff_t first_key
;
148 xfs_dfiloff_t last_key
;
155 if (whichfork
== XFS_DATA_FORK
)
156 forkname
= _("data");
158 forkname
= _("attr");
161 * unlike the ag freeblock btrees, if anything looks wrong
162 * in an inode bmap tree, just bail. it's possible that
163 * we'll miss a case where the to-be-toasted inode and
164 * another inode are claiming the same block but that's
167 if (be32_to_cpu(block
->bb_magic
) != XFS_BMAP_MAGIC
) {
168 do_warn(_("bad magic # %#x in inode %llu (%s fork) bmbt "
169 "block %llu\n"), be32_to_cpu(block
->bb_magic
),
173 if (be16_to_cpu(block
->bb_level
) != level
) {
174 do_warn(_("expected level %d got %d in inode %llu, (%s fork) "
175 "bmbt block %llu\n"), level
,
176 be16_to_cpu(block
->bb_level
), ino
, forkname
, bno
);
180 if (check_dups
== 0) {
182 * check sibling pointers. if bad we have a conflict
183 * between the sibling pointers and the child pointers
184 * in the parent block. blow out the inode if that happens
186 if (bm_cursor
->level
[level
].fsbno
!= NULLDFSBNO
) {
188 * this is not the first block on this level
189 * so the cursor for this level has recorded the
190 * values for this's block left-sibling.
192 if (bno
!= bm_cursor
->level
[level
].right_fsbno
) {
194 _("bad fwd (right) sibling pointer (saw %llu parent block says %llu)\n"
195 "\tin inode %llu (%s fork) bmap btree block %llu\n"),
196 bm_cursor
->level
[level
].right_fsbno
,
198 bm_cursor
->level
[level
].fsbno
);
201 if (be64_to_cpu(block
->bb_u
.l
.bb_leftsib
) !=
202 bm_cursor
->level
[level
].fsbno
) {
204 _("bad back (left) sibling pointer (saw %llu parent block says %llu)\n"
205 "\tin inode %llu (%s fork) bmap btree block %llu\n"),
206 be64_to_cpu(block
->bb_u
.l
.bb_leftsib
),
207 bm_cursor
->level
[level
].fsbno
,
213 * This is the first or only block on this level.
214 * Check that the left sibling pointer is NULL
216 if (be64_to_cpu(block
->bb_u
.l
.bb_leftsib
) != NULLDFSBNO
) {
218 _("bad back (left) sibling pointer (saw %llu should be NULL (0))\n"
219 "\tin inode %llu (%s fork) bmap btree block %llu\n"),
220 be64_to_cpu(block
->bb_u
.l
.bb_leftsib
),
227 * update cursor block pointers to reflect this block
229 bm_cursor
->level
[level
].fsbno
= bno
;
230 bm_cursor
->level
[level
].left_fsbno
=
231 be64_to_cpu(block
->bb_u
.l
.bb_leftsib
);
232 bm_cursor
->level
[level
].right_fsbno
=
233 be64_to_cpu(block
->bb_u
.l
.bb_rightsib
);
235 agno
= XFS_FSB_TO_AGNO(mp
, bno
);
236 agbno
= XFS_FSB_TO_AGBNO(mp
, bno
);
238 pthread_mutex_lock(&ag_locks
[agno
]);
239 state
= get_bmap(agno
, agbno
);
244 set_bmap(agno
, agbno
, XR_E_INUSE
);
249 * we'll try and continue searching here since
250 * the block looks like it's been claimed by file
251 * to store user data, a directory to store directory
252 * data, or the space allocation btrees but since
253 * we made it here, the block probably
254 * contains btree data.
256 set_bmap(agno
, agbno
, XR_E_MULT
);
258 _("inode 0x%llx bmap block 0x%llx claimed, state is %d\n"),
259 ino
, (__uint64_t
) bno
, state
);
263 set_bmap(agno
, agbno
, XR_E_MULT
);
265 _("inode 0x%llx bmap block 0x%llx claimed, state is %d\n"),
266 ino
, (__uint64_t
) bno
, state
);
268 * if we made it to here, this is probably a bmap block
269 * that is being used by *another* file as a bmap block
270 * so the block will be valid. Both files should be
271 * trashed along with any other file that impinges on
272 * any blocks referenced by either file. So we
273 * continue searching down this btree to mark all
280 _("bad state %d, inode 0x%llx bmap block 0x%llx\n"),
281 state
, ino
, (__uint64_t
) bno
);
284 pthread_mutex_unlock(&ag_locks
[agno
]);
287 * attribute fork for realtime files is in the regular
290 if (type
!= XR_INO_RTDATA
|| whichfork
!= XFS_DATA_FORK
) {
291 if (search_dup_extent(XFS_FSB_TO_AGNO(mp
, bno
),
292 XFS_FSB_TO_AGBNO(mp
, bno
),
293 XFS_FSB_TO_AGBNO(mp
, bno
) + 1))
296 if (search_rt_dup_extent(mp
, bno
))
301 numrecs
= be16_to_cpu(block
->bb_numrecs
);
304 if (numrecs
> mp
->m_bmap_dmxr
[0] || (isroot
== 0 && numrecs
<
305 mp
->m_bmap_dmnr
[0])) {
307 _("inode 0x%llx bad # of bmap records (%u, min - %u, max - %u)\n"),
308 ino
, numrecs
, mp
->m_bmap_dmnr
[0],
312 rp
= XFS_BMBT_REC_ADDR(mp
, block
, 1);
315 * XXX - if we were going to fix up the btree record,
316 * we'd do it right here. For now, if there's a problem,
317 * we'll bail out and presumably clear the inode.
319 if (check_dups
== 0) {
320 err
= process_bmbt_reclist(mp
, rp
, numrecs
,
321 type
, ino
, tot
, blkmapp
,
322 &first_key
, &last_key
,
327 * check that key ordering is monotonically increasing.
328 * if the last_key value in the cursor is set to
329 * NULLDFILOFF, then we know this is the first block
330 * on the leaf level and we shouldn't check the
333 if (first_key
<= bm_cursor
->level
[level
].last_key
&&
334 bm_cursor
->level
[level
].last_key
!=
337 _("out-of-order bmap key (file offset) in inode %llu, %s fork, fsbno %llu\n"),
342 * update cursor keys to reflect this block.
343 * don't have to check if last_key is > first_key
344 * since that gets checked by process_bmbt_reclist.
346 bm_cursor
->level
[level
].first_key
= first_key
;
347 bm_cursor
->level
[level
].last_key
= last_key
;
351 return(scan_bmbt_reclist(mp
, rp
, numrecs
,
352 type
, ino
, tot
, whichfork
));
354 if (numrecs
> mp
->m_bmap_dmxr
[1] || (isroot
== 0 && numrecs
<
355 mp
->m_bmap_dmnr
[1])) {
357 _("inode 0x%llx bad # of bmap records (%u, min - %u, max - %u)\n"),
358 ino
, numrecs
, mp
->m_bmap_dmnr
[1], mp
->m_bmap_dmxr
[1]);
361 pp
= XFS_BMBT_PTR_ADDR(mp
, block
, 1, mp
->m_bmap_dmxr
[1]);
362 pkey
= XFS_BMBT_KEY_ADDR(mp
, block
, 1);
364 last_key
= NULLDFILOFF
;
366 for (i
= 0, err
= 0; i
< numrecs
; i
++) {
368 * XXX - if we were going to fix up the interior btree nodes,
369 * we'd do it right here. For now, if there's a problem,
370 * we'll bail out and presumably clear the inode.
372 if (!verify_dfsbno(mp
, be64_to_cpu(pp
[i
]))) {
373 do_warn(_("bad bmap btree ptr 0x%llx in ino %llu\n"),
374 be64_to_cpu(pp
[i
]), ino
);
378 err
= scan_lbtree(be64_to_cpu(pp
[i
]), level
, scanfunc_bmap
,
379 type
, whichfork
, ino
, tot
, nex
, blkmapp
,
380 bm_cursor
, 0, check_dups
);
385 * fix key (offset) mismatches between the first key
386 * in the child block (as recorded in the cursor) and the
387 * key in the interior node referencing the child block.
389 * fixes cases where entries have been shifted between
390 * child blocks but the parent hasn't been updated. We
391 * don't have to worry about the key values in the cursor
392 * not being set since we only look at the key values of
393 * our child and those are guaranteed to be set by the
394 * call to scan_lbtree() above.
396 if (check_dups
== 0 && be64_to_cpu(pkey
[i
].br_startoff
) !=
397 bm_cursor
->level
[level
-1].first_key
) {
400 _("correcting bt key (was %llu, now %llu) in inode %llu\n"
401 "\t\t%s fork, btree block %llu\n"),
402 be64_to_cpu(pkey
[i
].br_startoff
),
403 bm_cursor
->level
[level
-1].first_key
,
407 pkey
[i
].br_startoff
= cpu_to_be64(
408 bm_cursor
->level
[level
-1].first_key
);
411 _("bad btree key (is %llu, should be %llu) in inode %llu\n"
412 "\t\t%s fork, btree block %llu\n"),
413 be64_to_cpu(pkey
[i
].br_startoff
),
414 bm_cursor
->level
[level
-1].first_key
,
421 * If we're the last node at our level, check that the last child
422 * block's forward sibling pointer is NULL.
424 if (check_dups
== 0 &&
425 bm_cursor
->level
[level
].right_fsbno
== NULLDFSBNO
&&
426 bm_cursor
->level
[level
- 1].right_fsbno
!= NULLDFSBNO
) {
428 _("bad fwd (right) sibling pointer (saw %llu should be NULLDFSBNO)\n"
429 "\tin inode %llu (%s fork) bmap btree block %llu\n"),
430 bm_cursor
->level
[level
- 1].right_fsbno
,
431 ino
, forkname
, bm_cursor
->level
[level
- 1].fsbno
);
436 * update cursor keys to reflect this block
438 if (check_dups
== 0) {
439 bm_cursor
->level
[level
].first_key
=
440 be64_to_cpu(pkey
[0].br_startoff
);
441 bm_cursor
->level
[level
].last_key
=
442 be64_to_cpu(pkey
[numrecs
- 1].br_startoff
);
450 struct xfs_btree_block
*block
,
466 assert(magic
== XFS_ABTB_MAGIC
|| magic
== XFS_ABTC_MAGIC
);
468 name
= (magic
== XFS_ABTB_MAGIC
) ? "bno" : "cnt";
470 if (be32_to_cpu(block
->bb_magic
) != magic
) {
471 do_warn(_("bad magic # %#x in bt%s block %d/%d\n"),
472 be32_to_cpu(block
->bb_magic
), name
, agno
, bno
);
477 if (be16_to_cpu(block
->bb_level
) != level
) {
478 do_warn(_("expected level %d got %d in bt%s block %d/%d\n"),
479 level
, be16_to_cpu(block
->bb_level
), name
, agno
, bno
);
486 * check for btree blocks multiply claimed
488 state
= get_bmap(agno
, bno
);
489 if (state
!= XR_E_UNKNOWN
) {
490 set_bmap(agno
, bno
, XR_E_MULT
);
492 _("%s freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
493 name
, state
, agno
, bno
, suspect
);
496 set_bmap(agno
, bno
, XR_E_FS_MAP
);
498 numrecs
= be16_to_cpu(block
->bb_numrecs
);
502 if (numrecs
> mp
->m_alloc_mxr
[0]) {
503 numrecs
= mp
->m_alloc_mxr
[0];
506 if (isroot
== 0 && numrecs
< mp
->m_alloc_mnr
[0]) {
507 numrecs
= mp
->m_alloc_mnr
[0];
514 rp
= XFS_ALLOC_REC_ADDR(mp
, block
, 1);
515 for (i
= 0; i
< numrecs
; i
++) {
516 xfs_agblock_t b
, end
;
517 xfs_extlen_t len
, blen
;
519 b
= be32_to_cpu(rp
[i
].ar_startblock
);
520 len
= be32_to_cpu(rp
[i
].ar_blockcount
);
523 if (b
== 0 || !verify_agbno(mp
, agno
, b
))
525 if (len
== 0 || len
> MAXEXTLEN
)
527 if (!verify_agbno(mp
, agno
, end
- 1))
530 for ( ; b
< end
; b
+= blen
) {
531 state
= get_bmap_ext(agno
, b
, end
, &blen
);
534 set_bmap(agno
, b
, XR_E_FREE1
);
538 * no warning messages -- we'll catch
541 if (magic
== XFS_ABTC_MAGIC
) {
542 set_bmap_ext(agno
, b
, blen
,
548 _("block (%d,%d-%d) multiply claimed by %s space tree, state - %d\n"),
549 agno
, b
, b
+ blen
- 1,
561 pp
= XFS_ALLOC_PTR_ADDR(mp
, block
, 1, mp
->m_alloc_mxr
[1]);
563 if (numrecs
> mp
->m_alloc_mxr
[1]) {
564 numrecs
= mp
->m_alloc_mxr
[1];
567 if (isroot
== 0 && numrecs
< mp
->m_alloc_mnr
[1]) {
568 numrecs
= mp
->m_alloc_mnr
[1];
573 * don't pass bogus tree flag down further if this block
574 * looked ok. bail out if two levels in a row look bad.
577 if (suspect
&& !hdr_errors
)
586 for (i
= 0; i
< numrecs
; i
++) {
587 xfs_agblock_t bno
= be32_to_cpu(pp
[i
]);
590 * XXX - put sibling detection right here.
591 * we know our sibling chain is good. So as we go,
592 * we check the entry before and after each entry.
593 * If either of the entries references a different block,
594 * check the sibling pointer. If there's a sibling
595 * pointer mismatch, try and extract as much data
598 if (bno
!= 0 && verify_agbno(mp
, agno
, bno
)) {
599 scan_sbtree(bno
, level
, agno
, suspect
,
600 (magic
== XFS_ABTB_MAGIC
) ?
601 scanfunc_bno
: scanfunc_cnt
, 0);
608 struct xfs_btree_block
*block
,
615 return scanfunc_allocbt(block
, level
, bno
, agno
,
616 suspect
, isroot
, XFS_ABTB_MAGIC
);
621 struct xfs_btree_block
*block
,
629 return scanfunc_allocbt(block
, level
, bno
, agno
,
630 suspect
, isroot
, XFS_ABTC_MAGIC
);
634 scan_single_ino_chunk(
646 ino_tree_node_t
*ino_rec
, *first_rec
, *last_rec
;
648 ino
= be32_to_cpu(rp
->ir_startino
);
649 off
= XFS_AGINO_TO_OFFSET(mp
, ino
);
650 agbno
= XFS_AGINO_TO_AGBNO(mp
, ino
);
651 lino
= XFS_AGINO_TO_INO(mp
, agno
, ino
);
654 * on multi-block block chunks, all chunks start
655 * at the beginning of the block. with multi-chunk
656 * blocks, all chunks must start on 64-inode boundaries
657 * since each block can hold N complete chunks. if
658 * fs has aligned inodes, all chunks must start
659 * at a fs_ino_alignment*N'th agbno. skip recs
660 * with badly aligned starting inodes.
663 (inodes_per_block
<= XFS_INODES_PER_CHUNK
&& off
!= 0) ||
664 (inodes_per_block
> XFS_INODES_PER_CHUNK
&&
665 off
% XFS_INODES_PER_CHUNK
!= 0) ||
666 (fs_aligned_inodes
&& agbno
% fs_ino_alignment
!= 0)) {
668 _("badly aligned inode rec (starting inode = %llu)\n"),
674 * verify numeric validity of inode chunk first
675 * before inserting into a tree. don't have to
676 * worry about the overflow case because the
677 * starting ino number of a chunk can only get
678 * within 255 inodes of max (NULLAGINO). if it
679 * gets closer, the agino number will be illegal
680 * as the agbno will be too large.
682 if (verify_aginum(mp
, agno
, ino
)) {
684 _("bad starting inode # (%llu (0x%x 0x%x)) in ino rec, skipping rec\n"),
689 if (verify_aginum(mp
, agno
,
690 ino
+ XFS_INODES_PER_CHUNK
- 1)) {
692 _("bad ending inode # (%llu (0x%x 0x%x)) in ino rec, skipping rec\n"),
693 lino
+ XFS_INODES_PER_CHUNK
- 1,
694 agno
, ino
+ XFS_INODES_PER_CHUNK
- 1);
699 * set state of each block containing inodes
701 if (off
== 0 && !suspect
) {
703 j
< XFS_INODES_PER_CHUNK
;
704 j
+= mp
->m_sb
.sb_inopblock
) {
705 agbno
= XFS_AGINO_TO_AGBNO(mp
, ino
+ j
);
707 state
= get_bmap(agno
, agbno
);
708 if (state
== XR_E_UNKNOWN
) {
709 set_bmap(agno
, agbno
, XR_E_INO
);
710 } else if (state
== XR_E_INUSE_FS
&& agno
== 0 &&
711 ino
+ j
>= first_prealloc_ino
&&
712 ino
+ j
< last_prealloc_ino
) {
713 set_bmap(agno
, agbno
, XR_E_INO
);
716 _("inode chunk claims used block, inobt block - agno %d, bno %d, inopb %d\n"),
717 agno
, agbno
, mp
->m_sb
.sb_inopblock
);
719 * XXX - maybe should mark
728 * ensure only one avl entry per chunk
730 find_inode_rec_range(agno
, ino
, ino
+ XFS_INODES_PER_CHUNK
,
731 &first_rec
, &last_rec
);
732 if (first_rec
!= NULL
) {
734 * this chunk overlaps with one (or more)
735 * already in the tree
738 _("inode rec for ino %llu (%d/%d) overlaps existing rec (start %d/%d)\n"),
739 lino
, agno
, ino
, agno
, first_rec
->ino_startnum
);
743 * if the 2 chunks start at the same place,
744 * then we don't have to put this one
745 * in the uncertain list. go to the next one.
747 if (first_rec
->ino_startnum
== ino
)
754 * now mark all the inodes as existing and free or used.
755 * if the tree is suspect, put them into the uncertain
759 if (XFS_INOBT_IS_FREE_DISK(rp
, 0)) {
761 ino_rec
= set_inode_free_alloc(agno
, ino
);
763 ino_rec
= set_inode_used_alloc(agno
, ino
);
765 for (j
= 1; j
< XFS_INODES_PER_CHUNK
; j
++) {
766 if (XFS_INOBT_IS_FREE_DISK(rp
, j
)) {
768 set_inode_free(ino_rec
, j
);
770 set_inode_used(ino_rec
, j
);
774 for (j
= 0; j
< XFS_INODES_PER_CHUNK
; j
++) {
775 if (XFS_INOBT_IS_FREE_DISK(rp
, j
)) {
777 add_aginode_uncertain(agno
, ino
+ j
, 1);
779 add_aginode_uncertain(agno
, ino
+ j
, 0);
784 if (nfree
!= be32_to_cpu(rp
->ir_freecount
)) {
785 do_warn(_("ir_freecount/free mismatch, inode "
786 "chunk %d/%d, freecount %d nfree %d\n"),
787 agno
, ino
, be32_to_cpu(rp
->ir_freecount
), nfree
);
795 * this one walks the inode btrees sucking the info there into
796 * the incore avl tree. We try and rescue corrupted btree records
797 * to minimize our chances of losing inodes. Inode info from potentially
798 * corrupt sources could be bogus so rather than put the info straight
799 * into the tree, instead we put it on a list and try and verify the
800 * info in the next phase by examining what's on disk. At that point,
801 * we'll be able to figure out what's what and stick the corrected info
802 * into the tree. We do bail out at some point and give up on a subtree
803 * so as to avoid walking randomly all over the ag.
805 * Note that it's also ok if the free/inuse info wrong, we can correct
806 * that when we examine the on-disk inode. The important thing is to
807 * get the start and alignment of the inode chunks right. Those chunks
808 * that we aren't sure about go into the uncertain list.
812 struct xfs_btree_block
*block
,
829 if (be32_to_cpu(block
->bb_magic
) != XFS_IBT_MAGIC
) {
830 do_warn(_("bad magic # %#x in inobt block %d/%d\n"),
831 be32_to_cpu(block
->bb_magic
), agno
, bno
);
837 if (be16_to_cpu(block
->bb_level
) != level
) {
838 do_warn(_("expected level %d got %d in inobt block %d/%d\n"),
839 level
, be16_to_cpu(block
->bb_level
), agno
, bno
);
847 * check for btree blocks multiply claimed, any unknown/free state
848 * is ok in the bitmap block.
850 state
= get_bmap(agno
, bno
);
855 set_bmap(agno
, bno
, XR_E_FS_MAP
);
858 set_bmap(agno
, bno
, XR_E_MULT
);
860 _("inode btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
861 state
, agno
, bno
, suspect
);
864 numrecs
= be16_to_cpu(block
->bb_numrecs
);
867 * leaf record in btree
870 /* check for trashed btree block */
872 if (numrecs
> mp
->m_inobt_mxr
[0]) {
873 numrecs
= mp
->m_inobt_mxr
[0];
876 if (isroot
== 0 && numrecs
< mp
->m_inobt_mnr
[0]) {
877 numrecs
= mp
->m_inobt_mnr
[0];
883 do_warn(_("dubious inode btree block header %d/%d\n"),
888 rp
= XFS_INOBT_REC_ADDR(mp
, block
, 1);
891 * step through the records, each record points to
892 * a chunk of inodes. The start of inode chunks should
893 * be block-aligned. Each inode btree rec should point
894 * to the start of a block of inodes or the start of a group
895 * of INODES_PER_CHUNK (64) inodes. off is the offset into
896 * the block. skip processing of bogus records.
898 for (i
= 0; i
< numrecs
; i
++)
899 suspect
= scan_single_ino_chunk(agno
, &rp
[i
], suspect
);
908 * interior record, continue on
910 if (numrecs
> mp
->m_inobt_mxr
[1]) {
911 numrecs
= mp
->m_inobt_mxr
[1];
914 if (isroot
== 0 && numrecs
< mp
->m_inobt_mnr
[1]) {
915 numrecs
= mp
->m_inobt_mnr
[1];
919 pp
= XFS_INOBT_PTR_ADDR(mp
, block
, 1, mp
->m_inobt_mxr
[1]);
922 * don't pass bogus tree flag down further if this block
923 * looked ok. bail out if two levels in a row look bad.
926 if (suspect
&& !hdr_errors
)
936 for (i
= 0; i
< numrecs
; i
++) {
937 if (be32_to_cpu(pp
[i
]) != 0 && verify_agbno(mp
, agno
,
939 scan_sbtree(be32_to_cpu(pp
[i
]), level
, agno
,
940 suspect
, scanfunc_ino
, 0);
955 agno
= be32_to_cpu(agf
->agf_seqno
);
957 if (XFS_SB_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
) &&
958 XFS_AGF_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
) &&
959 XFS_AGI_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
))
960 set_bmap(agno
, XFS_AGFL_BLOCK(mp
), XR_E_FS_MAP
);
962 if (be32_to_cpu(agf
->agf_flcount
) == 0)
965 agflbuf
= libxfs_readbuf(mp
->m_dev
,
966 XFS_AG_DADDR(mp
, agno
, XFS_AGFL_DADDR(mp
)),
967 XFS_FSS_TO_BB(mp
, 1), 0);
969 do_abort(_("can't read agfl block for ag %d\n"), agno
);
972 agfl
= XFS_BUF_TO_AGFL(agflbuf
);
973 i
= be32_to_cpu(agf
->agf_flfirst
);
976 bno
= be32_to_cpu(agfl
->agfl_bno
[i
]);
977 if (verify_agbno(mp
, agno
, bno
))
978 set_bmap(agno
, bno
, XR_E_FREE
);
980 do_warn(_("bad agbno %u in agfl, agno %d\n"),
983 if (i
== be32_to_cpu(agf
->agf_fllast
))
985 if (++i
== XFS_AGFL_SIZE(mp
))
988 if (count
!= be32_to_cpu(agf
->agf_flcount
)) {
989 do_warn(_("freeblk count %d != flcount %d in ag %d\n"), count
,
990 be32_to_cpu(agf
->agf_flcount
), agno
);
992 libxfs_putbuf(agflbuf
);
1010 agi_dirty
= agf_dirty
= sb_dirty
= 0;
1012 sbbuf
= libxfs_readbuf(mp
->m_dev
, XFS_AG_DADDR(mp
, agno
, XFS_SB_DADDR
),
1013 XFS_FSS_TO_BB(mp
, 1), 0);
1015 do_error(_("can't get root superblock for ag %d\n"), agno
);
1019 sb
= (xfs_sb_t
*)calloc(BBSIZE
, 1);
1021 do_error(_("can't allocate memory for superblock\n"));
1022 libxfs_putbuf(sbbuf
);
1025 libxfs_sb_from_disk(sb
, XFS_BUF_TO_SBP(sbbuf
));
1027 agfbuf
= libxfs_readbuf(mp
->m_dev
,
1028 XFS_AG_DADDR(mp
, agno
, XFS_AGF_DADDR(mp
)),
1029 XFS_FSS_TO_BB(mp
, 1), 0);
1031 do_error(_("can't read agf block for ag %d\n"), agno
);
1032 libxfs_putbuf(sbbuf
);
1036 agf
= XFS_BUF_TO_AGF(agfbuf
);
1038 agibuf
= libxfs_readbuf(mp
->m_dev
,
1039 XFS_AG_DADDR(mp
, agno
, XFS_AGI_DADDR(mp
)),
1040 XFS_FSS_TO_BB(mp
, 1), 0);
1042 do_error(_("can't read agi block for ag %d\n"), agno
);
1043 libxfs_putbuf(agfbuf
);
1044 libxfs_putbuf(sbbuf
);
1048 agi
= XFS_BUF_TO_AGI(agibuf
);
1050 /* fix up bad ag headers */
1052 status
= verify_set_agheader(mp
, sbbuf
, sb
, agf
, agi
, agno
);
1054 if (status
& XR_AG_SB_SEC
) {
1058 * clear bad sector bit because we don't want
1059 * to skip further processing. we just want to
1060 * ensure that we write out the modified sb buffer.
1062 status
&= ~XR_AG_SB_SEC
;
1064 if (status
& XR_AG_SB
) {
1066 do_warn(_("reset bad sb for ag %d\n"), agno
);
1069 do_warn(_("would reset bad sb for ag %d\n"), agno
);
1072 if (status
& XR_AG_AGF
) {
1074 do_warn(_("reset bad agf for ag %d\n"), agno
);
1077 do_warn(_("would reset bad agf for ag %d\n"), agno
);
1080 if (status
& XR_AG_AGI
) {
1082 do_warn(_("reset bad agi for ag %d\n"), agno
);
1085 do_warn(_("would reset bad agi for ag %d\n"), agno
);
1089 if (status
&& no_modify
) {
1090 libxfs_putbuf(agibuf
);
1091 libxfs_putbuf(agfbuf
);
1092 libxfs_putbuf(sbbuf
);
1095 do_warn(_("bad uncorrected agheader %d, skipping ag...\n"),
1103 if (be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_BNO
]) != 0 && verify_agbno(mp
,
1104 agno
, be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_BNO
])))
1105 scan_sbtree(be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_BNO
]),
1106 be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_BNO
]),
1107 agno
, 0, scanfunc_bno
, 1);
1109 do_warn(_("bad agbno %u for btbno root, agno %d\n"),
1110 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_BNO
]),
1113 if (be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_CNT
]) != 0 && verify_agbno(mp
,
1114 agno
, be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_CNT
])))
1115 scan_sbtree(be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_CNT
]),
1116 be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_CNT
]),
1117 agno
, 0, scanfunc_cnt
, 1);
1119 do_warn(_("bad agbno %u for btbcnt root, agno %d\n"),
1120 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_CNT
]),
1123 if (be32_to_cpu(agi
->agi_root
) != 0 && verify_agbno(mp
, agno
,
1124 be32_to_cpu(agi
->agi_root
)))
1125 scan_sbtree(be32_to_cpu(agi
->agi_root
),
1126 be32_to_cpu(agi
->agi_level
), agno
, 0, scanfunc_ino
, 1);
1128 do_warn(_("bad agbno %u for inobt root, agno %d\n"),
1129 be32_to_cpu(agi
->agi_root
), agno
);
1131 ASSERT(agi_dirty
== 0 || (agi_dirty
&& !no_modify
));
1133 if (agi_dirty
&& !no_modify
)
1134 libxfs_writebuf(agibuf
, 0);
1136 libxfs_putbuf(agibuf
);
1138 ASSERT(agf_dirty
== 0 || (agf_dirty
&& !no_modify
));
1140 if (agf_dirty
&& !no_modify
)
1141 libxfs_writebuf(agfbuf
, 0);
1143 libxfs_putbuf(agfbuf
);
1145 ASSERT(sb_dirty
== 0 || (sb_dirty
&& !no_modify
));
1147 if (sb_dirty
&& !no_modify
) {
1149 memcpy(&mp
->m_sb
, sb
, sizeof(xfs_sb_t
));
1150 libxfs_sb_to_disk(XFS_BUF_TO_SBP(sbbuf
), sb
, XFS_SB_ALL_BITS
);
1151 libxfs_writebuf(sbbuf
, 0);
1153 libxfs_putbuf(sbbuf
);
1155 PROG_RPT_INC(prog_rpt_done
[agno
], 1);