1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2017-2023 Oracle. All Rights Reserved.
4 * Author: Darrick J. Wong <djwong@kernel.org>
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "xfs_trans_resv.h"
11 #include "xfs_mount.h"
12 #include "xfs_btree.h"
14 #include "xfs_alloc.h"
15 #include "xfs_ialloc.h"
18 #include "xfs_inode.h"
19 #include "scrub/scrub.h"
20 #include "scrub/common.h"
26 if (xchk_need_intent_drain(sc
))
27 xchk_fsgates_enable(sc
, XCHK_FSGATES_DRAIN
);
28 return xchk_setup_fs(sc
);
33 /* Cross-reference with the other btrees. */
39 struct xfs_mount
*mp
= sc
->mp
;
40 xfs_agnumber_t agno
= sc
->sm
->sm_agno
;
44 if (sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
47 agbno
= XFS_SB_BLOCK(mp
);
49 error
= xchk_ag_init_existing(sc
, agno
, &sc
->sa
);
50 if (!xchk_xref_process_error(sc
, agno
, agbno
, &error
))
53 xchk_xref_is_used_space(sc
, agbno
, 1);
54 xchk_xref_is_not_inode_chunk(sc
, agbno
, 1);
55 xchk_xref_is_only_owned_by(sc
, agbno
, 1, &XFS_RMAP_OINFO_FS
);
56 xchk_xref_is_not_shared(sc
, agbno
, 1);
57 xchk_xref_is_not_cow_staging(sc
, agbno
, 1);
59 /* scrub teardown will take care of sc->sa for us */
63 * Scrub the filesystem superblock.
65 * Note: We do /not/ attempt to check AG 0's superblock. Mount is
66 * responsible for validating all the geometry information in sb 0, so
67 * if the filesystem is capable of initiating online scrub, then clearly
68 * sb 0 is ok and we can use its information to check everything else.
74 struct xfs_mount
*mp
= sc
->mp
;
77 struct xfs_perag
*pag
;
84 agno
= sc
->sm
->sm_agno
;
89 * Grab an active reference to the perag structure. If we can't get
90 * it, we're racing with something that's tearing down the AG, so
91 * signal that the AG no longer exists.
93 pag
= xfs_perag_get(mp
, agno
);
97 error
= xfs_sb_read_secondary(mp
, sc
->tp
, agno
, &bp
);
99 * The superblock verifier can return several different error codes
100 * if it thinks the superblock doesn't look right. For a mount these
101 * would all get bounced back to userspace, but if we're here then the
102 * fs mounted successfully, which means that this secondary superblock
103 * is simply incorrect. Treat all these codes the same way we treat
107 case -EINVAL
: /* also -EWRONGFS */
110 error
= -EFSCORRUPTED
;
115 if (!xchk_process_error(sc
, agno
, XFS_SB_BLOCK(mp
), &error
))
121 * Verify the geometries match. Fields that are permanently
122 * set by mkfs are checked; fields that can be updated later
123 * (and are not propagated to backup superblocks) are preen
126 if (sb
->sb_blocksize
!= cpu_to_be32(mp
->m_sb
.sb_blocksize
))
127 xchk_block_set_corrupt(sc
, bp
);
129 if (sb
->sb_dblocks
!= cpu_to_be64(mp
->m_sb
.sb_dblocks
))
130 xchk_block_set_corrupt(sc
, bp
);
132 if (sb
->sb_rblocks
!= cpu_to_be64(mp
->m_sb
.sb_rblocks
))
133 xchk_block_set_corrupt(sc
, bp
);
135 if (sb
->sb_rextents
!= cpu_to_be64(mp
->m_sb
.sb_rextents
))
136 xchk_block_set_corrupt(sc
, bp
);
138 if (!uuid_equal(&sb
->sb_uuid
, &mp
->m_sb
.sb_uuid
))
139 xchk_block_set_preen(sc
, bp
);
141 if (sb
->sb_logstart
!= cpu_to_be64(mp
->m_sb
.sb_logstart
))
142 xchk_block_set_corrupt(sc
, bp
);
144 if (sb
->sb_rootino
!= cpu_to_be64(mp
->m_sb
.sb_rootino
))
145 xchk_block_set_preen(sc
, bp
);
147 if (xfs_has_metadir(sc
->mp
)) {
148 if (sb
->sb_metadirino
!= cpu_to_be64(mp
->m_sb
.sb_metadirino
))
149 xchk_block_set_preen(sc
, bp
);
151 if (sb
->sb_rbmino
!= cpu_to_be64(mp
->m_sb
.sb_rbmino
))
152 xchk_block_set_preen(sc
, bp
);
154 if (sb
->sb_rsumino
!= cpu_to_be64(mp
->m_sb
.sb_rsumino
))
155 xchk_block_set_preen(sc
, bp
);
158 if (sb
->sb_rextsize
!= cpu_to_be32(mp
->m_sb
.sb_rextsize
))
159 xchk_block_set_corrupt(sc
, bp
);
161 if (sb
->sb_agblocks
!= cpu_to_be32(mp
->m_sb
.sb_agblocks
))
162 xchk_block_set_corrupt(sc
, bp
);
164 if (sb
->sb_agcount
!= cpu_to_be32(mp
->m_sb
.sb_agcount
))
165 xchk_block_set_corrupt(sc
, bp
);
167 if (sb
->sb_rbmblocks
!= cpu_to_be32(mp
->m_sb
.sb_rbmblocks
))
168 xchk_block_set_corrupt(sc
, bp
);
170 if (sb
->sb_logblocks
!= cpu_to_be32(mp
->m_sb
.sb_logblocks
))
171 xchk_block_set_corrupt(sc
, bp
);
173 /* Check sb_versionnum bits that are set at mkfs time. */
174 vernum_mask
= cpu_to_be16(XFS_SB_VERSION_NUMBITS
|
175 XFS_SB_VERSION_ALIGNBIT
|
176 XFS_SB_VERSION_DALIGNBIT
|
177 XFS_SB_VERSION_SHAREDBIT
|
178 XFS_SB_VERSION_LOGV2BIT
|
179 XFS_SB_VERSION_SECTORBIT
|
180 XFS_SB_VERSION_EXTFLGBIT
|
181 XFS_SB_VERSION_DIRV2BIT
);
182 if ((sb
->sb_versionnum
& vernum_mask
) !=
183 (cpu_to_be16(mp
->m_sb
.sb_versionnum
) & vernum_mask
))
184 xchk_block_set_corrupt(sc
, bp
);
186 /* Check sb_versionnum bits that can be set after mkfs time. */
187 vernum_mask
= cpu_to_be16(XFS_SB_VERSION_ATTRBIT
|
188 XFS_SB_VERSION_NLINKBIT
|
189 XFS_SB_VERSION_QUOTABIT
);
190 if ((sb
->sb_versionnum
& vernum_mask
) !=
191 (cpu_to_be16(mp
->m_sb
.sb_versionnum
) & vernum_mask
))
192 xchk_block_set_preen(sc
, bp
);
194 if (sb
->sb_sectsize
!= cpu_to_be16(mp
->m_sb
.sb_sectsize
))
195 xchk_block_set_corrupt(sc
, bp
);
197 if (sb
->sb_inodesize
!= cpu_to_be16(mp
->m_sb
.sb_inodesize
))
198 xchk_block_set_corrupt(sc
, bp
);
200 if (sb
->sb_inopblock
!= cpu_to_be16(mp
->m_sb
.sb_inopblock
))
201 xchk_block_set_corrupt(sc
, bp
);
203 if (memcmp(sb
->sb_fname
, mp
->m_sb
.sb_fname
, sizeof(sb
->sb_fname
)))
204 xchk_block_set_preen(sc
, bp
);
206 if (sb
->sb_blocklog
!= mp
->m_sb
.sb_blocklog
)
207 xchk_block_set_corrupt(sc
, bp
);
209 if (sb
->sb_sectlog
!= mp
->m_sb
.sb_sectlog
)
210 xchk_block_set_corrupt(sc
, bp
);
212 if (sb
->sb_inodelog
!= mp
->m_sb
.sb_inodelog
)
213 xchk_block_set_corrupt(sc
, bp
);
215 if (sb
->sb_inopblog
!= mp
->m_sb
.sb_inopblog
)
216 xchk_block_set_corrupt(sc
, bp
);
218 if (sb
->sb_agblklog
!= mp
->m_sb
.sb_agblklog
)
219 xchk_block_set_corrupt(sc
, bp
);
221 if (sb
->sb_rextslog
!= mp
->m_sb
.sb_rextslog
)
222 xchk_block_set_corrupt(sc
, bp
);
224 if (sb
->sb_imax_pct
!= mp
->m_sb
.sb_imax_pct
)
225 xchk_block_set_preen(sc
, bp
);
228 * Skip the summary counters since we track them in memory anyway.
229 * sb_icount, sb_ifree, sb_fdblocks, sb_frexents
232 if (!xfs_has_metadir(mp
)) {
233 if (sb
->sb_uquotino
!= cpu_to_be64(mp
->m_sb
.sb_uquotino
))
234 xchk_block_set_preen(sc
, bp
);
236 if (sb
->sb_gquotino
!= cpu_to_be64(mp
->m_sb
.sb_gquotino
))
237 xchk_block_set_preen(sc
, bp
);
241 * Skip the quota flags since repair will force quotacheck.
245 if (sb
->sb_flags
!= mp
->m_sb
.sb_flags
)
246 xchk_block_set_corrupt(sc
, bp
);
248 if (sb
->sb_shared_vn
!= mp
->m_sb
.sb_shared_vn
)
249 xchk_block_set_corrupt(sc
, bp
);
251 if (sb
->sb_inoalignmt
!= cpu_to_be32(mp
->m_sb
.sb_inoalignmt
))
252 xchk_block_set_corrupt(sc
, bp
);
254 if (sb
->sb_unit
!= cpu_to_be32(mp
->m_sb
.sb_unit
))
255 xchk_block_set_preen(sc
, bp
);
257 if (sb
->sb_width
!= cpu_to_be32(mp
->m_sb
.sb_width
))
258 xchk_block_set_preen(sc
, bp
);
260 if (sb
->sb_dirblklog
!= mp
->m_sb
.sb_dirblklog
)
261 xchk_block_set_corrupt(sc
, bp
);
263 if (sb
->sb_logsectlog
!= mp
->m_sb
.sb_logsectlog
)
264 xchk_block_set_corrupt(sc
, bp
);
266 if (sb
->sb_logsectsize
!= cpu_to_be16(mp
->m_sb
.sb_logsectsize
))
267 xchk_block_set_corrupt(sc
, bp
);
269 if (sb
->sb_logsunit
!= cpu_to_be32(mp
->m_sb
.sb_logsunit
))
270 xchk_block_set_corrupt(sc
, bp
);
272 /* Do we see any invalid bits in sb_features2? */
273 if (!xfs_sb_version_hasmorebits(&mp
->m_sb
)) {
274 if (sb
->sb_features2
!= 0)
275 xchk_block_set_corrupt(sc
, bp
);
277 v2_ok
= XFS_SB_VERSION2_OKBITS
;
278 if (xfs_sb_is_v5(&mp
->m_sb
))
279 v2_ok
|= XFS_SB_VERSION2_CRCBIT
;
281 if (!!(sb
->sb_features2
& cpu_to_be32(~v2_ok
)))
282 xchk_block_set_corrupt(sc
, bp
);
284 if (xfs_has_metadir(mp
)) {
285 if (sb
->sb_rgblklog
!= mp
->m_sb
.sb_rgblklog
)
286 xchk_block_set_corrupt(sc
, bp
);
287 if (memchr_inv(sb
->sb_pad
, 0, sizeof(sb
->sb_pad
)))
288 xchk_block_set_preen(sc
, bp
);
290 if (sb
->sb_features2
!= sb
->sb_bad_features2
)
291 xchk_block_set_preen(sc
, bp
);
295 /* Check sb_features2 flags that are set at mkfs time. */
296 features_mask
= cpu_to_be32(XFS_SB_VERSION2_LAZYSBCOUNTBIT
|
297 XFS_SB_VERSION2_PROJID32BIT
|
298 XFS_SB_VERSION2_CRCBIT
|
299 XFS_SB_VERSION2_FTYPE
);
300 if ((sb
->sb_features2
& features_mask
) !=
301 (cpu_to_be32(mp
->m_sb
.sb_features2
) & features_mask
))
302 xchk_block_set_corrupt(sc
, bp
);
304 /* Check sb_features2 flags that can be set after mkfs time. */
305 features_mask
= cpu_to_be32(XFS_SB_VERSION2_ATTR2BIT
);
306 if ((sb
->sb_features2
& features_mask
) !=
307 (cpu_to_be32(mp
->m_sb
.sb_features2
) & features_mask
))
308 xchk_block_set_preen(sc
, bp
);
310 if (!xfs_has_crc(mp
)) {
311 /* all v5 fields must be zero */
312 if (memchr_inv(&sb
->sb_features_compat
, 0,
313 sizeof(struct xfs_dsb
) -
314 offsetof(struct xfs_dsb
, sb_features_compat
)))
315 xchk_block_set_corrupt(sc
, bp
);
317 /* compat features must match */
318 if (sb
->sb_features_compat
!=
319 cpu_to_be32(mp
->m_sb
.sb_features_compat
))
320 xchk_block_set_corrupt(sc
, bp
);
322 /* ro compat features must match */
323 if (sb
->sb_features_ro_compat
!=
324 cpu_to_be32(mp
->m_sb
.sb_features_ro_compat
))
325 xchk_block_set_corrupt(sc
, bp
);
328 * NEEDSREPAIR is ignored on a secondary super, so we should
329 * clear it when we find it, though it's not a corruption.
331 features_mask
= cpu_to_be32(XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR
);
332 if ((cpu_to_be32(mp
->m_sb
.sb_features_incompat
) ^
333 sb
->sb_features_incompat
) & features_mask
)
334 xchk_block_set_preen(sc
, bp
);
336 /* all other incompat features must match */
337 if ((cpu_to_be32(mp
->m_sb
.sb_features_incompat
) ^
338 sb
->sb_features_incompat
) & ~features_mask
)
339 xchk_block_set_corrupt(sc
, bp
);
342 * log incompat features protect newer log record types from
343 * older log recovery code. Log recovery doesn't check the
344 * secondary supers, so we can clear these if needed.
346 if (sb
->sb_features_log_incompat
)
347 xchk_block_set_preen(sc
, bp
);
349 /* Don't care about sb_crc */
351 if (sb
->sb_spino_align
!= cpu_to_be32(mp
->m_sb
.sb_spino_align
))
352 xchk_block_set_corrupt(sc
, bp
);
354 if (!xfs_has_metadir(mp
)) {
355 if (sb
->sb_pquotino
!= cpu_to_be64(mp
->m_sb
.sb_pquotino
))
356 xchk_block_set_preen(sc
, bp
);
359 /* Don't care about sb_lsn */
362 if (xfs_has_metauuid(mp
)) {
363 /* The metadata UUID must be the same for all supers */
364 if (!uuid_equal(&sb
->sb_meta_uuid
, &mp
->m_sb
.sb_meta_uuid
))
365 xchk_block_set_corrupt(sc
, bp
);
368 if (xfs_has_metadir(mp
)) {
369 if (sb
->sb_rgcount
!= cpu_to_be32(mp
->m_sb
.sb_rgcount
))
370 xchk_block_set_corrupt(sc
, bp
);
372 if (sb
->sb_rgextents
!= cpu_to_be32(mp
->m_sb
.sb_rgextents
))
373 xchk_block_set_corrupt(sc
, bp
);
376 /* Everything else must be zero. */
377 if (memchr_inv(sb
+ 1, 0,
378 BBTOB(bp
->b_length
) - sizeof(struct xfs_dsb
)))
379 xchk_block_set_corrupt(sc
, bp
);
381 xchk_superblock_xref(sc
, bp
);
389 /* Tally freespace record lengths. */
391 xchk_agf_record_bno_lengths(
392 struct xfs_btree_cur
*cur
,
393 const struct xfs_alloc_rec_incore
*rec
,
396 xfs_extlen_t
*blocks
= priv
;
398 (*blocks
) += rec
->ar_blockcount
;
402 /* Check agf_freeblks */
404 xchk_agf_xref_freeblks(
405 struct xfs_scrub
*sc
)
407 struct xfs_agf
*agf
= sc
->sa
.agf_bp
->b_addr
;
408 xfs_extlen_t blocks
= 0;
414 error
= xfs_alloc_query_all(sc
->sa
.bno_cur
,
415 xchk_agf_record_bno_lengths
, &blocks
);
416 if (!xchk_should_check_xref(sc
, &error
, &sc
->sa
.bno_cur
))
418 if (blocks
!= be32_to_cpu(agf
->agf_freeblks
))
419 xchk_block_xref_set_corrupt(sc
, sc
->sa
.agf_bp
);
422 /* Cross reference the AGF with the cntbt (freespace by length btree) */
425 struct xfs_scrub
*sc
)
427 struct xfs_agf
*agf
= sc
->sa
.agf_bp
->b_addr
;
436 /* Any freespace at all? */
437 error
= xfs_alloc_lookup_le(sc
->sa
.cnt_cur
, 0, -1U, &have
);
438 if (!xchk_should_check_xref(sc
, &error
, &sc
->sa
.cnt_cur
))
441 if (agf
->agf_freeblks
!= cpu_to_be32(0))
442 xchk_block_xref_set_corrupt(sc
, sc
->sa
.agf_bp
);
446 /* Check agf_longest */
447 error
= xfs_alloc_get_rec(sc
->sa
.cnt_cur
, &agbno
, &blocks
, &have
);
448 if (!xchk_should_check_xref(sc
, &error
, &sc
->sa
.cnt_cur
))
450 if (!have
|| blocks
!= be32_to_cpu(agf
->agf_longest
))
451 xchk_block_xref_set_corrupt(sc
, sc
->sa
.agf_bp
);
454 /* Check the btree block counts in the AGF against the btrees. */
456 xchk_agf_xref_btreeblks(
457 struct xfs_scrub
*sc
)
459 struct xfs_agf
*agf
= sc
->sa
.agf_bp
->b_addr
;
460 struct xfs_mount
*mp
= sc
->mp
;
461 xfs_agblock_t blocks
;
462 xfs_agblock_t btreeblks
;
465 /* agf_btreeblks didn't exist before lazysbcount */
466 if (!xfs_has_lazysbcount(sc
->mp
))
469 /* Check agf_rmap_blocks; set up for agf_btreeblks check */
470 if (sc
->sa
.rmap_cur
) {
471 error
= xfs_btree_count_blocks(sc
->sa
.rmap_cur
, &blocks
);
472 if (!xchk_should_check_xref(sc
, &error
, &sc
->sa
.rmap_cur
))
474 btreeblks
= blocks
- 1;
475 if (blocks
!= be32_to_cpu(agf
->agf_rmap_blocks
))
476 xchk_block_xref_set_corrupt(sc
, sc
->sa
.agf_bp
);
482 * No rmap cursor; we can't xref if we have the rmapbt feature.
483 * We also can't do it if we're missing the free space btree cursors.
485 if ((xfs_has_rmapbt(mp
) && !sc
->sa
.rmap_cur
) ||
486 !sc
->sa
.bno_cur
|| !sc
->sa
.cnt_cur
)
489 /* Check agf_btreeblks */
490 error
= xfs_btree_count_blocks(sc
->sa
.bno_cur
, &blocks
);
491 if (!xchk_should_check_xref(sc
, &error
, &sc
->sa
.bno_cur
))
493 btreeblks
+= blocks
- 1;
495 error
= xfs_btree_count_blocks(sc
->sa
.cnt_cur
, &blocks
);
496 if (!xchk_should_check_xref(sc
, &error
, &sc
->sa
.cnt_cur
))
498 btreeblks
+= blocks
- 1;
500 if (btreeblks
!= be32_to_cpu(agf
->agf_btreeblks
))
501 xchk_block_xref_set_corrupt(sc
, sc
->sa
.agf_bp
);
504 /* Check agf_refcount_blocks against tree size */
506 xchk_agf_xref_refcblks(
507 struct xfs_scrub
*sc
)
509 struct xfs_agf
*agf
= sc
->sa
.agf_bp
->b_addr
;
510 xfs_agblock_t blocks
;
513 if (!sc
->sa
.refc_cur
)
516 error
= xfs_btree_count_blocks(sc
->sa
.refc_cur
, &blocks
);
517 if (!xchk_should_check_xref(sc
, &error
, &sc
->sa
.refc_cur
))
519 if (blocks
!= be32_to_cpu(agf
->agf_refcount_blocks
))
520 xchk_block_xref_set_corrupt(sc
, sc
->sa
.agf_bp
);
523 /* Cross-reference with the other btrees. */
526 struct xfs_scrub
*sc
)
528 struct xfs_mount
*mp
= sc
->mp
;
531 if (sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
534 agbno
= XFS_AGF_BLOCK(mp
);
536 xchk_ag_btcur_init(sc
, &sc
->sa
);
538 xchk_xref_is_used_space(sc
, agbno
, 1);
539 xchk_agf_xref_freeblks(sc
);
540 xchk_agf_xref_cntbt(sc
);
541 xchk_xref_is_not_inode_chunk(sc
, agbno
, 1);
542 xchk_xref_is_only_owned_by(sc
, agbno
, 1, &XFS_RMAP_OINFO_FS
);
543 xchk_agf_xref_btreeblks(sc
);
544 xchk_xref_is_not_shared(sc
, agbno
, 1);
545 xchk_xref_is_not_cow_staging(sc
, agbno
, 1);
546 xchk_agf_xref_refcblks(sc
);
548 /* scrub teardown will take care of sc->sa for us */
554 struct xfs_scrub
*sc
)
556 struct xfs_mount
*mp
= sc
->mp
;
558 struct xfs_perag
*pag
;
559 xfs_agnumber_t agno
= sc
->sm
->sm_agno
;
562 xfs_agblock_t agfl_first
;
563 xfs_agblock_t agfl_last
;
564 xfs_agblock_t agfl_count
;
565 xfs_agblock_t fl_count
;
569 error
= xchk_ag_read_headers(sc
, agno
, &sc
->sa
);
570 if (!xchk_process_error(sc
, agno
, XFS_AGF_BLOCK(sc
->mp
), &error
))
572 xchk_buffer_recheck(sc
, sc
->sa
.agf_bp
);
574 agf
= sc
->sa
.agf_bp
->b_addr
;
577 /* Check the AG length */
578 eoag
= be32_to_cpu(agf
->agf_length
);
579 if (eoag
!= pag_group(pag
)->xg_block_count
)
580 xchk_block_set_corrupt(sc
, sc
->sa
.agf_bp
);
582 /* Check the AGF btree roots and levels */
583 agbno
= be32_to_cpu(agf
->agf_bno_root
);
584 if (!xfs_verify_agbno(pag
, agbno
))
585 xchk_block_set_corrupt(sc
, sc
->sa
.agf_bp
);
587 agbno
= be32_to_cpu(agf
->agf_cnt_root
);
588 if (!xfs_verify_agbno(pag
, agbno
))
589 xchk_block_set_corrupt(sc
, sc
->sa
.agf_bp
);
591 level
= be32_to_cpu(agf
->agf_bno_level
);
592 if (level
<= 0 || level
> mp
->m_alloc_maxlevels
)
593 xchk_block_set_corrupt(sc
, sc
->sa
.agf_bp
);
595 level
= be32_to_cpu(agf
->agf_cnt_level
);
596 if (level
<= 0 || level
> mp
->m_alloc_maxlevels
)
597 xchk_block_set_corrupt(sc
, sc
->sa
.agf_bp
);
599 if (xfs_has_rmapbt(mp
)) {
600 agbno
= be32_to_cpu(agf
->agf_rmap_root
);
601 if (!xfs_verify_agbno(pag
, agbno
))
602 xchk_block_set_corrupt(sc
, sc
->sa
.agf_bp
);
604 level
= be32_to_cpu(agf
->agf_rmap_level
);
605 if (level
<= 0 || level
> mp
->m_rmap_maxlevels
)
606 xchk_block_set_corrupt(sc
, sc
->sa
.agf_bp
);
609 if (xfs_has_reflink(mp
)) {
610 agbno
= be32_to_cpu(agf
->agf_refcount_root
);
611 if (!xfs_verify_agbno(pag
, agbno
))
612 xchk_block_set_corrupt(sc
, sc
->sa
.agf_bp
);
614 level
= be32_to_cpu(agf
->agf_refcount_level
);
615 if (level
<= 0 || level
> mp
->m_refc_maxlevels
)
616 xchk_block_set_corrupt(sc
, sc
->sa
.agf_bp
);
619 /* Check the AGFL counters */
620 agfl_first
= be32_to_cpu(agf
->agf_flfirst
);
621 agfl_last
= be32_to_cpu(agf
->agf_fllast
);
622 agfl_count
= be32_to_cpu(agf
->agf_flcount
);
623 if (agfl_last
> agfl_first
)
624 fl_count
= agfl_last
- agfl_first
+ 1;
626 fl_count
= xfs_agfl_size(mp
) - agfl_first
+ agfl_last
+ 1;
627 if (agfl_count
!= 0 && fl_count
!= agfl_count
)
628 xchk_block_set_corrupt(sc
, sc
->sa
.agf_bp
);
630 /* Do the incore counters match? */
631 if (pag
->pagf_freeblks
!= be32_to_cpu(agf
->agf_freeblks
))
632 xchk_block_set_corrupt(sc
, sc
->sa
.agf_bp
);
633 if (pag
->pagf_flcount
!= be32_to_cpu(agf
->agf_flcount
))
634 xchk_block_set_corrupt(sc
, sc
->sa
.agf_bp
);
635 if (xfs_has_lazysbcount(sc
->mp
) &&
636 pag
->pagf_btreeblks
!= be32_to_cpu(agf
->agf_btreeblks
))
637 xchk_block_set_corrupt(sc
, sc
->sa
.agf_bp
);
646 struct xchk_agfl_info
{
647 /* Number of AGFL entries that the AGF claims are in use. */
648 unsigned int agflcount
;
650 /* Number of AGFL entries that we found. */
651 unsigned int nr_entries
;
653 /* Buffer to hold AGFL entries for extent checking. */
654 xfs_agblock_t
*entries
;
656 struct xfs_buf
*agfl_bp
;
657 struct xfs_scrub
*sc
;
660 /* Cross-reference with the other btrees. */
662 xchk_agfl_block_xref(
663 struct xfs_scrub
*sc
,
666 if (sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
669 xchk_xref_is_used_space(sc
, agbno
, 1);
670 xchk_xref_is_not_inode_chunk(sc
, agbno
, 1);
671 xchk_xref_is_only_owned_by(sc
, agbno
, 1, &XFS_RMAP_OINFO_AG
);
672 xchk_xref_is_not_shared(sc
, agbno
, 1);
673 xchk_xref_is_not_cow_staging(sc
, agbno
, 1);
676 /* Scrub an AGFL block. */
679 struct xfs_mount
*mp
,
683 struct xchk_agfl_info
*sai
= priv
;
684 struct xfs_scrub
*sc
= sai
->sc
;
686 if (xfs_verify_agbno(sc
->sa
.pag
, agbno
) &&
687 sai
->nr_entries
< sai
->agflcount
)
688 sai
->entries
[sai
->nr_entries
++] = agbno
;
690 xchk_block_set_corrupt(sc
, sai
->agfl_bp
);
692 xchk_agfl_block_xref(sc
, agbno
);
694 if (sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
705 const xfs_agblock_t
*a
= pa
;
706 const xfs_agblock_t
*b
= pb
;
708 return (int)*a
- (int)*b
;
711 /* Cross-reference with the other btrees. */
714 struct xfs_scrub
*sc
)
716 struct xfs_mount
*mp
= sc
->mp
;
719 if (sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
722 agbno
= XFS_AGFL_BLOCK(mp
);
724 xchk_ag_btcur_init(sc
, &sc
->sa
);
726 xchk_xref_is_used_space(sc
, agbno
, 1);
727 xchk_xref_is_not_inode_chunk(sc
, agbno
, 1);
728 xchk_xref_is_only_owned_by(sc
, agbno
, 1, &XFS_RMAP_OINFO_FS
);
729 xchk_xref_is_not_shared(sc
, agbno
, 1);
730 xchk_xref_is_not_cow_staging(sc
, agbno
, 1);
733 * Scrub teardown will take care of sc->sa for us. Leave sc->sa
734 * active so that the agfl block xref can use it too.
738 /* Scrub the AGFL. */
741 struct xfs_scrub
*sc
)
743 struct xchk_agfl_info sai
= {
747 xfs_agnumber_t agno
= sc
->sm
->sm_agno
;
751 /* Lock the AGF and AGI so that nobody can touch this AG. */
752 error
= xchk_ag_read_headers(sc
, agno
, &sc
->sa
);
753 if (!xchk_process_error(sc
, agno
, XFS_AGFL_BLOCK(sc
->mp
), &error
))
756 return -EFSCORRUPTED
;
758 /* Try to read the AGFL, and verify its structure if we get it. */
759 error
= xfs_alloc_read_agfl(sc
->sa
.pag
, sc
->tp
, &sai
.agfl_bp
);
760 if (!xchk_process_error(sc
, agno
, XFS_AGFL_BLOCK(sc
->mp
), &error
))
762 xchk_buffer_recheck(sc
, sai
.agfl_bp
);
766 if (sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
769 /* Allocate buffer to ensure uniqueness of AGFL entries. */
770 agf
= sc
->sa
.agf_bp
->b_addr
;
771 sai
.agflcount
= be32_to_cpu(agf
->agf_flcount
);
772 if (sai
.agflcount
> xfs_agfl_size(sc
->mp
)) {
773 xchk_block_set_corrupt(sc
, sc
->sa
.agf_bp
);
776 sai
.entries
= kvcalloc(sai
.agflcount
, sizeof(xfs_agblock_t
),
783 /* Check the blocks in the AGFL. */
784 error
= xfs_agfl_walk(sc
->mp
, sc
->sa
.agf_bp
->b_addr
, sai
.agfl_bp
,
785 xchk_agfl_block
, &sai
);
786 if (error
== -ECANCELED
) {
793 if (sai
.agflcount
!= sai
.nr_entries
) {
794 xchk_block_set_corrupt(sc
, sc
->sa
.agf_bp
);
798 /* Sort entries, check for duplicates. */
799 sort(sai
.entries
, sai
.nr_entries
, sizeof(sai
.entries
[0]),
800 xchk_agblock_cmp
, NULL
);
801 for (i
= 1; i
< sai
.nr_entries
; i
++) {
802 if (sai
.entries
[i
] == sai
.entries
[i
- 1]) {
803 xchk_block_set_corrupt(sc
, sc
->sa
.agf_bp
);
816 /* Check agi_count/agi_freecount */
818 xchk_agi_xref_icounts(
819 struct xfs_scrub
*sc
)
821 struct xfs_agi
*agi
= sc
->sa
.agi_bp
->b_addr
;
823 xfs_agino_t freecount
;
829 error
= xfs_ialloc_count_inodes(sc
->sa
.ino_cur
, &icount
, &freecount
);
830 if (!xchk_should_check_xref(sc
, &error
, &sc
->sa
.ino_cur
))
832 if (be32_to_cpu(agi
->agi_count
) != icount
||
833 be32_to_cpu(agi
->agi_freecount
) != freecount
)
834 xchk_block_xref_set_corrupt(sc
, sc
->sa
.agi_bp
);
837 /* Check agi_[fi]blocks against tree size */
839 xchk_agi_xref_fiblocks(
840 struct xfs_scrub
*sc
)
842 struct xfs_agi
*agi
= sc
->sa
.agi_bp
->b_addr
;
843 xfs_agblock_t blocks
;
846 if (!xfs_has_inobtcounts(sc
->mp
))
849 if (sc
->sa
.ino_cur
) {
850 error
= xfs_btree_count_blocks(sc
->sa
.ino_cur
, &blocks
);
851 if (!xchk_should_check_xref(sc
, &error
, &sc
->sa
.ino_cur
))
853 if (blocks
!= be32_to_cpu(agi
->agi_iblocks
))
854 xchk_block_xref_set_corrupt(sc
, sc
->sa
.agi_bp
);
857 if (sc
->sa
.fino_cur
) {
858 error
= xfs_btree_count_blocks(sc
->sa
.fino_cur
, &blocks
);
859 if (!xchk_should_check_xref(sc
, &error
, &sc
->sa
.fino_cur
))
861 if (blocks
!= be32_to_cpu(agi
->agi_fblocks
))
862 xchk_block_xref_set_corrupt(sc
, sc
->sa
.agi_bp
);
866 /* Cross-reference with the other btrees. */
869 struct xfs_scrub
*sc
)
871 struct xfs_mount
*mp
= sc
->mp
;
874 if (sc
->sm
->sm_flags
& XFS_SCRUB_OFLAG_CORRUPT
)
877 agbno
= XFS_AGI_BLOCK(mp
);
879 xchk_ag_btcur_init(sc
, &sc
->sa
);
881 xchk_xref_is_used_space(sc
, agbno
, 1);
882 xchk_xref_is_not_inode_chunk(sc
, agbno
, 1);
883 xchk_agi_xref_icounts(sc
);
884 xchk_xref_is_only_owned_by(sc
, agbno
, 1, &XFS_RMAP_OINFO_FS
);
885 xchk_xref_is_not_shared(sc
, agbno
, 1);
886 xchk_xref_is_not_cow_staging(sc
, agbno
, 1);
887 xchk_agi_xref_fiblocks(sc
);
889 /* scrub teardown will take care of sc->sa for us */
893 * Check the unlinked buckets for links to bad inodes. We hold the AGI, so
894 * there cannot be any threads updating unlinked list pointers in this AG.
898 struct xfs_scrub
*sc
,
902 struct xfs_inode
*ip
;
904 for (i
= 0; i
< XFS_AGI_UNLINKED_BUCKETS
; i
++) {
905 xfs_agino_t agino
= be32_to_cpu(agi
->agi_unlinked
[i
]);
907 while (agino
!= NULLAGINO
) {
908 if (agino
% XFS_AGI_UNLINKED_BUCKETS
!= i
) {
909 xchk_block_set_corrupt(sc
, sc
->sa
.agi_bp
);
913 ip
= xfs_iunlink_lookup(sc
->sa
.pag
, agino
);
915 xchk_block_set_corrupt(sc
, sc
->sa
.agi_bp
);
919 if (!xfs_inode_on_unlinked_list(ip
)) {
920 xchk_block_set_corrupt(sc
, sc
->sa
.agi_bp
);
924 agino
= ip
->i_next_unlinked
;
932 struct xfs_scrub
*sc
)
934 struct xfs_mount
*mp
= sc
->mp
;
936 struct xfs_perag
*pag
;
937 struct xfs_ino_geometry
*igeo
= M_IGEO(sc
->mp
);
938 xfs_agnumber_t agno
= sc
->sm
->sm_agno
;
942 xfs_agino_t first_agino
;
943 xfs_agino_t last_agino
;
949 error
= xchk_ag_read_headers(sc
, agno
, &sc
->sa
);
950 if (!xchk_process_error(sc
, agno
, XFS_AGI_BLOCK(sc
->mp
), &error
))
952 xchk_buffer_recheck(sc
, sc
->sa
.agi_bp
);
954 agi
= sc
->sa
.agi_bp
->b_addr
;
957 /* Check the AG length */
958 eoag
= be32_to_cpu(agi
->agi_length
);
959 if (eoag
!= pag_group(pag
)->xg_block_count
)
960 xchk_block_set_corrupt(sc
, sc
->sa
.agi_bp
);
962 /* Check btree roots and levels */
963 agbno
= be32_to_cpu(agi
->agi_root
);
964 if (!xfs_verify_agbno(pag
, agbno
))
965 xchk_block_set_corrupt(sc
, sc
->sa
.agi_bp
);
967 level
= be32_to_cpu(agi
->agi_level
);
968 if (level
<= 0 || level
> igeo
->inobt_maxlevels
)
969 xchk_block_set_corrupt(sc
, sc
->sa
.agi_bp
);
971 if (xfs_has_finobt(mp
)) {
972 agbno
= be32_to_cpu(agi
->agi_free_root
);
973 if (!xfs_verify_agbno(pag
, agbno
))
974 xchk_block_set_corrupt(sc
, sc
->sa
.agi_bp
);
976 level
= be32_to_cpu(agi
->agi_free_level
);
977 if (level
<= 0 || level
> igeo
->inobt_maxlevels
)
978 xchk_block_set_corrupt(sc
, sc
->sa
.agi_bp
);
981 /* Check inode counters */
982 xfs_agino_range(mp
, agno
, &first_agino
, &last_agino
);
983 icount
= be32_to_cpu(agi
->agi_count
);
984 if (icount
> last_agino
- first_agino
+ 1 ||
985 icount
< be32_to_cpu(agi
->agi_freecount
))
986 xchk_block_set_corrupt(sc
, sc
->sa
.agi_bp
);
988 /* Check inode pointers */
989 agino
= be32_to_cpu(agi
->agi_newino
);
990 if (!xfs_verify_agino_or_null(pag
, agino
))
991 xchk_block_set_corrupt(sc
, sc
->sa
.agi_bp
);
993 agino
= be32_to_cpu(agi
->agi_dirino
);
994 if (!xfs_verify_agino_or_null(pag
, agino
))
995 xchk_block_set_corrupt(sc
, sc
->sa
.agi_bp
);
997 /* Check unlinked inode buckets */
998 for (i
= 0; i
< XFS_AGI_UNLINKED_BUCKETS
; i
++) {
999 agino
= be32_to_cpu(agi
->agi_unlinked
[i
]);
1000 if (!xfs_verify_agino_or_null(pag
, agino
))
1001 xchk_block_set_corrupt(sc
, sc
->sa
.agi_bp
);
1004 if (agi
->agi_pad32
!= cpu_to_be32(0))
1005 xchk_block_set_corrupt(sc
, sc
->sa
.agi_bp
);
1007 /* Do the incore counters match? */
1008 if (pag
->pagi_count
!= be32_to_cpu(agi
->agi_count
))
1009 xchk_block_set_corrupt(sc
, sc
->sa
.agi_bp
);
1010 if (pag
->pagi_freecount
!= be32_to_cpu(agi
->agi_freecount
))
1011 xchk_block_set_corrupt(sc
, sc
->sa
.agi_bp
);
1013 xchk_iunlink(sc
, agi
);