]>
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"
33 static xfs_mount_t
*mp
= NULL
;
36 * Variables to validate AG header values against the manual count
37 * from the btree traversal.
41 xfs_extlen_t agffreeblks
;
42 xfs_extlen_t agflongest
;
43 __uint64_t agfbtreeblks
;
45 __uint32_t agifreecount
;
47 __uint64_t ifreecount
;
48 __uint32_t fibtfreecount
;
52 set_mp(xfs_mount_t
*mpp
)
54 libxfs_bcache_purge();
64 void (*func
)(struct xfs_btree_block
*block
,
75 const struct xfs_buf_ops
*ops
)
79 bp
= libxfs_readbuf(mp
->m_dev
, XFS_AGB_TO_DADDR(mp
, agno
, root
),
80 XFS_FSB_TO_BB(mp
, 1), 0, ops
);
82 do_error(_("can't read btree block %d/%d\n"), agno
, root
);
85 if (bp
->b_error
== -EFSBADCRC
|| bp
->b_error
== -EFSCORRUPTED
) {
86 do_warn(_("btree block %d/%d is suspect, error %d\n"),
87 agno
, root
, bp
->b_error
);
91 (*func
)(XFS_BUF_TO_BLOCK(bp
), nlevels
- 1, root
, agno
, suspect
,
97 * returns 1 on bad news (inode needs to be cleared), 0 on good
103 int (*func
)(struct xfs_btree_block
*block
,
112 bmap_cursor_t
*bm_cursor
,
123 bmap_cursor_t
*bm_cursor
,
127 const struct xfs_buf_ops
*ops
)
134 bp
= libxfs_readbuf(mp
->m_dev
, XFS_FSB_TO_DADDR(mp
, root
),
135 XFS_FSB_TO_BB(mp
, 1), 0, ops
);
137 do_error(_("can't read btree block %d/%d\n"),
138 XFS_FSB_TO_AGNO(mp
, root
),
139 XFS_FSB_TO_AGBNO(mp
, root
));
144 * only check for bad CRC here - caller will determine if there
145 * is a corruption or not and whether it got corrected and so needs
146 * writing back. CRC errors always imply we need to write the block.
148 if (bp
->b_error
== -EFSBADCRC
) {
149 do_warn(_("btree block %d/%d is suspect, error %d\n"),
150 XFS_FSB_TO_AGNO(mp
, root
),
151 XFS_FSB_TO_AGBNO(mp
, root
), bp
->b_error
);
155 err
= (*func
)(XFS_BUF_TO_BLOCK(bp
), nlevels
- 1,
156 type
, whichfork
, root
, ino
, tot
, nex
, blkmapp
,
157 bm_cursor
, isroot
, check_dups
, &dirty
,
160 ASSERT(dirty
== 0 || (dirty
&& !no_modify
));
162 if ((dirty
|| badcrc
) && !no_modify
)
163 libxfs_writebuf(bp
, 0);
172 struct xfs_btree_block
*block
,
181 bmap_cursor_t
*bm_cursor
,
190 xfs_bmbt_key_t
*pkey
;
192 xfs_fileoff_t first_key
;
193 xfs_fileoff_t last_key
;
194 char *forkname
= get_forkname(whichfork
);
201 * unlike the ag freeblock btrees, if anything looks wrong
202 * in an inode bmap tree, just bail. it's possible that
203 * we'll miss a case where the to-be-toasted inode and
204 * another inode are claiming the same block but that's
207 if (be32_to_cpu(block
->bb_magic
) != magic
) {
209 _("bad magic # %#x in inode %" PRIu64
" (%s fork) bmbt block %" PRIu64
"\n"),
210 be32_to_cpu(block
->bb_magic
), ino
, forkname
, bno
);
213 if (be16_to_cpu(block
->bb_level
) != level
) {
215 _("expected level %d got %d in inode %" PRIu64
", (%s fork) bmbt block %" PRIu64
"\n"),
216 level
, be16_to_cpu(block
->bb_level
),
221 if (magic
== XFS_BMAP_CRC_MAGIC
) {
223 if (be64_to_cpu(block
->bb_u
.l
.bb_owner
) != ino
) {
225 _("expected owner inode %" PRIu64
", got %llu, bmbt block %" PRIu64
"\n"),
226 ino
, be64_to_cpu(block
->bb_u
.l
.bb_owner
), bno
);
229 /* verify block number */
230 if (be64_to_cpu(block
->bb_u
.l
.bb_blkno
) !=
231 XFS_FSB_TO_DADDR(mp
, bno
)) {
233 _("expected block %" PRIu64
", got %llu, bmbt block %" PRIu64
"\n"),
234 XFS_FSB_TO_DADDR(mp
, bno
),
235 be64_to_cpu(block
->bb_u
.l
.bb_blkno
), bno
);
239 if (platform_uuid_compare(&block
->bb_u
.l
.bb_uuid
,
240 &mp
->m_sb
.sb_meta_uuid
) != 0) {
242 _("wrong FS UUID, bmbt block %" PRIu64
"\n"),
248 if (check_dups
== 0) {
250 * check sibling pointers. if bad we have a conflict
251 * between the sibling pointers and the child pointers
252 * in the parent block. blow out the inode if that happens
254 if (bm_cursor
->level
[level
].fsbno
!= NULLFSBLOCK
) {
256 * this is not the first block on this level
257 * so the cursor for this level has recorded the
258 * values for this's block left-sibling.
260 if (bno
!= bm_cursor
->level
[level
].right_fsbno
) {
262 _("bad fwd (right) sibling pointer (saw %" PRIu64
" parent block says %" PRIu64
")\n"
263 "\tin inode %" PRIu64
" (%s fork) bmap btree block %" PRIu64
"\n"),
264 bm_cursor
->level
[level
].right_fsbno
,
266 bm_cursor
->level
[level
].fsbno
);
269 if (be64_to_cpu(block
->bb_u
.l
.bb_leftsib
) !=
270 bm_cursor
->level
[level
].fsbno
) {
272 _("bad back (left) sibling pointer (saw %llu parent block says %" PRIu64
")\n"
273 "\tin inode %" PRIu64
" (%s fork) bmap btree block %" PRIu64
"\n"),
275 be64_to_cpu(block
->bb_u
.l
.bb_leftsib
),
276 bm_cursor
->level
[level
].fsbno
,
282 * This is the first or only block on this level.
283 * Check that the left sibling pointer is NULL
285 if (be64_to_cpu(block
->bb_u
.l
.bb_leftsib
) != NULLFSBLOCK
) {
287 _("bad back (left) sibling pointer (saw %llu should be NULL (0))\n"
288 "\tin inode %" PRIu64
" (%s fork) bmap btree block %" PRIu64
"\n"),
290 be64_to_cpu(block
->bb_u
.l
.bb_leftsib
),
297 * update cursor block pointers to reflect this block
299 bm_cursor
->level
[level
].fsbno
= bno
;
300 bm_cursor
->level
[level
].left_fsbno
=
301 be64_to_cpu(block
->bb_u
.l
.bb_leftsib
);
302 bm_cursor
->level
[level
].right_fsbno
=
303 be64_to_cpu(block
->bb_u
.l
.bb_rightsib
);
305 agno
= XFS_FSB_TO_AGNO(mp
, bno
);
306 agbno
= XFS_FSB_TO_AGBNO(mp
, bno
);
308 pthread_mutex_lock(&ag_locks
[agno
].lock
);
309 state
= get_bmap(agno
, agbno
);
314 set_bmap(agno
, agbno
, XR_E_INUSE
);
319 * we'll try and continue searching here since
320 * the block looks like it's been claimed by file
321 * to store user data, a directory to store directory
322 * data, or the space allocation btrees but since
323 * we made it here, the block probably
324 * contains btree data.
326 set_bmap(agno
, agbno
, XR_E_MULT
);
328 _("inode 0x%" PRIx64
"bmap block 0x%" PRIx64
" claimed, state is %d\n"),
333 set_bmap(agno
, agbno
, XR_E_MULT
);
335 _("inode 0x%" PRIx64
" bmap block 0x%" PRIx64
" claimed, state is %d\n"),
338 * if we made it to here, this is probably a bmap block
339 * that is being used by *another* file as a bmap block
340 * so the block will be valid. Both files should be
341 * trashed along with any other file that impinges on
342 * any blocks referenced by either file. So we
343 * continue searching down this btree to mark all
350 _("bad state %d, inode %" PRIu64
" bmap block 0x%" PRIx64
"\n"),
354 pthread_mutex_unlock(&ag_locks
[agno
].lock
);
357 * attribute fork for realtime files is in the regular
360 if (type
!= XR_INO_RTDATA
|| whichfork
!= XFS_DATA_FORK
) {
361 if (search_dup_extent(XFS_FSB_TO_AGNO(mp
, bno
),
362 XFS_FSB_TO_AGBNO(mp
, bno
),
363 XFS_FSB_TO_AGBNO(mp
, bno
) + 1))
366 if (search_rt_dup_extent(mp
, bno
))
371 numrecs
= be16_to_cpu(block
->bb_numrecs
);
374 if (numrecs
> mp
->m_bmap_dmxr
[0] || (isroot
== 0 && numrecs
<
375 mp
->m_bmap_dmnr
[0])) {
377 _("inode %" PRIu64
" bad # of bmap records (%u, min - %u, max - %u)\n"),
378 ino
, numrecs
, mp
->m_bmap_dmnr
[0],
382 rp
= XFS_BMBT_REC_ADDR(mp
, block
, 1);
385 * XXX - if we were going to fix up the btree record,
386 * we'd do it right here. For now, if there's a problem,
387 * we'll bail out and presumably clear the inode.
389 if (check_dups
== 0) {
390 err
= process_bmbt_reclist(mp
, rp
, &numrecs
, type
, ino
,
391 tot
, blkmapp
, &first_key
,
392 &last_key
, whichfork
);
397 * check that key ordering is monotonically increasing.
398 * if the last_key value in the cursor is set to
399 * NULLFILEOFF, then we know this is the first block
400 * on the leaf level and we shouldn't check the
403 if (first_key
<= bm_cursor
->level
[level
].last_key
&&
404 bm_cursor
->level
[level
].last_key
!=
407 _("out-of-order bmap key (file offset) in inode %" PRIu64
", %s fork, fsbno %" PRIu64
"\n"),
412 * update cursor keys to reflect this block.
413 * don't have to check if last_key is > first_key
414 * since that gets checked by process_bmbt_reclist.
416 bm_cursor
->level
[level
].first_key
= first_key
;
417 bm_cursor
->level
[level
].last_key
= last_key
;
421 return scan_bmbt_reclist(mp
, rp
, &numrecs
, type
, ino
,
425 if (numrecs
> mp
->m_bmap_dmxr
[1] || (isroot
== 0 && numrecs
<
426 mp
->m_bmap_dmnr
[1])) {
428 _("inode %" PRIu64
" bad # of bmap records (%u, min - %u, max - %u)\n"),
429 ino
, numrecs
, mp
->m_bmap_dmnr
[1], mp
->m_bmap_dmxr
[1]);
432 pp
= XFS_BMBT_PTR_ADDR(mp
, block
, 1, mp
->m_bmap_dmxr
[1]);
433 pkey
= XFS_BMBT_KEY_ADDR(mp
, block
, 1);
435 last_key
= NULLFILEOFF
;
437 for (i
= 0, err
= 0; i
< numrecs
; i
++) {
439 * XXX - if we were going to fix up the interior btree nodes,
440 * we'd do it right here. For now, if there's a problem,
441 * we'll bail out and presumably clear the inode.
443 if (!verify_dfsbno(mp
, be64_to_cpu(pp
[i
]))) {
445 _("bad bmap btree ptr 0x%llx in ino %" PRIu64
"\n"),
446 (unsigned long long) be64_to_cpu(pp
[i
]), ino
);
450 err
= scan_lbtree(be64_to_cpu(pp
[i
]), level
, scan_bmapbt
,
451 type
, whichfork
, ino
, tot
, nex
, blkmapp
,
452 bm_cursor
, 0, check_dups
, magic
,
458 * fix key (offset) mismatches between the first key
459 * in the child block (as recorded in the cursor) and the
460 * key in the interior node referencing the child block.
462 * fixes cases where entries have been shifted between
463 * child blocks but the parent hasn't been updated. We
464 * don't have to worry about the key values in the cursor
465 * not being set since we only look at the key values of
466 * our child and those are guaranteed to be set by the
467 * call to scan_lbtree() above.
469 if (check_dups
== 0 && be64_to_cpu(pkey
[i
].br_startoff
) !=
470 bm_cursor
->level
[level
-1].first_key
) {
473 _("correcting bt key (was %llu, now %" PRIu64
") in inode %" PRIu64
"\n"
474 "\t\t%s fork, btree block %" PRIu64
"\n"),
476 be64_to_cpu(pkey
[i
].br_startoff
),
477 bm_cursor
->level
[level
-1].first_key
,
481 pkey
[i
].br_startoff
= cpu_to_be64(
482 bm_cursor
->level
[level
-1].first_key
);
485 _("bad btree key (is %llu, should be %" PRIu64
") in inode %" PRIu64
"\n"
486 "\t\t%s fork, btree block %" PRIu64
"\n"),
488 be64_to_cpu(pkey
[i
].br_startoff
),
489 bm_cursor
->level
[level
-1].first_key
,
496 * If we're the last node at our level, check that the last child
497 * block's forward sibling pointer is NULL.
499 if (check_dups
== 0 &&
500 bm_cursor
->level
[level
].right_fsbno
== NULLFSBLOCK
&&
501 bm_cursor
->level
[level
- 1].right_fsbno
!= NULLFSBLOCK
) {
503 _("bad fwd (right) sibling pointer (saw %" PRIu64
" should be NULLFSBLOCK)\n"
504 "\tin inode %" PRIu64
" (%s fork) bmap btree block %" PRIu64
"\n"),
505 bm_cursor
->level
[level
- 1].right_fsbno
,
506 ino
, forkname
, bm_cursor
->level
[level
- 1].fsbno
);
511 * update cursor keys to reflect this block
513 if (check_dups
== 0) {
514 bm_cursor
->level
[level
].first_key
=
515 be64_to_cpu(pkey
[0].br_startoff
);
516 bm_cursor
->level
[level
].last_key
=
517 be64_to_cpu(pkey
[numrecs
- 1].br_startoff
);
525 struct xfs_btree_block
*block
,
534 struct aghdr_cnts
*agcnts
= priv
;
542 xfs_extlen_t lastcount
= 0;
543 xfs_agblock_t lastblock
= 0;
546 case XFS_ABTB_CRC_MAGIC
:
550 case XFS_ABTC_CRC_MAGIC
:
560 if (be32_to_cpu(block
->bb_magic
) != magic
) {
561 do_warn(_("bad magic # %#x in bt%s block %d/%d\n"),
562 be32_to_cpu(block
->bb_magic
), name
, agno
, bno
);
569 * All freespace btree blocks except the roots are freed for a
570 * fully used filesystem, thus they are counted towards the
571 * free data block counter.
574 agcnts
->agfbtreeblks
++;
578 if (be16_to_cpu(block
->bb_level
) != level
) {
579 do_warn(_("expected level %d got %d in bt%s block %d/%d\n"),
580 level
, be16_to_cpu(block
->bb_level
), name
, agno
, bno
);
587 * check for btree blocks multiply claimed
589 state
= get_bmap(agno
, bno
);
590 if (state
!= XR_E_UNKNOWN
) {
591 set_bmap(agno
, bno
, XR_E_MULT
);
593 _("%s freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
594 name
, state
, agno
, bno
, suspect
);
597 set_bmap(agno
, bno
, XR_E_FS_MAP
);
599 numrecs
= be16_to_cpu(block
->bb_numrecs
);
602 if (numrecs
> mp
->m_alloc_mxr
[0]) {
603 numrecs
= mp
->m_alloc_mxr
[0];
606 if (isroot
== 0 && numrecs
< mp
->m_alloc_mnr
[0]) {
607 numrecs
= mp
->m_alloc_mnr
[0];
613 _("bad btree nrecs (%u, min=%u, max=%u) in bt%s block %u/%u\n"),
614 be16_to_cpu(block
->bb_numrecs
),
615 mp
->m_alloc_mnr
[0], mp
->m_alloc_mxr
[0],
620 rp
= XFS_ALLOC_REC_ADDR(mp
, block
, 1);
621 for (i
= 0; i
< numrecs
; i
++) {
622 xfs_agblock_t b
, end
;
623 xfs_extlen_t len
, blen
;
625 b
= be32_to_cpu(rp
[i
].ar_startblock
);
626 len
= be32_to_cpu(rp
[i
].ar_blockcount
);
629 if (b
== 0 || !verify_agbno(mp
, agno
, b
)) {
631 _("invalid start block %u in record %u of %s btree block %u/%u\n"),
632 b
, i
, name
, agno
, bno
);
635 if (len
== 0 || !verify_agbno(mp
, agno
, end
- 1)) {
637 _("invalid length %u in record %u of %s btree block %u/%u\n"),
638 len
, i
, name
, agno
, bno
);
642 if (magic
== XFS_ABTB_MAGIC
||
643 magic
== XFS_ABTB_CRC_MAGIC
) {
644 if (b
<= lastblock
) {
646 "out-of-order bno btree record %d (%u %u) block %u/%u\n"),
647 i
, b
, len
, agno
, bno
);
652 agcnts
->fdblocks
+= len
;
653 agcnts
->agffreeblks
+= len
;
654 if (len
> agcnts
->agflongest
)
655 agcnts
->agflongest
= len
;
656 if (len
< lastcount
) {
658 "out-of-order cnt btree record %d (%u %u) block %u/%u\n"),
659 i
, b
, len
, agno
, bno
);
665 for ( ; b
< end
; b
+= blen
) {
666 state
= get_bmap_ext(agno
, b
, end
, &blen
);
669 set_bmap(agno
, b
, XR_E_FREE1
);
673 * no warning messages -- we'll catch
676 if (magic
== XFS_ABTC_MAGIC
||
677 magic
== XFS_ABTC_CRC_MAGIC
) {
678 set_bmap_ext(agno
, b
, blen
,
684 _("block (%d,%d-%d) multiply claimed by %s space tree, state - %d\n"),
685 agno
, b
, b
+ blen
- 1,
697 pp
= XFS_ALLOC_PTR_ADDR(mp
, block
, 1, mp
->m_alloc_mxr
[1]);
699 if (numrecs
> mp
->m_alloc_mxr
[1]) {
700 numrecs
= mp
->m_alloc_mxr
[1];
703 if (isroot
== 0 && numrecs
< mp
->m_alloc_mnr
[1]) {
704 numrecs
= mp
->m_alloc_mnr
[1];
709 * don't pass bogus tree flag down further if this block
710 * looked ok. bail out if two levels in a row look bad.
714 _("bad btree nrecs (%u, min=%u, max=%u) in bt%s block %u/%u\n"),
715 be16_to_cpu(block
->bb_numrecs
),
716 mp
->m_alloc_mnr
[1], mp
->m_alloc_mxr
[1],
721 } else if (suspect
) {
725 for (i
= 0; i
< numrecs
; i
++) {
726 xfs_agblock_t bno
= be32_to_cpu(pp
[i
]);
729 * XXX - put sibling detection right here.
730 * we know our sibling chain is good. So as we go,
731 * we check the entry before and after each entry.
732 * If either of the entries references a different block,
733 * check the sibling pointer. If there's a sibling
734 * pointer mismatch, try and extract as much data
737 if (bno
!= 0 && verify_agbno(mp
, agno
, bno
)) {
739 case XFS_ABTB_CRC_MAGIC
:
741 scan_sbtree(bno
, level
, agno
, suspect
,
742 scan_allocbt
, 0, magic
, priv
,
743 &xfs_allocbt_buf_ops
);
745 case XFS_ABTC_CRC_MAGIC
:
747 scan_sbtree(bno
, level
, agno
, suspect
,
748 scan_allocbt
, 0, magic
, priv
,
749 &xfs_allocbt_buf_ops
);
758 struct xfs_inobt_rec
*rp
,
761 if (!xfs_sb_version_hassparseinodes(&mp
->m_sb
))
764 return xfs_inobt_is_sparse_disk(rp
, offset
);
768 * The following helpers are to help process and validate individual on-disk
769 * inode btree records. We have two possible inode btrees with slightly
770 * different semantics. Many of the validations and actions are equivalent, such
771 * as record alignment constraints, etc. Other validations differ, such as the
772 * fact that the inode chunk block allocation state is set by the content of the
773 * core inobt and verified by the content of the finobt.
775 * The following structures are used to facilitate common validation routines
776 * where the only difference between validation of the inobt or finobt might be
777 * the error messages that results in the event of failure.
784 const char *inobt_names
[] = {
790 verify_single_ino_chunk_align(
792 enum inobt_type type
,
793 struct xfs_inobt_rec
*rp
,
797 const char *inobt_name
= inobt_names
[type
];
804 ino
= be32_to_cpu(rp
->ir_startino
);
805 off
= XFS_AGINO_TO_OFFSET(mp
, ino
);
806 agbno
= XFS_AGINO_TO_AGBNO(mp
, ino
);
807 lino
= XFS_AGINO_TO_INO(mp
, agno
, ino
);
810 * on multi-block block chunks, all chunks start at the beginning of the
811 * block. with multi-chunk blocks, all chunks must start on 64-inode
812 * boundaries since each block can hold N complete chunks. if fs has
813 * aligned inodes, all chunks must start at a fs_ino_alignment*N'th
814 * agbno. skip recs with badly aligned starting inodes.
817 (inodes_per_block
<= XFS_INODES_PER_CHUNK
&& off
!= 0) ||
818 (inodes_per_block
> XFS_INODES_PER_CHUNK
&&
819 off
% XFS_INODES_PER_CHUNK
!= 0) ||
820 (fs_aligned_inodes
&& fs_ino_alignment
&&
821 agbno
% fs_ino_alignment
!= 0)) {
823 _("badly aligned %s rec (starting inode = %" PRIu64
")\n"),
829 * verify numeric validity of inode chunk first before inserting into a
830 * tree. don't have to worry about the overflow case because the
831 * starting ino number of a chunk can only get within 255 inodes of max
832 * (NULLAGINO). if it gets closer, the agino number will be illegal as
833 * the agbno will be too large.
835 if (verify_aginum(mp
, agno
, ino
)) {
837 _("bad starting inode # (%" PRIu64
" (0x%x 0x%x)) in %s rec, skipping rec\n"),
838 lino
, agno
, ino
, inobt_name
);
843 if (verify_aginum(mp
, agno
,
844 ino
+ XFS_INODES_PER_CHUNK
- 1)) {
846 _("bad ending inode # (%" PRIu64
" (0x%x 0x%zx)) in %s rec, skipping rec\n"),
847 lino
+ XFS_INODES_PER_CHUNK
- 1,
849 ino
+ XFS_INODES_PER_CHUNK
- 1,
859 * Process the state of individual inodes in an on-disk inobt record and import
860 * into the appropriate in-core tree based on whether the on-disk tree is
861 * suspect. Return the total and free inode counts based on the record free and
865 import_single_ino_chunk(
867 enum inobt_type type
,
868 struct xfs_inobt_rec
*rp
,
873 struct ino_tree_node
*ino_rec
= NULL
;
874 const char *inobt_name
= inobt_names
[type
];
880 ino
= be32_to_cpu(rp
->ir_startino
);
883 if (XFS_INOBT_IS_FREE_DISK(rp
, 0))
884 ino_rec
= set_inode_free_alloc(mp
, agno
, ino
);
886 ino_rec
= set_inode_used_alloc(mp
, agno
, ino
);
887 for (j
= 1; j
< XFS_INODES_PER_CHUNK
; j
++) {
888 if (XFS_INOBT_IS_FREE_DISK(rp
, j
))
889 set_inode_free(ino_rec
, j
);
891 set_inode_used(ino_rec
, j
);
894 for (j
= 0; j
< XFS_INODES_PER_CHUNK
; j
++) {
895 if (XFS_INOBT_IS_FREE_DISK(rp
, j
))
896 add_aginode_uncertain(mp
, agno
, ino
+ j
, 1);
898 add_aginode_uncertain(mp
, agno
, ino
+ j
, 0);
903 * Mark sparse inodes as such in the in-core tree. Verify that sparse
904 * inodes are free and that freecount is consistent with the free mask.
907 for (j
= 0; j
< XFS_INODES_PER_CHUNK
; j
++) {
908 if (ino_issparse(rp
, j
)) {
909 if (!suspect
&& !XFS_INOBT_IS_FREE_DISK(rp
, j
)) {
911 _("ir_holemask/ir_free mismatch, %s chunk %d/%u, holemask 0x%x free 0x%llx\n"),
912 inobt_name
, agno
, ino
,
913 be16_to_cpu(rp
->ir_u
.sp
.ir_holemask
),
914 be64_to_cpu(rp
->ir_free
));
917 if (!suspect
&& ino_rec
)
918 set_inode_sparse(ino_rec
, j
);
920 /* count fields track non-sparse inos */
921 if (XFS_INOBT_IS_FREE_DISK(rp
, j
))
928 *p_ninodes
= ninodes
;
934 scan_single_ino_chunk(
947 ino_tree_node_t
*first_rec
, *last_rec
;
951 ino
= be32_to_cpu(rp
->ir_startino
);
952 off
= XFS_AGINO_TO_OFFSET(mp
, ino
);
953 agbno
= XFS_AGINO_TO_AGBNO(mp
, ino
);
954 lino
= XFS_AGINO_TO_INO(mp
, agno
, ino
);
955 freecount
= inorec_get_freecount(mp
, rp
);
958 * Verify record alignment, start/end inode numbers, etc.
960 suspect
= verify_single_ino_chunk_align(agno
, INOBT
, rp
, suspect
,
966 * set state of each block containing inodes
968 if (off
== 0 && !suspect
) {
970 j
< XFS_INODES_PER_CHUNK
;
971 j
+= mp
->m_sb
.sb_inopblock
) {
973 /* inodes in sparse chunks don't use blocks */
974 if (ino_issparse(rp
, j
))
977 agbno
= XFS_AGINO_TO_AGBNO(mp
, ino
+ j
);
978 state
= get_bmap(agno
, agbno
);
979 if (state
== XR_E_UNKNOWN
) {
980 set_bmap(agno
, agbno
, XR_E_INO
);
981 } else if (state
== XR_E_INUSE_FS
&& agno
== 0 &&
982 ino
+ j
>= first_prealloc_ino
&&
983 ino
+ j
< last_prealloc_ino
) {
984 set_bmap(agno
, agbno
, XR_E_INO
);
987 _("inode chunk claims used block, inobt block - agno %d, bno %d, inopb %d\n"),
988 agno
, agbno
, mp
->m_sb
.sb_inopblock
);
990 * XXX - maybe should mark
999 * ensure only one avl entry per chunk
1001 find_inode_rec_range(mp
, agno
, ino
, ino
+ XFS_INODES_PER_CHUNK
,
1002 &first_rec
, &last_rec
);
1003 if (first_rec
!= NULL
) {
1005 * this chunk overlaps with one (or more)
1006 * already in the tree
1009 _("inode rec for ino %" PRIu64
" (%d/%d) overlaps existing rec (start %d/%d)\n"),
1010 lino
, agno
, ino
, agno
, first_rec
->ino_startnum
);
1014 * if the 2 chunks start at the same place,
1015 * then we don't have to put this one
1016 * in the uncertain list. go to the next one.
1018 if (first_rec
->ino_startnum
== ino
)
1023 * Import the state of individual inodes into the appropriate in-core
1024 * trees, mark them free or used, and get the resulting total and free
1027 nfree
= ninodes
= 0;
1028 suspect
= import_single_ino_chunk(agno
, INOBT
, rp
, suspect
, &nfree
,
1031 if (nfree
!= freecount
) {
1033 _("ir_freecount/free mismatch, inode chunk %d/%u, freecount %d nfree %d\n"),
1034 agno
, ino
, freecount
, nfree
);
1037 /* verify sparse record formats have a valid inode count */
1038 if (xfs_sb_version_hassparseinodes(&mp
->m_sb
) &&
1039 ninodes
!= rp
->ir_u
.sp
.ir_count
) {
1041 _("invalid inode count, inode chunk %d/%u, count %d ninodes %d\n"),
1042 agno
, ino
, rp
->ir_u
.sp
.ir_count
, ninodes
);
1049 scan_single_finobt_chunk(
1050 xfs_agnumber_t agno
,
1051 xfs_inobt_rec_t
*rp
,
1056 xfs_agblock_t agbno
;
1062 ino_tree_node_t
*first_rec
, *last_rec
;
1066 ino
= be32_to_cpu(rp
->ir_startino
);
1067 off
= XFS_AGINO_TO_OFFSET(mp
, ino
);
1068 agbno
= XFS_AGINO_TO_AGBNO(mp
, ino
);
1069 lino
= XFS_AGINO_TO_INO(mp
, agno
, ino
);
1070 freecount
= inorec_get_freecount(mp
, rp
);
1073 * Verify record alignment, start/end inode numbers, etc.
1075 suspect
= verify_single_ino_chunk_align(agno
, FINOBT
, rp
, suspect
,
1081 * cross check state of each block containing inodes referenced by the
1082 * finobt against what we have already scanned from the alloc inobt.
1084 if (off
== 0 && !suspect
) {
1086 j
< XFS_INODES_PER_CHUNK
;
1087 j
+= mp
->m_sb
.sb_inopblock
) {
1088 agbno
= XFS_AGINO_TO_AGBNO(mp
, ino
+ j
);
1089 state
= get_bmap(agno
, agbno
);
1091 /* sparse inodes should not refer to inode blocks */
1092 if (ino_issparse(rp
, j
)) {
1093 if (state
== XR_E_INO
) {
1095 _("sparse inode chunk claims inode block, finobt block - agno %d, bno %d, inopb %d\n"),
1096 agno
, agbno
, mp
->m_sb
.sb_inopblock
);
1102 if (state
== XR_E_INO
) {
1104 } else if ((state
== XR_E_UNKNOWN
) ||
1105 (state
== XR_E_INUSE_FS
&& agno
== 0 &&
1106 ino
+ j
>= first_prealloc_ino
&&
1107 ino
+ j
< last_prealloc_ino
)) {
1109 _("inode chunk claims untracked block, finobt block - agno %d, bno %d, inopb %d\n"),
1110 agno
, agbno
, mp
->m_sb
.sb_inopblock
);
1112 set_bmap(agno
, agbno
, XR_E_INO
);
1116 _("inode chunk claims used block, finobt block - agno %d, bno %d, inopb %d\n"),
1117 agno
, agbno
, mp
->m_sb
.sb_inopblock
);
1124 * ensure we have an incore entry for each chunk
1126 find_inode_rec_range(mp
, agno
, ino
, ino
+ XFS_INODES_PER_CHUNK
,
1127 &first_rec
, &last_rec
);
1134 * verify consistency between finobt record and incore state
1136 if (first_rec
->ino_startnum
!= ino
) {
1138 _("finobt rec for ino %" PRIu64
" (%d/%u) does not match existing rec (%d/%d)\n"),
1139 lino
, agno
, ino
, agno
, first_rec
->ino_startnum
);
1143 nfree
= ninodes
= 0;
1144 for (j
= 0; j
< XFS_INODES_PER_CHUNK
; j
++) {
1145 int isfree
= XFS_INOBT_IS_FREE_DISK(rp
, j
);
1146 int issparse
= ino_issparse(rp
, j
);
1150 if (isfree
&& !issparse
)
1154 * inode allocation state should be consistent between
1155 * the inobt and finobt
1158 isfree
!= is_inode_free(first_rec
, j
))
1162 issparse
!= is_inode_sparse(first_rec
, j
))
1166 goto check_freecount
;
1170 * The finobt contains a record that the previous inobt scan never
1171 * found. Warn about it and import the inodes into the appropriate
1174 * Note that this should do the right thing if the previous inobt scan
1175 * had added these inodes to the uncertain tree. If the finobt is not
1176 * suspect, these inodes should supercede the uncertain ones. Otherwise,
1177 * the uncertain tree helpers handle the case where uncertain inodes
1180 do_warn(_("undiscovered finobt record, ino %" PRIu64
" (%d/%u)\n"),
1183 nfree
= ninodes
= 0;
1184 suspect
= import_single_ino_chunk(agno
, FINOBT
, rp
, suspect
, &nfree
,
1190 * Verify that the record freecount matches the actual number of free
1191 * inodes counted in the record. Don't increment 'suspect' here, since
1192 * we have already verified the allocation state of the individual
1193 * inodes against the in-core state. This will have already incremented
1194 * 'suspect' if something is wrong. If suspect hasn't been set at this
1195 * point, these warnings mean that we have a simple freecount
1196 * inconsistency or a stray finobt record (as opposed to a broader tree
1197 * corruption). Issue a warning and continue the scan. The final btree
1198 * reconstruction will correct this naturally.
1200 if (nfree
!= freecount
) {
1202 _("finobt ir_freecount/free mismatch, inode chunk %d/%u, freecount %d nfree %d\n"),
1203 agno
, ino
, freecount
, nfree
);
1208 _("finobt record with no free inodes, inode chunk %d/%u\n"), agno
, ino
);
1211 /* verify sparse record formats have a valid inode count */
1212 if (xfs_sb_version_hassparseinodes(&mp
->m_sb
) &&
1213 ninodes
!= rp
->ir_u
.sp
.ir_count
) {
1215 _("invalid inode count, inode chunk %d/%u, count %d ninodes %d\n"),
1216 agno
, ino
, rp
->ir_u
.sp
.ir_count
, ninodes
);
1223 * this one walks the inode btrees sucking the info there into
1224 * the incore avl tree. We try and rescue corrupted btree records
1225 * to minimize our chances of losing inodes. Inode info from potentially
1226 * corrupt sources could be bogus so rather than put the info straight
1227 * into the tree, instead we put it on a list and try and verify the
1228 * info in the next phase by examining what's on disk. At that point,
1229 * we'll be able to figure out what's what and stick the corrected info
1230 * into the tree. We do bail out at some point and give up on a subtree
1231 * so as to avoid walking randomly all over the ag.
1233 * Note that it's also ok if the free/inuse info wrong, we can correct
1234 * that when we examine the on-disk inode. The important thing is to
1235 * get the start and alignment of the inode chunks right. Those chunks
1236 * that we aren't sure about go into the uncertain list.
1240 struct xfs_btree_block
*block
,
1243 xfs_agnumber_t agno
,
1249 struct aghdr_cnts
*agcnts
= priv
;
1253 xfs_inobt_ptr_t
*pp
;
1254 xfs_inobt_rec_t
*rp
;
1260 if (be32_to_cpu(block
->bb_magic
) != magic
) {
1261 do_warn(_("bad magic # %#x in inobt block %d/%d\n"),
1262 be32_to_cpu(block
->bb_magic
), agno
, bno
);
1268 if (be16_to_cpu(block
->bb_level
) != level
) {
1269 do_warn(_("expected level %d got %d in inobt block %d/%d\n"),
1270 level
, be16_to_cpu(block
->bb_level
), agno
, bno
);
1278 * check for btree blocks multiply claimed, any unknown/free state
1279 * is ok in the bitmap block.
1281 state
= get_bmap(agno
, bno
);
1286 set_bmap(agno
, bno
, XR_E_FS_MAP
);
1289 set_bmap(agno
, bno
, XR_E_MULT
);
1291 _("inode btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
1292 state
, agno
, bno
, suspect
);
1295 numrecs
= be16_to_cpu(block
->bb_numrecs
);
1298 * leaf record in btree
1301 /* check for trashed btree block */
1303 if (numrecs
> mp
->m_inobt_mxr
[0]) {
1304 numrecs
= mp
->m_inobt_mxr
[0];
1307 if (isroot
== 0 && numrecs
< mp
->m_inobt_mnr
[0]) {
1308 numrecs
= mp
->m_inobt_mnr
[0];
1314 do_warn(_("dubious inode btree block header %d/%d\n"),
1319 rp
= XFS_INOBT_REC_ADDR(mp
, block
, 1);
1322 * step through the records, each record points to
1323 * a chunk of inodes. The start of inode chunks should
1324 * be block-aligned. Each inode btree rec should point
1325 * to the start of a block of inodes or the start of a group
1326 * of INODES_PER_CHUNK (64) inodes. off is the offset into
1327 * the block. skip processing of bogus records.
1329 for (i
= 0; i
< numrecs
; i
++) {
1330 freecount
= inorec_get_freecount(mp
, &rp
[i
]);
1332 if (magic
== XFS_IBT_MAGIC
||
1333 magic
== XFS_IBT_CRC_MAGIC
) {
1334 int icount
= XFS_INODES_PER_CHUNK
;
1337 * ir_count holds the inode count for all
1338 * records on fs' with sparse inode support
1340 if (xfs_sb_version_hassparseinodes(&mp
->m_sb
))
1341 icount
= rp
[i
].ir_u
.sp
.ir_count
;
1343 agcnts
->agicount
+= icount
;
1344 agcnts
->agifreecount
+= freecount
;
1345 agcnts
->ifreecount
+= freecount
;
1347 suspect
= scan_single_ino_chunk(agno
, &rp
[i
],
1351 * the finobt tracks records with free inodes,
1352 * so only the free inode count is expected to be
1353 * consistent with the agi
1355 agcnts
->fibtfreecount
+= freecount
;
1357 suspect
= scan_single_finobt_chunk(agno
, &rp
[i
],
1369 * interior record, continue on
1371 if (numrecs
> mp
->m_inobt_mxr
[1]) {
1372 numrecs
= mp
->m_inobt_mxr
[1];
1375 if (isroot
== 0 && numrecs
< mp
->m_inobt_mnr
[1]) {
1376 numrecs
= mp
->m_inobt_mnr
[1];
1380 pp
= XFS_INOBT_PTR_ADDR(mp
, block
, 1, mp
->m_inobt_mxr
[1]);
1383 * don't pass bogus tree flag down further if this block
1384 * looked ok. bail out if two levels in a row look bad.
1387 if (suspect
&& !hdr_errors
)
1397 for (i
= 0; i
< numrecs
; i
++) {
1398 if (be32_to_cpu(pp
[i
]) != 0 && verify_agbno(mp
, agno
,
1399 be32_to_cpu(pp
[i
])))
1400 scan_sbtree(be32_to_cpu(pp
[i
]), level
, agno
,
1401 suspect
, scan_inobt
, 0, magic
, priv
,
1402 &xfs_inobt_buf_ops
);
1409 struct aghdr_cnts
*agcnts
)
1412 xfs_agnumber_t agno
;
1418 agno
= be32_to_cpu(agf
->agf_seqno
);
1420 if (XFS_SB_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
) &&
1421 XFS_AGF_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
) &&
1422 XFS_AGI_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
))
1423 set_bmap(agno
, XFS_AGFL_BLOCK(mp
), XR_E_FS_MAP
);
1425 if (be32_to_cpu(agf
->agf_flcount
) == 0)
1428 agflbuf
= libxfs_readbuf(mp
->m_dev
,
1429 XFS_AG_DADDR(mp
, agno
, XFS_AGFL_DADDR(mp
)),
1430 XFS_FSS_TO_BB(mp
, 1), 0, &xfs_agfl_buf_ops
);
1432 do_abort(_("can't read agfl block for ag %d\n"), agno
);
1435 if (agflbuf
->b_error
== -EFSBADCRC
)
1436 do_warn(_("agfl has bad CRC for ag %d\n"), agno
);
1438 freelist
= XFS_BUF_TO_AGFL_BNO(mp
, agflbuf
);
1439 i
= be32_to_cpu(agf
->agf_flfirst
);
1442 /* agf values not fixed in verify_set_agf, so recheck */
1443 if (be32_to_cpu(agf
->agf_flfirst
) >= XFS_AGFL_SIZE(mp
) ||
1444 be32_to_cpu(agf
->agf_fllast
) >= XFS_AGFL_SIZE(mp
)) {
1445 do_warn(_("agf %d freelist blocks bad, skipping "
1446 "freelist scan\n"), i
);
1453 bno
= be32_to_cpu(freelist
[i
]);
1454 if (verify_agbno(mp
, agno
, bno
))
1455 set_bmap(agno
, bno
, XR_E_FREE
);
1457 do_warn(_("bad agbno %u in agfl, agno %d\n"),
1460 if (i
== be32_to_cpu(agf
->agf_fllast
))
1462 if (++i
== XFS_AGFL_SIZE(mp
))
1465 if (count
!= be32_to_cpu(agf
->agf_flcount
)) {
1466 do_warn(_("freeblk count %d != flcount %d in ag %d\n"), count
,
1467 be32_to_cpu(agf
->agf_flcount
), agno
);
1470 agcnts
->fdblocks
+= count
;
1472 libxfs_putbuf(agflbuf
);
1477 struct xfs_agf
*agf
,
1478 xfs_agnumber_t agno
,
1479 struct aghdr_cnts
*agcnts
)
1484 bno
= be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_BNO
]);
1485 if (bno
!= 0 && verify_agbno(mp
, agno
, bno
)) {
1486 magic
= xfs_sb_version_hascrc(&mp
->m_sb
) ? XFS_ABTB_CRC_MAGIC
1488 scan_sbtree(bno
, be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_BNO
]),
1489 agno
, 0, scan_allocbt
, 1, magic
, agcnts
,
1490 &xfs_allocbt_buf_ops
);
1492 do_warn(_("bad agbno %u for btbno root, agno %d\n"),
1496 bno
= be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_CNT
]);
1497 if (bno
!= 0 && verify_agbno(mp
, agno
, bno
)) {
1498 magic
= xfs_sb_version_hascrc(&mp
->m_sb
) ? XFS_ABTC_CRC_MAGIC
1500 scan_sbtree(bno
, be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_CNT
]),
1501 agno
, 0, scan_allocbt
, 1, magic
, agcnts
,
1502 &xfs_allocbt_buf_ops
);
1504 do_warn(_("bad agbno %u for btbcnt root, agno %d\n"),
1508 if (be32_to_cpu(agf
->agf_freeblks
) != agcnts
->agffreeblks
) {
1509 do_warn(_("agf_freeblks %u, counted %u in ag %u\n"),
1510 be32_to_cpu(agf
->agf_freeblks
), agcnts
->agffreeblks
, agno
);
1513 if (be32_to_cpu(agf
->agf_longest
) != agcnts
->agflongest
) {
1514 do_warn(_("agf_longest %u, counted %u in ag %u\n"),
1515 be32_to_cpu(agf
->agf_longest
), agcnts
->agflongest
, agno
);
1518 if (xfs_sb_version_haslazysbcount(&mp
->m_sb
) &&
1519 be32_to_cpu(agf
->agf_btreeblks
) != agcnts
->agfbtreeblks
) {
1520 do_warn(_("agf_btreeblks %u, counted %" PRIu64
" in ag %u\n"),
1521 be32_to_cpu(agf
->agf_btreeblks
), agcnts
->agfbtreeblks
, agno
);
1527 struct xfs_agi
*agi
,
1528 xfs_agnumber_t agno
,
1529 struct aghdr_cnts
*agcnts
)
1535 bno
= be32_to_cpu(agi
->agi_root
);
1536 if (bno
!= 0 && verify_agbno(mp
, agno
, bno
)) {
1537 magic
= xfs_sb_version_hascrc(&mp
->m_sb
) ? XFS_IBT_CRC_MAGIC
1539 scan_sbtree(bno
, be32_to_cpu(agi
->agi_level
),
1540 agno
, 0, scan_inobt
, 1, magic
, agcnts
,
1541 &xfs_inobt_buf_ops
);
1543 do_warn(_("bad agbno %u for inobt root, agno %d\n"),
1544 be32_to_cpu(agi
->agi_root
), agno
);
1547 if (xfs_sb_version_hasfinobt(&mp
->m_sb
)) {
1548 bno
= be32_to_cpu(agi
->agi_free_root
);
1549 if (bno
!= 0 && verify_agbno(mp
, agno
, bno
)) {
1550 magic
= xfs_sb_version_hascrc(&mp
->m_sb
) ?
1551 XFS_FIBT_CRC_MAGIC
: XFS_FIBT_MAGIC
;
1552 scan_sbtree(bno
, be32_to_cpu(agi
->agi_free_level
),
1553 agno
, 0, scan_inobt
, 1, magic
, agcnts
,
1554 &xfs_inobt_buf_ops
);
1556 do_warn(_("bad agbno %u for finobt root, agno %d\n"),
1557 be32_to_cpu(agi
->agi_free_root
), agno
);
1561 if (be32_to_cpu(agi
->agi_count
) != agcnts
->agicount
) {
1562 do_warn(_("agi_count %u, counted %u in ag %u\n"),
1563 be32_to_cpu(agi
->agi_count
), agcnts
->agicount
, agno
);
1566 if (be32_to_cpu(agi
->agi_freecount
) != agcnts
->agifreecount
) {
1567 do_warn(_("agi_freecount %u, counted %u in ag %u\n"),
1568 be32_to_cpu(agi
->agi_freecount
), agcnts
->agifreecount
, agno
);
1571 if (xfs_sb_version_hasfinobt(&mp
->m_sb
) &&
1572 be32_to_cpu(agi
->agi_freecount
) != agcnts
->fibtfreecount
) {
1573 do_warn(_("agi_freecount %u, counted %u in ag %u finobt\n"),
1574 be32_to_cpu(agi
->agi_freecount
), agcnts
->fibtfreecount
,
1578 for (i
= 0; i
< XFS_AGI_UNLINKED_BUCKETS
; i
++) {
1579 xfs_agino_t agino
= be32_to_cpu(agi
->agi_unlinked
[i
]);
1581 if (agino
!= NULLAGINO
) {
1583 _("agi unlinked bucket %d is %u in ag %u (inode=%" PRIu64
")\n"),
1585 XFS_AGINO_TO_INO(mp
, agno
, agino
));
1591 * Scan an AG for obvious corruption.
1596 xfs_agnumber_t agno
,
1599 struct aghdr_cnts
*agcnts
= arg
;
1600 struct xfs_agf
*agf
;
1601 struct xfs_buf
*agfbuf
= NULL
;
1603 struct xfs_agi
*agi
;
1604 struct xfs_buf
*agibuf
= NULL
;
1606 struct xfs_sb
*sb
= NULL
;
1607 struct xfs_buf
*sbbuf
= NULL
;
1610 char *objname
= NULL
;
1612 sb
= (struct xfs_sb
*)calloc(BBTOB(XFS_FSS_TO_BB(mp
, 1)), 1);
1614 do_error(_("can't allocate memory for superblock\n"));
1618 sbbuf
= libxfs_readbuf(mp
->m_dev
, XFS_AG_DADDR(mp
, agno
, XFS_SB_DADDR
),
1619 XFS_FSS_TO_BB(mp
, 1), 0, &xfs_sb_buf_ops
);
1621 objname
= _("root superblock");
1624 libxfs_sb_from_disk(sb
, XFS_BUF_TO_SBP(sbbuf
));
1625 libxfs_sb_quota_from_disk(sb
);
1627 agfbuf
= libxfs_readbuf(mp
->m_dev
,
1628 XFS_AG_DADDR(mp
, agno
, XFS_AGF_DADDR(mp
)),
1629 XFS_FSS_TO_BB(mp
, 1), 0, &xfs_agf_buf_ops
);
1631 objname
= _("agf block");
1632 goto out_free_sbbuf
;
1634 agf
= XFS_BUF_TO_AGF(agfbuf
);
1636 agibuf
= libxfs_readbuf(mp
->m_dev
,
1637 XFS_AG_DADDR(mp
, agno
, XFS_AGI_DADDR(mp
)),
1638 XFS_FSS_TO_BB(mp
, 1), 0, &xfs_agi_buf_ops
);
1640 objname
= _("agi block");
1641 goto out_free_agfbuf
;
1643 agi
= XFS_BUF_TO_AGI(agibuf
);
1645 /* fix up bad ag headers */
1647 status
= verify_set_agheader(mp
, sbbuf
, sb
, agf
, agi
, agno
);
1649 if (status
& XR_AG_SB_SEC
) {
1653 * clear bad sector bit because we don't want
1654 * to skip further processing. we just want to
1655 * ensure that we write out the modified sb buffer.
1657 status
&= ~XR_AG_SB_SEC
;
1659 if (status
& XR_AG_SB
) {
1661 do_warn(_("reset bad sb for ag %d\n"), agno
);
1664 do_warn(_("would reset bad sb for ag %d\n"), agno
);
1667 if (status
& XR_AG_AGF
) {
1669 do_warn(_("reset bad agf for ag %d\n"), agno
);
1672 do_warn(_("would reset bad agf for ag %d\n"), agno
);
1675 if (status
& XR_AG_AGI
) {
1677 do_warn(_("reset bad agi for ag %d\n"), agno
);
1680 do_warn(_("would reset bad agi for ag %d\n"), agno
);
1684 if (status
&& no_modify
) {
1685 do_warn(_("bad uncorrected agheader %d, skipping ag...\n"),
1687 goto out_free_agibuf
;
1690 scan_freelist(agf
, agcnts
);
1692 validate_agf(agf
, agno
, agcnts
);
1693 validate_agi(agi
, agno
, agcnts
);
1695 ASSERT(agi_dirty
== 0 || (agi_dirty
&& !no_modify
));
1696 ASSERT(agf_dirty
== 0 || (agf_dirty
&& !no_modify
));
1697 ASSERT(sb_dirty
== 0 || (sb_dirty
&& !no_modify
));
1700 * Only pay attention to CRC/verifier errors if we can correct them.
1701 * Note that we can get uncorrected EFSCORRUPTED errors here because
1702 * the verifier will flag on out of range values that we can't correct
1703 * until phase 5 when we have all the information necessary to rebuild
1704 * the freespace/inode btrees. We can correct bad CRC errors
1705 * immediately, though.
1708 agi_dirty
+= (agibuf
->b_error
== -EFSBADCRC
);
1709 agf_dirty
+= (agfbuf
->b_error
== -EFSBADCRC
);
1710 sb_dirty
+= (sbbuf
->b_error
== -EFSBADCRC
);
1713 if (agi_dirty
&& !no_modify
)
1714 libxfs_writebuf(agibuf
, 0);
1716 libxfs_putbuf(agibuf
);
1718 if (agf_dirty
&& !no_modify
)
1719 libxfs_writebuf(agfbuf
, 0);
1721 libxfs_putbuf(agfbuf
);
1723 if (sb_dirty
&& !no_modify
) {
1725 memcpy(&mp
->m_sb
, sb
, sizeof(xfs_sb_t
));
1726 libxfs_sb_to_disk(XFS_BUF_TO_SBP(sbbuf
), sb
);
1727 libxfs_writebuf(sbbuf
, 0);
1729 libxfs_putbuf(sbbuf
);
1731 PROG_RPT_INC(prog_rpt_done
[agno
], 1);
1733 #ifdef XR_INODE_TRACE
1734 print_inode_list(i
);
1739 libxfs_putbuf(agibuf
);
1741 libxfs_putbuf(agfbuf
);
1743 libxfs_putbuf(sbbuf
);
1748 do_error(_("can't get %s for ag %d\n"), objname
, agno
);
1751 #define SCAN_THREADS 32
1755 struct xfs_mount
*mp
,
1758 struct aghdr_cnts
*agcnts
;
1759 __uint64_t fdblocks
= 0;
1760 __uint64_t icount
= 0;
1761 __uint64_t ifreecount
= 0;
1765 agcnts
= malloc(mp
->m_sb
.sb_agcount
* sizeof(*agcnts
));
1767 do_abort(_("no memory for ag header counts\n"));
1770 memset(agcnts
, 0, mp
->m_sb
.sb_agcount
* sizeof(*agcnts
));
1772 create_work_queue(&wq
, mp
, scan_threads
);
1774 for (i
= 0; i
< mp
->m_sb
.sb_agcount
; i
++)
1775 queue_work(&wq
, scan_ag
, i
, &agcnts
[i
]);
1777 destroy_work_queue(&wq
);
1779 /* tally up the counts */
1780 for (i
= 0; i
< mp
->m_sb
.sb_agcount
; i
++) {
1781 fdblocks
+= agcnts
[i
].fdblocks
;
1782 icount
+= agcnts
[i
].agicount
;
1783 ifreecount
+= agcnts
[i
].ifreecount
;
1789 * Validate that our manual counts match the superblock.
1791 if (mp
->m_sb
.sb_icount
!= icount
) {
1792 do_warn(_("sb_icount %" PRIu64
", counted %" PRIu64
"\n"),
1793 mp
->m_sb
.sb_icount
, icount
);
1796 if (mp
->m_sb
.sb_ifree
!= ifreecount
) {
1797 do_warn(_("sb_ifree %" PRIu64
", counted %" PRIu64
"\n"),
1798 mp
->m_sb
.sb_ifree
, ifreecount
);
1801 if (mp
->m_sb
.sb_fdblocks
!= fdblocks
) {
1802 do_warn(_("sb_fdblocks %" PRIu64
", counted %" PRIu64
"\n"),
1803 mp
->m_sb
.sb_fdblocks
, fdblocks
);