1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2017-2023 Oracle. All Rights Reserved. 4 * Author: Darrick J. Wong <djwong@kernel.org> 5 */ 6 #include "xfs.h" 7 #include "xfs_fs.h" 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" 13 #include "xfs_sb.h" 14 #include "xfs_alloc.h" 15 #include "xfs_ialloc.h" 16 #include "xfs_rmap.h" 17 #include "xfs_ag.h" 18 #include "xfs_inode.h" 19 #include "scrub/scrub.h" 20 #include "scrub/common.h" 21 22 int 23 xchk_setup_agheader( 24 struct xfs_scrub *sc) 25 { 26 if (xchk_need_intent_drain(sc)) 27 xchk_fsgates_enable(sc, XCHK_FSGATES_DRAIN); 28 return xchk_setup_fs(sc); 29 } 30 31 /* Superblock */ 32 33 /* Cross-reference with the other btrees. */ 34 STATIC void 35 xchk_superblock_xref( 36 struct xfs_scrub *sc, 37 struct xfs_buf *bp) 38 { 39 struct xfs_mount *mp = sc->mp; 40 xfs_agnumber_t agno = sc->sm->sm_agno; 41 xfs_agblock_t agbno; 42 int error; 43 44 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 45 return; 46 47 agbno = XFS_SB_BLOCK(mp); 48 49 error = xchk_ag_init_existing(sc, agno, &sc->sa); 50 if (!xchk_xref_process_error(sc, agno, agbno, &error)) 51 return; 52 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); 58 59 /* scrub teardown will take care of sc->sa for us */ 60 } 61 62 /* 63 * Scrub the filesystem superblock. 64 * 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. 69 */ 70 int 71 xchk_superblock( 72 struct xfs_scrub *sc) 73 { 74 struct xfs_mount *mp = sc->mp; 75 struct xfs_buf *bp; 76 struct xfs_dsb *sb; 77 struct xfs_perag *pag; 78 xfs_agnumber_t agno; 79 uint32_t v2_ok; 80 __be32 features_mask; 81 int error; 82 __be16 vernum_mask; 83 84 agno = sc->sm->sm_agno; 85 if (agno == 0) 86 return 0; 87 88 /* 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. 92 */ 93 pag = xfs_perag_get(mp, agno); 94 if (!pag) 95 return -ENOENT; 96 97 error = xfs_sb_read_secondary(mp, sc->tp, agno, &bp); 98 /* 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 104 * any corruption. 105 */ 106 switch (error) { 107 case -EINVAL: /* also -EWRONGFS */ 108 case -ENOSYS: 109 case -EFBIG: 110 error = -EFSCORRUPTED; 111 fallthrough; 112 default: 113 break; 114 } 115 if (!xchk_process_error(sc, agno, XFS_SB_BLOCK(mp), &error)) 116 goto out_pag; 117 118 sb = bp->b_addr; 119 120 /* 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 124 * checked. 125 */ 126 if (sb->sb_blocksize != cpu_to_be32(mp->m_sb.sb_blocksize)) 127 xchk_block_set_corrupt(sc, bp); 128 129 if (sb->sb_dblocks != cpu_to_be64(mp->m_sb.sb_dblocks)) 130 xchk_block_set_corrupt(sc, bp); 131 132 if (sb->sb_rblocks != cpu_to_be64(mp->m_sb.sb_rblocks)) 133 xchk_block_set_corrupt(sc, bp); 134 135 if (sb->sb_rextents != cpu_to_be64(mp->m_sb.sb_rextents)) 136 xchk_block_set_corrupt(sc, bp); 137 138 if (!uuid_equal(&sb->sb_uuid, &mp->m_sb.sb_uuid)) 139 xchk_block_set_preen(sc, bp); 140 141 if (sb->sb_logstart != cpu_to_be64(mp->m_sb.sb_logstart)) 142 xchk_block_set_corrupt(sc, bp); 143 144 if (sb->sb_rootino != cpu_to_be64(mp->m_sb.sb_rootino)) 145 xchk_block_set_preen(sc, bp); 146 147 if (sb->sb_rbmino != cpu_to_be64(mp->m_sb.sb_rbmino)) 148 xchk_block_set_preen(sc, bp); 149 150 if (sb->sb_rsumino != cpu_to_be64(mp->m_sb.sb_rsumino)) 151 xchk_block_set_preen(sc, bp); 152 153 if (sb->sb_rextsize != cpu_to_be32(mp->m_sb.sb_rextsize)) 154 xchk_block_set_corrupt(sc, bp); 155 156 if (sb->sb_agblocks != cpu_to_be32(mp->m_sb.sb_agblocks)) 157 xchk_block_set_corrupt(sc, bp); 158 159 if (sb->sb_agcount != cpu_to_be32(mp->m_sb.sb_agcount)) 160 xchk_block_set_corrupt(sc, bp); 161 162 if (sb->sb_rbmblocks != cpu_to_be32(mp->m_sb.sb_rbmblocks)) 163 xchk_block_set_corrupt(sc, bp); 164 165 if (sb->sb_logblocks != cpu_to_be32(mp->m_sb.sb_logblocks)) 166 xchk_block_set_corrupt(sc, bp); 167 168 /* Check sb_versionnum bits that are set at mkfs time. */ 169 vernum_mask = cpu_to_be16(XFS_SB_VERSION_NUMBITS | 170 XFS_SB_VERSION_ALIGNBIT | 171 XFS_SB_VERSION_DALIGNBIT | 172 XFS_SB_VERSION_SHAREDBIT | 173 XFS_SB_VERSION_LOGV2BIT | 174 XFS_SB_VERSION_SECTORBIT | 175 XFS_SB_VERSION_EXTFLGBIT | 176 XFS_SB_VERSION_DIRV2BIT); 177 if ((sb->sb_versionnum & vernum_mask) != 178 (cpu_to_be16(mp->m_sb.sb_versionnum) & vernum_mask)) 179 xchk_block_set_corrupt(sc, bp); 180 181 /* Check sb_versionnum bits that can be set after mkfs time. */ 182 vernum_mask = cpu_to_be16(XFS_SB_VERSION_ATTRBIT | 183 XFS_SB_VERSION_NLINKBIT | 184 XFS_SB_VERSION_QUOTABIT); 185 if ((sb->sb_versionnum & vernum_mask) != 186 (cpu_to_be16(mp->m_sb.sb_versionnum) & vernum_mask)) 187 xchk_block_set_preen(sc, bp); 188 189 if (sb->sb_sectsize != cpu_to_be16(mp->m_sb.sb_sectsize)) 190 xchk_block_set_corrupt(sc, bp); 191 192 if (sb->sb_inodesize != cpu_to_be16(mp->m_sb.sb_inodesize)) 193 xchk_block_set_corrupt(sc, bp); 194 195 if (sb->sb_inopblock != cpu_to_be16(mp->m_sb.sb_inopblock)) 196 xchk_block_set_corrupt(sc, bp); 197 198 if (memcmp(sb->sb_fname, mp->m_sb.sb_fname, sizeof(sb->sb_fname))) 199 xchk_block_set_preen(sc, bp); 200 201 if (sb->sb_blocklog != mp->m_sb.sb_blocklog) 202 xchk_block_set_corrupt(sc, bp); 203 204 if (sb->sb_sectlog != mp->m_sb.sb_sectlog) 205 xchk_block_set_corrupt(sc, bp); 206 207 if (sb->sb_inodelog != mp->m_sb.sb_inodelog) 208 xchk_block_set_corrupt(sc, bp); 209 210 if (sb->sb_inopblog != mp->m_sb.sb_inopblog) 211 xchk_block_set_corrupt(sc, bp); 212 213 if (sb->sb_agblklog != mp->m_sb.sb_agblklog) 214 xchk_block_set_corrupt(sc, bp); 215 216 if (sb->sb_rextslog != mp->m_sb.sb_rextslog) 217 xchk_block_set_corrupt(sc, bp); 218 219 if (sb->sb_imax_pct != mp->m_sb.sb_imax_pct) 220 xchk_block_set_preen(sc, bp); 221 222 /* 223 * Skip the summary counters since we track them in memory anyway. 224 * sb_icount, sb_ifree, sb_fdblocks, sb_frexents 225 */ 226 227 if (sb->sb_uquotino != cpu_to_be64(mp->m_sb.sb_uquotino)) 228 xchk_block_set_preen(sc, bp); 229 230 if (sb->sb_gquotino != cpu_to_be64(mp->m_sb.sb_gquotino)) 231 xchk_block_set_preen(sc, bp); 232 233 /* 234 * Skip the quota flags since repair will force quotacheck. 235 * sb_qflags 236 */ 237 238 if (sb->sb_flags != mp->m_sb.sb_flags) 239 xchk_block_set_corrupt(sc, bp); 240 241 if (sb->sb_shared_vn != mp->m_sb.sb_shared_vn) 242 xchk_block_set_corrupt(sc, bp); 243 244 if (sb->sb_inoalignmt != cpu_to_be32(mp->m_sb.sb_inoalignmt)) 245 xchk_block_set_corrupt(sc, bp); 246 247 if (sb->sb_unit != cpu_to_be32(mp->m_sb.sb_unit)) 248 xchk_block_set_preen(sc, bp); 249 250 if (sb->sb_width != cpu_to_be32(mp->m_sb.sb_width)) 251 xchk_block_set_preen(sc, bp); 252 253 if (sb->sb_dirblklog != mp->m_sb.sb_dirblklog) 254 xchk_block_set_corrupt(sc, bp); 255 256 if (sb->sb_logsectlog != mp->m_sb.sb_logsectlog) 257 xchk_block_set_corrupt(sc, bp); 258 259 if (sb->sb_logsectsize != cpu_to_be16(mp->m_sb.sb_logsectsize)) 260 xchk_block_set_corrupt(sc, bp); 261 262 if (sb->sb_logsunit != cpu_to_be32(mp->m_sb.sb_logsunit)) 263 xchk_block_set_corrupt(sc, bp); 264 265 /* Do we see any invalid bits in sb_features2? */ 266 if (!xfs_sb_version_hasmorebits(&mp->m_sb)) { 267 if (sb->sb_features2 != 0) 268 xchk_block_set_corrupt(sc, bp); 269 } else { 270 v2_ok = XFS_SB_VERSION2_OKBITS; 271 if (xfs_sb_is_v5(&mp->m_sb)) 272 v2_ok |= XFS_SB_VERSION2_CRCBIT; 273 274 if (!!(sb->sb_features2 & cpu_to_be32(~v2_ok))) 275 xchk_block_set_corrupt(sc, bp); 276 277 if (sb->sb_features2 != sb->sb_bad_features2) 278 xchk_block_set_preen(sc, bp); 279 } 280 281 /* Check sb_features2 flags that are set at mkfs time. */ 282 features_mask = cpu_to_be32(XFS_SB_VERSION2_LAZYSBCOUNTBIT | 283 XFS_SB_VERSION2_PROJID32BIT | 284 XFS_SB_VERSION2_CRCBIT | 285 XFS_SB_VERSION2_FTYPE); 286 if ((sb->sb_features2 & features_mask) != 287 (cpu_to_be32(mp->m_sb.sb_features2) & features_mask)) 288 xchk_block_set_corrupt(sc, bp); 289 290 /* Check sb_features2 flags that can be set after mkfs time. */ 291 features_mask = cpu_to_be32(XFS_SB_VERSION2_ATTR2BIT); 292 if ((sb->sb_features2 & features_mask) != 293 (cpu_to_be32(mp->m_sb.sb_features2) & features_mask)) 294 xchk_block_set_preen(sc, bp); 295 296 if (!xfs_has_crc(mp)) { 297 /* all v5 fields must be zero */ 298 if (memchr_inv(&sb->sb_features_compat, 0, 299 sizeof(struct xfs_dsb) - 300 offsetof(struct xfs_dsb, sb_features_compat))) 301 xchk_block_set_corrupt(sc, bp); 302 } else { 303 /* compat features must match */ 304 if (sb->sb_features_compat != 305 cpu_to_be32(mp->m_sb.sb_features_compat)) 306 xchk_block_set_corrupt(sc, bp); 307 308 /* ro compat features must match */ 309 if (sb->sb_features_ro_compat != 310 cpu_to_be32(mp->m_sb.sb_features_ro_compat)) 311 xchk_block_set_corrupt(sc, bp); 312 313 /* 314 * NEEDSREPAIR is ignored on a secondary super, so we should 315 * clear it when we find it, though it's not a corruption. 316 */ 317 features_mask = cpu_to_be32(XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR); 318 if ((cpu_to_be32(mp->m_sb.sb_features_incompat) ^ 319 sb->sb_features_incompat) & features_mask) 320 xchk_block_set_preen(sc, bp); 321 322 /* all other incompat features must match */ 323 if ((cpu_to_be32(mp->m_sb.sb_features_incompat) ^ 324 sb->sb_features_incompat) & ~features_mask) 325 xchk_block_set_corrupt(sc, bp); 326 327 /* 328 * log incompat features protect newer log record types from 329 * older log recovery code. Log recovery doesn't check the 330 * secondary supers, so we can clear these if needed. 331 */ 332 if (sb->sb_features_log_incompat) 333 xchk_block_set_preen(sc, bp); 334 335 /* Don't care about sb_crc */ 336 337 if (sb->sb_spino_align != cpu_to_be32(mp->m_sb.sb_spino_align)) 338 xchk_block_set_corrupt(sc, bp); 339 340 if (sb->sb_pquotino != cpu_to_be64(mp->m_sb.sb_pquotino)) 341 xchk_block_set_preen(sc, bp); 342 343 /* Don't care about sb_lsn */ 344 } 345 346 if (xfs_has_metauuid(mp)) { 347 /* The metadata UUID must be the same for all supers */ 348 if (!uuid_equal(&sb->sb_meta_uuid, &mp->m_sb.sb_meta_uuid)) 349 xchk_block_set_corrupt(sc, bp); 350 } 351 352 /* Everything else must be zero. */ 353 if (memchr_inv(sb + 1, 0, 354 BBTOB(bp->b_length) - sizeof(struct xfs_dsb))) 355 xchk_block_set_corrupt(sc, bp); 356 357 xchk_superblock_xref(sc, bp); 358 out_pag: 359 xfs_perag_put(pag); 360 return error; 361 } 362 363 /* AGF */ 364 365 /* Tally freespace record lengths. */ 366 STATIC int 367 xchk_agf_record_bno_lengths( 368 struct xfs_btree_cur *cur, 369 const struct xfs_alloc_rec_incore *rec, 370 void *priv) 371 { 372 xfs_extlen_t *blocks = priv; 373 374 (*blocks) += rec->ar_blockcount; 375 return 0; 376 } 377 378 /* Check agf_freeblks */ 379 static inline void 380 xchk_agf_xref_freeblks( 381 struct xfs_scrub *sc) 382 { 383 struct xfs_agf *agf = sc->sa.agf_bp->b_addr; 384 xfs_extlen_t blocks = 0; 385 int error; 386 387 if (!sc->sa.bno_cur) 388 return; 389 390 error = xfs_alloc_query_all(sc->sa.bno_cur, 391 xchk_agf_record_bno_lengths, &blocks); 392 if (!xchk_should_check_xref(sc, &error, &sc->sa.bno_cur)) 393 return; 394 if (blocks != be32_to_cpu(agf->agf_freeblks)) 395 xchk_block_xref_set_corrupt(sc, sc->sa.agf_bp); 396 } 397 398 /* Cross reference the AGF with the cntbt (freespace by length btree) */ 399 static inline void 400 xchk_agf_xref_cntbt( 401 struct xfs_scrub *sc) 402 { 403 struct xfs_agf *agf = sc->sa.agf_bp->b_addr; 404 xfs_agblock_t agbno; 405 xfs_extlen_t blocks; 406 int have; 407 int error; 408 409 if (!sc->sa.cnt_cur) 410 return; 411 412 /* Any freespace at all? */ 413 error = xfs_alloc_lookup_le(sc->sa.cnt_cur, 0, -1U, &have); 414 if (!xchk_should_check_xref(sc, &error, &sc->sa.cnt_cur)) 415 return; 416 if (!have) { 417 if (agf->agf_freeblks != cpu_to_be32(0)) 418 xchk_block_xref_set_corrupt(sc, sc->sa.agf_bp); 419 return; 420 } 421 422 /* Check agf_longest */ 423 error = xfs_alloc_get_rec(sc->sa.cnt_cur, &agbno, &blocks, &have); 424 if (!xchk_should_check_xref(sc, &error, &sc->sa.cnt_cur)) 425 return; 426 if (!have || blocks != be32_to_cpu(agf->agf_longest)) 427 xchk_block_xref_set_corrupt(sc, sc->sa.agf_bp); 428 } 429 430 /* Check the btree block counts in the AGF against the btrees. */ 431 STATIC void 432 xchk_agf_xref_btreeblks( 433 struct xfs_scrub *sc) 434 { 435 struct xfs_agf *agf = sc->sa.agf_bp->b_addr; 436 struct xfs_mount *mp = sc->mp; 437 xfs_agblock_t blocks; 438 xfs_agblock_t btreeblks; 439 int error; 440 441 /* agf_btreeblks didn't exist before lazysbcount */ 442 if (!xfs_has_lazysbcount(sc->mp)) 443 return; 444 445 /* Check agf_rmap_blocks; set up for agf_btreeblks check */ 446 if (sc->sa.rmap_cur) { 447 error = xfs_btree_count_blocks(sc->sa.rmap_cur, &blocks); 448 if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur)) 449 return; 450 btreeblks = blocks - 1; 451 if (blocks != be32_to_cpu(agf->agf_rmap_blocks)) 452 xchk_block_xref_set_corrupt(sc, sc->sa.agf_bp); 453 } else { 454 btreeblks = 0; 455 } 456 457 /* 458 * No rmap cursor; we can't xref if we have the rmapbt feature. 459 * We also can't do it if we're missing the free space btree cursors. 460 */ 461 if ((xfs_has_rmapbt(mp) && !sc->sa.rmap_cur) || 462 !sc->sa.bno_cur || !sc->sa.cnt_cur) 463 return; 464 465 /* Check agf_btreeblks */ 466 error = xfs_btree_count_blocks(sc->sa.bno_cur, &blocks); 467 if (!xchk_should_check_xref(sc, &error, &sc->sa.bno_cur)) 468 return; 469 btreeblks += blocks - 1; 470 471 error = xfs_btree_count_blocks(sc->sa.cnt_cur, &blocks); 472 if (!xchk_should_check_xref(sc, &error, &sc->sa.cnt_cur)) 473 return; 474 btreeblks += blocks - 1; 475 476 if (btreeblks != be32_to_cpu(agf->agf_btreeblks)) 477 xchk_block_xref_set_corrupt(sc, sc->sa.agf_bp); 478 } 479 480 /* Check agf_refcount_blocks against tree size */ 481 static inline void 482 xchk_agf_xref_refcblks( 483 struct xfs_scrub *sc) 484 { 485 struct xfs_agf *agf = sc->sa.agf_bp->b_addr; 486 xfs_agblock_t blocks; 487 int error; 488 489 if (!sc->sa.refc_cur) 490 return; 491 492 error = xfs_btree_count_blocks(sc->sa.refc_cur, &blocks); 493 if (!xchk_should_check_xref(sc, &error, &sc->sa.refc_cur)) 494 return; 495 if (blocks != be32_to_cpu(agf->agf_refcount_blocks)) 496 xchk_block_xref_set_corrupt(sc, sc->sa.agf_bp); 497 } 498 499 /* Cross-reference with the other btrees. */ 500 STATIC void 501 xchk_agf_xref( 502 struct xfs_scrub *sc) 503 { 504 struct xfs_mount *mp = sc->mp; 505 xfs_agblock_t agbno; 506 507 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 508 return; 509 510 agbno = XFS_AGF_BLOCK(mp); 511 512 xchk_ag_btcur_init(sc, &sc->sa); 513 514 xchk_xref_is_used_space(sc, agbno, 1); 515 xchk_agf_xref_freeblks(sc); 516 xchk_agf_xref_cntbt(sc); 517 xchk_xref_is_not_inode_chunk(sc, agbno, 1); 518 xchk_xref_is_only_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_FS); 519 xchk_agf_xref_btreeblks(sc); 520 xchk_xref_is_not_shared(sc, agbno, 1); 521 xchk_xref_is_not_cow_staging(sc, agbno, 1); 522 xchk_agf_xref_refcblks(sc); 523 524 /* scrub teardown will take care of sc->sa for us */ 525 } 526 527 /* Scrub the AGF. */ 528 int 529 xchk_agf( 530 struct xfs_scrub *sc) 531 { 532 struct xfs_mount *mp = sc->mp; 533 struct xfs_agf *agf; 534 struct xfs_perag *pag; 535 xfs_agnumber_t agno = sc->sm->sm_agno; 536 xfs_agblock_t agbno; 537 xfs_agblock_t eoag; 538 xfs_agblock_t agfl_first; 539 xfs_agblock_t agfl_last; 540 xfs_agblock_t agfl_count; 541 xfs_agblock_t fl_count; 542 int level; 543 int error = 0; 544 545 error = xchk_ag_read_headers(sc, agno, &sc->sa); 546 if (!xchk_process_error(sc, agno, XFS_AGF_BLOCK(sc->mp), &error)) 547 goto out; 548 xchk_buffer_recheck(sc, sc->sa.agf_bp); 549 550 agf = sc->sa.agf_bp->b_addr; 551 pag = sc->sa.pag; 552 553 /* Check the AG length */ 554 eoag = be32_to_cpu(agf->agf_length); 555 if (eoag != pag->block_count) 556 xchk_block_set_corrupt(sc, sc->sa.agf_bp); 557 558 /* Check the AGF btree roots and levels */ 559 agbno = be32_to_cpu(agf->agf_bno_root); 560 if (!xfs_verify_agbno(pag, agbno)) 561 xchk_block_set_corrupt(sc, sc->sa.agf_bp); 562 563 agbno = be32_to_cpu(agf->agf_cnt_root); 564 if (!xfs_verify_agbno(pag, agbno)) 565 xchk_block_set_corrupt(sc, sc->sa.agf_bp); 566 567 level = be32_to_cpu(agf->agf_bno_level); 568 if (level <= 0 || level > mp->m_alloc_maxlevels) 569 xchk_block_set_corrupt(sc, sc->sa.agf_bp); 570 571 level = be32_to_cpu(agf->agf_cnt_level); 572 if (level <= 0 || level > mp->m_alloc_maxlevels) 573 xchk_block_set_corrupt(sc, sc->sa.agf_bp); 574 575 if (xfs_has_rmapbt(mp)) { 576 agbno = be32_to_cpu(agf->agf_rmap_root); 577 if (!xfs_verify_agbno(pag, agbno)) 578 xchk_block_set_corrupt(sc, sc->sa.agf_bp); 579 580 level = be32_to_cpu(agf->agf_rmap_level); 581 if (level <= 0 || level > mp->m_rmap_maxlevels) 582 xchk_block_set_corrupt(sc, sc->sa.agf_bp); 583 } 584 585 if (xfs_has_reflink(mp)) { 586 agbno = be32_to_cpu(agf->agf_refcount_root); 587 if (!xfs_verify_agbno(pag, agbno)) 588 xchk_block_set_corrupt(sc, sc->sa.agf_bp); 589 590 level = be32_to_cpu(agf->agf_refcount_level); 591 if (level <= 0 || level > mp->m_refc_maxlevels) 592 xchk_block_set_corrupt(sc, sc->sa.agf_bp); 593 } 594 595 /* Check the AGFL counters */ 596 agfl_first = be32_to_cpu(agf->agf_flfirst); 597 agfl_last = be32_to_cpu(agf->agf_fllast); 598 agfl_count = be32_to_cpu(agf->agf_flcount); 599 if (agfl_last > agfl_first) 600 fl_count = agfl_last - agfl_first + 1; 601 else 602 fl_count = xfs_agfl_size(mp) - agfl_first + agfl_last + 1; 603 if (agfl_count != 0 && fl_count != agfl_count) 604 xchk_block_set_corrupt(sc, sc->sa.agf_bp); 605 606 /* Do the incore counters match? */ 607 if (pag->pagf_freeblks != be32_to_cpu(agf->agf_freeblks)) 608 xchk_block_set_corrupt(sc, sc->sa.agf_bp); 609 if (pag->pagf_flcount != be32_to_cpu(agf->agf_flcount)) 610 xchk_block_set_corrupt(sc, sc->sa.agf_bp); 611 if (xfs_has_lazysbcount(sc->mp) && 612 pag->pagf_btreeblks != be32_to_cpu(agf->agf_btreeblks)) 613 xchk_block_set_corrupt(sc, sc->sa.agf_bp); 614 615 xchk_agf_xref(sc); 616 out: 617 return error; 618 } 619 620 /* AGFL */ 621 622 struct xchk_agfl_info { 623 /* Number of AGFL entries that the AGF claims are in use. */ 624 unsigned int agflcount; 625 626 /* Number of AGFL entries that we found. */ 627 unsigned int nr_entries; 628 629 /* Buffer to hold AGFL entries for extent checking. */ 630 xfs_agblock_t *entries; 631 632 struct xfs_buf *agfl_bp; 633 struct xfs_scrub *sc; 634 }; 635 636 /* Cross-reference with the other btrees. */ 637 STATIC void 638 xchk_agfl_block_xref( 639 struct xfs_scrub *sc, 640 xfs_agblock_t agbno) 641 { 642 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 643 return; 644 645 xchk_xref_is_used_space(sc, agbno, 1); 646 xchk_xref_is_not_inode_chunk(sc, agbno, 1); 647 xchk_xref_is_only_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_AG); 648 xchk_xref_is_not_shared(sc, agbno, 1); 649 xchk_xref_is_not_cow_staging(sc, agbno, 1); 650 } 651 652 /* Scrub an AGFL block. */ 653 STATIC int 654 xchk_agfl_block( 655 struct xfs_mount *mp, 656 xfs_agblock_t agbno, 657 void *priv) 658 { 659 struct xchk_agfl_info *sai = priv; 660 struct xfs_scrub *sc = sai->sc; 661 662 if (xfs_verify_agbno(sc->sa.pag, agbno) && 663 sai->nr_entries < sai->agflcount) 664 sai->entries[sai->nr_entries++] = agbno; 665 else 666 xchk_block_set_corrupt(sc, sai->agfl_bp); 667 668 xchk_agfl_block_xref(sc, agbno); 669 670 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 671 return -ECANCELED; 672 673 return 0; 674 } 675 676 static int 677 xchk_agblock_cmp( 678 const void *pa, 679 const void *pb) 680 { 681 const xfs_agblock_t *a = pa; 682 const xfs_agblock_t *b = pb; 683 684 return (int)*a - (int)*b; 685 } 686 687 /* Cross-reference with the other btrees. */ 688 STATIC void 689 xchk_agfl_xref( 690 struct xfs_scrub *sc) 691 { 692 struct xfs_mount *mp = sc->mp; 693 xfs_agblock_t agbno; 694 695 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 696 return; 697 698 agbno = XFS_AGFL_BLOCK(mp); 699 700 xchk_ag_btcur_init(sc, &sc->sa); 701 702 xchk_xref_is_used_space(sc, agbno, 1); 703 xchk_xref_is_not_inode_chunk(sc, agbno, 1); 704 xchk_xref_is_only_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_FS); 705 xchk_xref_is_not_shared(sc, agbno, 1); 706 xchk_xref_is_not_cow_staging(sc, agbno, 1); 707 708 /* 709 * Scrub teardown will take care of sc->sa for us. Leave sc->sa 710 * active so that the agfl block xref can use it too. 711 */ 712 } 713 714 /* Scrub the AGFL. */ 715 int 716 xchk_agfl( 717 struct xfs_scrub *sc) 718 { 719 struct xchk_agfl_info sai = { 720 .sc = sc, 721 }; 722 struct xfs_agf *agf; 723 xfs_agnumber_t agno = sc->sm->sm_agno; 724 unsigned int i; 725 int error; 726 727 /* Lock the AGF and AGI so that nobody can touch this AG. */ 728 error = xchk_ag_read_headers(sc, agno, &sc->sa); 729 if (!xchk_process_error(sc, agno, XFS_AGFL_BLOCK(sc->mp), &error)) 730 return error; 731 if (!sc->sa.agf_bp) 732 return -EFSCORRUPTED; 733 734 /* Try to read the AGFL, and verify its structure if we get it. */ 735 error = xfs_alloc_read_agfl(sc->sa.pag, sc->tp, &sai.agfl_bp); 736 if (!xchk_process_error(sc, agno, XFS_AGFL_BLOCK(sc->mp), &error)) 737 return error; 738 xchk_buffer_recheck(sc, sai.agfl_bp); 739 740 xchk_agfl_xref(sc); 741 742 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 743 goto out; 744 745 /* Allocate buffer to ensure uniqueness of AGFL entries. */ 746 agf = sc->sa.agf_bp->b_addr; 747 sai.agflcount = be32_to_cpu(agf->agf_flcount); 748 if (sai.agflcount > xfs_agfl_size(sc->mp)) { 749 xchk_block_set_corrupt(sc, sc->sa.agf_bp); 750 goto out; 751 } 752 sai.entries = kvcalloc(sai.agflcount, sizeof(xfs_agblock_t), 753 XCHK_GFP_FLAGS); 754 if (!sai.entries) { 755 error = -ENOMEM; 756 goto out; 757 } 758 759 /* Check the blocks in the AGFL. */ 760 error = xfs_agfl_walk(sc->mp, sc->sa.agf_bp->b_addr, sai.agfl_bp, 761 xchk_agfl_block, &sai); 762 if (error == -ECANCELED) { 763 error = 0; 764 goto out_free; 765 } 766 if (error) 767 goto out_free; 768 769 if (sai.agflcount != sai.nr_entries) { 770 xchk_block_set_corrupt(sc, sc->sa.agf_bp); 771 goto out_free; 772 } 773 774 /* Sort entries, check for duplicates. */ 775 sort(sai.entries, sai.nr_entries, sizeof(sai.entries[0]), 776 xchk_agblock_cmp, NULL); 777 for (i = 1; i < sai.nr_entries; i++) { 778 if (sai.entries[i] == sai.entries[i - 1]) { 779 xchk_block_set_corrupt(sc, sc->sa.agf_bp); 780 break; 781 } 782 } 783 784 out_free: 785 kvfree(sai.entries); 786 out: 787 return error; 788 } 789 790 /* AGI */ 791 792 /* Check agi_count/agi_freecount */ 793 static inline void 794 xchk_agi_xref_icounts( 795 struct xfs_scrub *sc) 796 { 797 struct xfs_agi *agi = sc->sa.agi_bp->b_addr; 798 xfs_agino_t icount; 799 xfs_agino_t freecount; 800 int error; 801 802 if (!sc->sa.ino_cur) 803 return; 804 805 error = xfs_ialloc_count_inodes(sc->sa.ino_cur, &icount, &freecount); 806 if (!xchk_should_check_xref(sc, &error, &sc->sa.ino_cur)) 807 return; 808 if (be32_to_cpu(agi->agi_count) != icount || 809 be32_to_cpu(agi->agi_freecount) != freecount) 810 xchk_block_xref_set_corrupt(sc, sc->sa.agi_bp); 811 } 812 813 /* Check agi_[fi]blocks against tree size */ 814 static inline void 815 xchk_agi_xref_fiblocks( 816 struct xfs_scrub *sc) 817 { 818 struct xfs_agi *agi = sc->sa.agi_bp->b_addr; 819 xfs_agblock_t blocks; 820 int error = 0; 821 822 if (!xfs_has_inobtcounts(sc->mp)) 823 return; 824 825 if (sc->sa.ino_cur) { 826 error = xfs_btree_count_blocks(sc->sa.ino_cur, &blocks); 827 if (!xchk_should_check_xref(sc, &error, &sc->sa.ino_cur)) 828 return; 829 if (blocks != be32_to_cpu(agi->agi_iblocks)) 830 xchk_block_xref_set_corrupt(sc, sc->sa.agi_bp); 831 } 832 833 if (sc->sa.fino_cur) { 834 error = xfs_btree_count_blocks(sc->sa.fino_cur, &blocks); 835 if (!xchk_should_check_xref(sc, &error, &sc->sa.fino_cur)) 836 return; 837 if (blocks != be32_to_cpu(agi->agi_fblocks)) 838 xchk_block_xref_set_corrupt(sc, sc->sa.agi_bp); 839 } 840 } 841 842 /* Cross-reference with the other btrees. */ 843 STATIC void 844 xchk_agi_xref( 845 struct xfs_scrub *sc) 846 { 847 struct xfs_mount *mp = sc->mp; 848 xfs_agblock_t agbno; 849 850 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 851 return; 852 853 agbno = XFS_AGI_BLOCK(mp); 854 855 xchk_ag_btcur_init(sc, &sc->sa); 856 857 xchk_xref_is_used_space(sc, agbno, 1); 858 xchk_xref_is_not_inode_chunk(sc, agbno, 1); 859 xchk_agi_xref_icounts(sc); 860 xchk_xref_is_only_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_FS); 861 xchk_xref_is_not_shared(sc, agbno, 1); 862 xchk_xref_is_not_cow_staging(sc, agbno, 1); 863 xchk_agi_xref_fiblocks(sc); 864 865 /* scrub teardown will take care of sc->sa for us */ 866 } 867 868 /* 869 * Check the unlinked buckets for links to bad inodes. We hold the AGI, so 870 * there cannot be any threads updating unlinked list pointers in this AG. 871 */ 872 STATIC void 873 xchk_iunlink( 874 struct xfs_scrub *sc, 875 struct xfs_agi *agi) 876 { 877 unsigned int i; 878 struct xfs_inode *ip; 879 880 for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) { 881 xfs_agino_t agino = be32_to_cpu(agi->agi_unlinked[i]); 882 883 while (agino != NULLAGINO) { 884 if (agino % XFS_AGI_UNLINKED_BUCKETS != i) { 885 xchk_block_set_corrupt(sc, sc->sa.agi_bp); 886 return; 887 } 888 889 ip = xfs_iunlink_lookup(sc->sa.pag, agino); 890 if (!ip) { 891 xchk_block_set_corrupt(sc, sc->sa.agi_bp); 892 return; 893 } 894 895 if (!xfs_inode_on_unlinked_list(ip)) { 896 xchk_block_set_corrupt(sc, sc->sa.agi_bp); 897 return; 898 } 899 900 agino = ip->i_next_unlinked; 901 } 902 } 903 } 904 905 /* Scrub the AGI. */ 906 int 907 xchk_agi( 908 struct xfs_scrub *sc) 909 { 910 struct xfs_mount *mp = sc->mp; 911 struct xfs_agi *agi; 912 struct xfs_perag *pag; 913 struct xfs_ino_geometry *igeo = M_IGEO(sc->mp); 914 xfs_agnumber_t agno = sc->sm->sm_agno; 915 xfs_agblock_t agbno; 916 xfs_agblock_t eoag; 917 xfs_agino_t agino; 918 xfs_agino_t first_agino; 919 xfs_agino_t last_agino; 920 xfs_agino_t icount; 921 int i; 922 int level; 923 int error = 0; 924 925 error = xchk_ag_read_headers(sc, agno, &sc->sa); 926 if (!xchk_process_error(sc, agno, XFS_AGI_BLOCK(sc->mp), &error)) 927 goto out; 928 xchk_buffer_recheck(sc, sc->sa.agi_bp); 929 930 agi = sc->sa.agi_bp->b_addr; 931 pag = sc->sa.pag; 932 933 /* Check the AG length */ 934 eoag = be32_to_cpu(agi->agi_length); 935 if (eoag != pag->block_count) 936 xchk_block_set_corrupt(sc, sc->sa.agi_bp); 937 938 /* Check btree roots and levels */ 939 agbno = be32_to_cpu(agi->agi_root); 940 if (!xfs_verify_agbno(pag, agbno)) 941 xchk_block_set_corrupt(sc, sc->sa.agi_bp); 942 943 level = be32_to_cpu(agi->agi_level); 944 if (level <= 0 || level > igeo->inobt_maxlevels) 945 xchk_block_set_corrupt(sc, sc->sa.agi_bp); 946 947 if (xfs_has_finobt(mp)) { 948 agbno = be32_to_cpu(agi->agi_free_root); 949 if (!xfs_verify_agbno(pag, agbno)) 950 xchk_block_set_corrupt(sc, sc->sa.agi_bp); 951 952 level = be32_to_cpu(agi->agi_free_level); 953 if (level <= 0 || level > igeo->inobt_maxlevels) 954 xchk_block_set_corrupt(sc, sc->sa.agi_bp); 955 } 956 957 /* Check inode counters */ 958 xfs_agino_range(mp, agno, &first_agino, &last_agino); 959 icount = be32_to_cpu(agi->agi_count); 960 if (icount > last_agino - first_agino + 1 || 961 icount < be32_to_cpu(agi->agi_freecount)) 962 xchk_block_set_corrupt(sc, sc->sa.agi_bp); 963 964 /* Check inode pointers */ 965 agino = be32_to_cpu(agi->agi_newino); 966 if (!xfs_verify_agino_or_null(pag, agino)) 967 xchk_block_set_corrupt(sc, sc->sa.agi_bp); 968 969 agino = be32_to_cpu(agi->agi_dirino); 970 if (!xfs_verify_agino_or_null(pag, agino)) 971 xchk_block_set_corrupt(sc, sc->sa.agi_bp); 972 973 /* Check unlinked inode buckets */ 974 for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) { 975 agino = be32_to_cpu(agi->agi_unlinked[i]); 976 if (!xfs_verify_agino_or_null(pag, agino)) 977 xchk_block_set_corrupt(sc, sc->sa.agi_bp); 978 } 979 980 if (agi->agi_pad32 != cpu_to_be32(0)) 981 xchk_block_set_corrupt(sc, sc->sa.agi_bp); 982 983 /* Do the incore counters match? */ 984 if (pag->pagi_count != be32_to_cpu(agi->agi_count)) 985 xchk_block_set_corrupt(sc, sc->sa.agi_bp); 986 if (pag->pagi_freecount != be32_to_cpu(agi->agi_freecount)) 987 xchk_block_set_corrupt(sc, sc->sa.agi_bp); 988 989 xchk_iunlink(sc, agi); 990 991 xchk_agi_xref(sc); 992 out: 993 return error; 994 } 995
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.