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_log_format.h" 14 #include "xfs_trans.h" 15 #include "xfs_inode.h" 16 #include "xfs_ialloc.h" 17 #include "xfs_ialloc_btree.h" 18 #include "xfs_icache.h" 19 #include "xfs_rmap.h" 20 #include "scrub/scrub.h" 21 #include "scrub/common.h" 22 #include "scrub/btree.h" 23 #include "scrub/trace.h" 24 #include "xfs_ag.h" 25 26 /* 27 * Set us up to scrub inode btrees. 28 * If we detect a discrepancy between the inobt and the inode, 29 * try again after forcing logged inode cores out to disk. 30 */ 31 int 32 xchk_setup_ag_iallocbt( 33 struct xfs_scrub *sc) 34 { 35 if (xchk_need_intent_drain(sc)) 36 xchk_fsgates_enable(sc, XCHK_FSGATES_DRAIN); 37 return xchk_setup_ag_btree(sc, sc->flags & XCHK_TRY_HARDER); 38 } 39 40 /* Inode btree scrubber. */ 41 42 struct xchk_iallocbt { 43 /* Number of inodes we see while scanning inobt. */ 44 unsigned long long inodes; 45 46 /* Expected next startino, for big block filesystems. */ 47 xfs_agino_t next_startino; 48 49 /* Expected end of the current inode cluster. */ 50 xfs_agino_t next_cluster_ino; 51 }; 52 53 /* 54 * Does the finobt have a record for this inode with the same hole/free state? 55 * This is a bit complicated because of the following: 56 * 57 * - The finobt need not have a record if all inodes in the inobt record are 58 * allocated. 59 * - The finobt need not have a record if all inodes in the inobt record are 60 * free. 61 * - The finobt need not have a record if the inobt record says this is a hole. 62 * This likely doesn't happen in practice. 63 */ 64 STATIC int 65 xchk_inobt_xref_finobt( 66 struct xfs_scrub *sc, 67 struct xfs_inobt_rec_incore *irec, 68 xfs_agino_t agino, 69 bool free, 70 bool hole) 71 { 72 struct xfs_inobt_rec_incore frec; 73 struct xfs_btree_cur *cur = sc->sa.fino_cur; 74 bool ffree, fhole; 75 unsigned int frec_idx, fhole_idx; 76 int has_record; 77 int error; 78 79 ASSERT(cur->bc_btnum == XFS_BTNUM_FINO); 80 81 error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &has_record); 82 if (error) 83 return error; 84 if (!has_record) 85 goto no_record; 86 87 error = xfs_inobt_get_rec(cur, &frec, &has_record); 88 if (!has_record) 89 return -EFSCORRUPTED; 90 91 if (frec.ir_startino + XFS_INODES_PER_CHUNK <= agino) 92 goto no_record; 93 94 /* There's a finobt record; free and hole status must match. */ 95 frec_idx = agino - frec.ir_startino; 96 ffree = frec.ir_free & (1ULL << frec_idx); 97 fhole_idx = frec_idx / XFS_INODES_PER_HOLEMASK_BIT; 98 fhole = frec.ir_holemask & (1U << fhole_idx); 99 100 if (ffree != free) 101 xchk_btree_xref_set_corrupt(sc, cur, 0); 102 if (fhole != hole) 103 xchk_btree_xref_set_corrupt(sc, cur, 0); 104 return 0; 105 106 no_record: 107 /* inobt record is fully allocated */ 108 if (irec->ir_free == 0) 109 return 0; 110 111 /* inobt record is totally unallocated */ 112 if (irec->ir_free == XFS_INOBT_ALL_FREE) 113 return 0; 114 115 /* inobt record says this is a hole */ 116 if (hole) 117 return 0; 118 119 /* finobt doesn't care about allocated inodes */ 120 if (!free) 121 return 0; 122 123 xchk_btree_xref_set_corrupt(sc, cur, 0); 124 return 0; 125 } 126 127 /* 128 * Make sure that each inode of this part of an inobt record has the same 129 * sparse and free status as the finobt. 130 */ 131 STATIC void 132 xchk_inobt_chunk_xref_finobt( 133 struct xfs_scrub *sc, 134 struct xfs_inobt_rec_incore *irec, 135 xfs_agino_t agino, 136 unsigned int nr_inodes) 137 { 138 xfs_agino_t i; 139 unsigned int rec_idx; 140 int error; 141 142 ASSERT(sc->sm->sm_type == XFS_SCRUB_TYPE_INOBT); 143 144 if (!sc->sa.fino_cur || xchk_skip_xref(sc->sm)) 145 return; 146 147 for (i = agino, rec_idx = agino - irec->ir_startino; 148 i < agino + nr_inodes; 149 i++, rec_idx++) { 150 bool free, hole; 151 unsigned int hole_idx; 152 153 free = irec->ir_free & (1ULL << rec_idx); 154 hole_idx = rec_idx / XFS_INODES_PER_HOLEMASK_BIT; 155 hole = irec->ir_holemask & (1U << hole_idx); 156 157 error = xchk_inobt_xref_finobt(sc, irec, i, free, hole); 158 if (!xchk_should_check_xref(sc, &error, &sc->sa.fino_cur)) 159 return; 160 } 161 } 162 163 /* 164 * Does the inobt have a record for this inode with the same hole/free state? 165 * The inobt must always have a record if there's a finobt record. 166 */ 167 STATIC int 168 xchk_finobt_xref_inobt( 169 struct xfs_scrub *sc, 170 struct xfs_inobt_rec_incore *frec, 171 xfs_agino_t agino, 172 bool ffree, 173 bool fhole) 174 { 175 struct xfs_inobt_rec_incore irec; 176 struct xfs_btree_cur *cur = sc->sa.ino_cur; 177 bool free, hole; 178 unsigned int rec_idx, hole_idx; 179 int has_record; 180 int error; 181 182 ASSERT(cur->bc_btnum == XFS_BTNUM_INO); 183 184 error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &has_record); 185 if (error) 186 return error; 187 if (!has_record) 188 goto no_record; 189 190 error = xfs_inobt_get_rec(cur, &irec, &has_record); 191 if (!has_record) 192 return -EFSCORRUPTED; 193 194 if (irec.ir_startino + XFS_INODES_PER_CHUNK <= agino) 195 goto no_record; 196 197 /* There's an inobt record; free and hole status must match. */ 198 rec_idx = agino - irec.ir_startino; 199 free = irec.ir_free & (1ULL << rec_idx); 200 hole_idx = rec_idx / XFS_INODES_PER_HOLEMASK_BIT; 201 hole = irec.ir_holemask & (1U << hole_idx); 202 203 if (ffree != free) 204 xchk_btree_xref_set_corrupt(sc, cur, 0); 205 if (fhole != hole) 206 xchk_btree_xref_set_corrupt(sc, cur, 0); 207 return 0; 208 209 no_record: 210 /* finobt should never have a record for which the inobt does not */ 211 xchk_btree_xref_set_corrupt(sc, cur, 0); 212 return 0; 213 } 214 215 /* 216 * Make sure that each inode of this part of an finobt record has the same 217 * sparse and free status as the inobt. 218 */ 219 STATIC void 220 xchk_finobt_chunk_xref_inobt( 221 struct xfs_scrub *sc, 222 struct xfs_inobt_rec_incore *frec, 223 xfs_agino_t agino, 224 unsigned int nr_inodes) 225 { 226 xfs_agino_t i; 227 unsigned int rec_idx; 228 int error; 229 230 ASSERT(sc->sm->sm_type == XFS_SCRUB_TYPE_FINOBT); 231 232 if (!sc->sa.ino_cur || xchk_skip_xref(sc->sm)) 233 return; 234 235 for (i = agino, rec_idx = agino - frec->ir_startino; 236 i < agino + nr_inodes; 237 i++, rec_idx++) { 238 bool ffree, fhole; 239 unsigned int hole_idx; 240 241 ffree = frec->ir_free & (1ULL << rec_idx); 242 hole_idx = rec_idx / XFS_INODES_PER_HOLEMASK_BIT; 243 fhole = frec->ir_holemask & (1U << hole_idx); 244 245 error = xchk_finobt_xref_inobt(sc, frec, i, ffree, fhole); 246 if (!xchk_should_check_xref(sc, &error, &sc->sa.ino_cur)) 247 return; 248 } 249 } 250 251 /* Is this chunk worth checking and cross-referencing? */ 252 STATIC bool 253 xchk_iallocbt_chunk( 254 struct xchk_btree *bs, 255 struct xfs_inobt_rec_incore *irec, 256 xfs_agino_t agino, 257 unsigned int nr_inodes) 258 { 259 struct xfs_scrub *sc = bs->sc; 260 struct xfs_mount *mp = bs->cur->bc_mp; 261 struct xfs_perag *pag = bs->cur->bc_ag.pag; 262 xfs_agblock_t agbno; 263 xfs_extlen_t len; 264 265 agbno = XFS_AGINO_TO_AGBNO(mp, agino); 266 len = XFS_B_TO_FSB(mp, nr_inodes * mp->m_sb.sb_inodesize); 267 268 if (!xfs_verify_agbext(pag, agbno, len)) 269 xchk_btree_set_corrupt(bs->sc, bs->cur, 0); 270 271 if (bs->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 272 return false; 273 274 xchk_xref_is_used_space(sc, agbno, len); 275 if (sc->sm->sm_type == XFS_SCRUB_TYPE_INOBT) 276 xchk_inobt_chunk_xref_finobt(sc, irec, agino, nr_inodes); 277 else 278 xchk_finobt_chunk_xref_inobt(sc, irec, agino, nr_inodes); 279 xchk_xref_is_only_owned_by(sc, agbno, len, &XFS_RMAP_OINFO_INODES); 280 xchk_xref_is_not_shared(sc, agbno, len); 281 xchk_xref_is_not_cow_staging(sc, agbno, len); 282 return true; 283 } 284 285 /* 286 * Check that an inode's allocation status matches ir_free in the inobt 287 * record. First we try querying the in-core inode state, and if the inode 288 * isn't loaded we examine the on-disk inode directly. 289 * 290 * Since there can be 1:M and M:1 mappings between inobt records and inode 291 * clusters, we pass in the inode location information as an inobt record; 292 * the index of an inode cluster within the inobt record (as well as the 293 * cluster buffer itself); and the index of the inode within the cluster. 294 * 295 * @irec is the inobt record. 296 * @irec_ino is the inode offset from the start of the record. 297 * @dip is the on-disk inode. 298 */ 299 STATIC int 300 xchk_iallocbt_check_cluster_ifree( 301 struct xchk_btree *bs, 302 struct xfs_inobt_rec_incore *irec, 303 unsigned int irec_ino, 304 struct xfs_dinode *dip) 305 { 306 struct xfs_mount *mp = bs->cur->bc_mp; 307 xfs_ino_t fsino; 308 xfs_agino_t agino; 309 bool irec_free; 310 bool ino_inuse; 311 bool freemask_ok; 312 int error = 0; 313 314 if (xchk_should_terminate(bs->sc, &error)) 315 return error; 316 317 /* 318 * Given an inobt record and the offset of an inode from the start of 319 * the record, compute which fs inode we're talking about. 320 */ 321 agino = irec->ir_startino + irec_ino; 322 fsino = XFS_AGINO_TO_INO(mp, bs->cur->bc_ag.pag->pag_agno, agino); 323 irec_free = (irec->ir_free & XFS_INOBT_MASK(irec_ino)); 324 325 if (be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC || 326 (dip->di_version >= 3 && be64_to_cpu(dip->di_ino) != fsino)) { 327 xchk_btree_set_corrupt(bs->sc, bs->cur, 0); 328 goto out; 329 } 330 331 error = xfs_icache_inode_is_allocated(mp, bs->cur->bc_tp, fsino, 332 &ino_inuse); 333 if (error == -ENODATA) { 334 /* Not cached, just read the disk buffer */ 335 freemask_ok = irec_free ^ !!(dip->di_mode); 336 if (!(bs->sc->flags & XCHK_TRY_HARDER) && !freemask_ok) 337 return -EDEADLOCK; 338 } else if (error < 0) { 339 /* 340 * Inode is only half assembled, or there was an IO error, 341 * or the verifier failed, so don't bother trying to check. 342 * The inode scrubber can deal with this. 343 */ 344 goto out; 345 } else { 346 /* Inode is all there. */ 347 freemask_ok = irec_free ^ ino_inuse; 348 } 349 if (!freemask_ok) 350 xchk_btree_set_corrupt(bs->sc, bs->cur, 0); 351 out: 352 return 0; 353 } 354 355 /* 356 * Check that the holemask and freemask of a hypothetical inode cluster match 357 * what's actually on disk. If sparse inodes are enabled, the cluster does 358 * not actually have to map to inodes if the corresponding holemask bit is set. 359 * 360 * @cluster_base is the first inode in the cluster within the @irec. 361 */ 362 STATIC int 363 xchk_iallocbt_check_cluster( 364 struct xchk_btree *bs, 365 struct xfs_inobt_rec_incore *irec, 366 unsigned int cluster_base) 367 { 368 struct xfs_imap imap; 369 struct xfs_mount *mp = bs->cur->bc_mp; 370 struct xfs_buf *cluster_bp; 371 unsigned int nr_inodes; 372 xfs_agnumber_t agno = bs->cur->bc_ag.pag->pag_agno; 373 xfs_agblock_t agbno; 374 unsigned int cluster_index; 375 uint16_t cluster_mask = 0; 376 uint16_t ir_holemask; 377 int error = 0; 378 379 nr_inodes = min_t(unsigned int, XFS_INODES_PER_CHUNK, 380 M_IGEO(mp)->inodes_per_cluster); 381 382 /* Map this inode cluster */ 383 agbno = XFS_AGINO_TO_AGBNO(mp, irec->ir_startino + cluster_base); 384 385 /* Compute a bitmask for this cluster that can be used for holemask. */ 386 for (cluster_index = 0; 387 cluster_index < nr_inodes; 388 cluster_index += XFS_INODES_PER_HOLEMASK_BIT) 389 cluster_mask |= XFS_INOBT_MASK((cluster_base + cluster_index) / 390 XFS_INODES_PER_HOLEMASK_BIT); 391 392 /* 393 * Map the first inode of this cluster to a buffer and offset. 394 * Be careful about inobt records that don't align with the start of 395 * the inode buffer when block sizes are large enough to hold multiple 396 * inode chunks. When this happens, cluster_base will be zero but 397 * ir_startino can be large enough to make im_boffset nonzero. 398 */ 399 ir_holemask = (irec->ir_holemask & cluster_mask); 400 imap.im_blkno = XFS_AGB_TO_DADDR(mp, agno, agbno); 401 imap.im_len = XFS_FSB_TO_BB(mp, M_IGEO(mp)->blocks_per_cluster); 402 imap.im_boffset = XFS_INO_TO_OFFSET(mp, irec->ir_startino) << 403 mp->m_sb.sb_inodelog; 404 405 if (imap.im_boffset != 0 && cluster_base != 0) { 406 ASSERT(imap.im_boffset == 0 || cluster_base == 0); 407 xchk_btree_set_corrupt(bs->sc, bs->cur, 0); 408 return 0; 409 } 410 411 trace_xchk_iallocbt_check_cluster(mp, agno, irec->ir_startino, 412 imap.im_blkno, imap.im_len, cluster_base, nr_inodes, 413 cluster_mask, ir_holemask, 414 XFS_INO_TO_OFFSET(mp, irec->ir_startino + 415 cluster_base)); 416 417 /* The whole cluster must be a hole or not a hole. */ 418 if (ir_holemask != cluster_mask && ir_holemask != 0) { 419 xchk_btree_set_corrupt(bs->sc, bs->cur, 0); 420 return 0; 421 } 422 423 /* If any part of this is a hole, skip it. */ 424 if (ir_holemask) { 425 xchk_xref_is_not_owned_by(bs->sc, agbno, 426 M_IGEO(mp)->blocks_per_cluster, 427 &XFS_RMAP_OINFO_INODES); 428 return 0; 429 } 430 431 xchk_xref_is_only_owned_by(bs->sc, agbno, M_IGEO(mp)->blocks_per_cluster, 432 &XFS_RMAP_OINFO_INODES); 433 434 /* Grab the inode cluster buffer. */ 435 error = xfs_imap_to_bp(mp, bs->cur->bc_tp, &imap, &cluster_bp); 436 if (!xchk_btree_xref_process_error(bs->sc, bs->cur, 0, &error)) 437 return error; 438 439 /* Check free status of each inode within this cluster. */ 440 for (cluster_index = 0; cluster_index < nr_inodes; cluster_index++) { 441 struct xfs_dinode *dip; 442 443 if (imap.im_boffset >= BBTOB(cluster_bp->b_length)) { 444 xchk_btree_set_corrupt(bs->sc, bs->cur, 0); 445 break; 446 } 447 448 dip = xfs_buf_offset(cluster_bp, imap.im_boffset); 449 error = xchk_iallocbt_check_cluster_ifree(bs, irec, 450 cluster_base + cluster_index, dip); 451 if (error) 452 break; 453 imap.im_boffset += mp->m_sb.sb_inodesize; 454 } 455 456 xfs_trans_brelse(bs->cur->bc_tp, cluster_bp); 457 return error; 458 } 459 460 /* 461 * For all the inode clusters that could map to this inobt record, make sure 462 * that the holemask makes sense and that the allocation status of each inode 463 * matches the freemask. 464 */ 465 STATIC int 466 xchk_iallocbt_check_clusters( 467 struct xchk_btree *bs, 468 struct xfs_inobt_rec_incore *irec) 469 { 470 unsigned int cluster_base; 471 int error = 0; 472 473 /* 474 * For the common case where this inobt record maps to multiple inode 475 * clusters this will call _check_cluster for each cluster. 476 * 477 * For the case that multiple inobt records map to a single cluster, 478 * this will call _check_cluster once. 479 */ 480 for (cluster_base = 0; 481 cluster_base < XFS_INODES_PER_CHUNK; 482 cluster_base += M_IGEO(bs->sc->mp)->inodes_per_cluster) { 483 error = xchk_iallocbt_check_cluster(bs, irec, cluster_base); 484 if (error) 485 break; 486 } 487 488 return error; 489 } 490 491 /* 492 * Make sure this inode btree record is aligned properly. Because a fs block 493 * contains multiple inodes, we check that the inobt record is aligned to the 494 * correct inode, not just the correct block on disk. This results in a finer 495 * grained corruption check. 496 */ 497 STATIC void 498 xchk_iallocbt_rec_alignment( 499 struct xchk_btree *bs, 500 struct xfs_inobt_rec_incore *irec) 501 { 502 struct xfs_mount *mp = bs->sc->mp; 503 struct xchk_iallocbt *iabt = bs->private; 504 struct xfs_ino_geometry *igeo = M_IGEO(mp); 505 506 /* 507 * finobt records have different positioning requirements than inobt 508 * records: each finobt record must have a corresponding inobt record. 509 * That is checked in the xref function, so for now we only catch the 510 * obvious case where the record isn't at all aligned properly. 511 * 512 * Note that if a fs block contains more than a single chunk of inodes, 513 * we will have finobt records only for those chunks containing free 514 * inodes, and therefore expect chunk alignment of finobt records. 515 * Otherwise, we expect that the finobt record is aligned to the 516 * cluster alignment as told by the superblock. 517 */ 518 if (bs->cur->bc_btnum == XFS_BTNUM_FINO) { 519 unsigned int imask; 520 521 imask = min_t(unsigned int, XFS_INODES_PER_CHUNK, 522 igeo->cluster_align_inodes) - 1; 523 if (irec->ir_startino & imask) 524 xchk_btree_set_corrupt(bs->sc, bs->cur, 0); 525 return; 526 } 527 528 if (iabt->next_startino != NULLAGINO) { 529 /* 530 * We're midway through a cluster of inodes that is mapped by 531 * multiple inobt records. Did we get the record for the next 532 * irec in the sequence? 533 */ 534 if (irec->ir_startino != iabt->next_startino) { 535 xchk_btree_set_corrupt(bs->sc, bs->cur, 0); 536 return; 537 } 538 539 iabt->next_startino += XFS_INODES_PER_CHUNK; 540 541 /* Are we done with the cluster? */ 542 if (iabt->next_startino >= iabt->next_cluster_ino) { 543 iabt->next_startino = NULLAGINO; 544 iabt->next_cluster_ino = NULLAGINO; 545 } 546 return; 547 } 548 549 /* inobt records must be aligned to cluster and inoalignmnt size. */ 550 if (irec->ir_startino & (igeo->cluster_align_inodes - 1)) { 551 xchk_btree_set_corrupt(bs->sc, bs->cur, 0); 552 return; 553 } 554 555 if (irec->ir_startino & (igeo->inodes_per_cluster - 1)) { 556 xchk_btree_set_corrupt(bs->sc, bs->cur, 0); 557 return; 558 } 559 560 if (igeo->inodes_per_cluster <= XFS_INODES_PER_CHUNK) 561 return; 562 563 /* 564 * If this is the start of an inode cluster that can be mapped by 565 * multiple inobt records, the next inobt record must follow exactly 566 * after this one. 567 */ 568 iabt->next_startino = irec->ir_startino + XFS_INODES_PER_CHUNK; 569 iabt->next_cluster_ino = irec->ir_startino + igeo->inodes_per_cluster; 570 } 571 572 /* Scrub an inobt/finobt record. */ 573 STATIC int 574 xchk_iallocbt_rec( 575 struct xchk_btree *bs, 576 const union xfs_btree_rec *rec) 577 { 578 struct xfs_mount *mp = bs->cur->bc_mp; 579 struct xchk_iallocbt *iabt = bs->private; 580 struct xfs_inobt_rec_incore irec; 581 uint64_t holes; 582 xfs_agino_t agino; 583 int holecount; 584 int i; 585 int error = 0; 586 uint16_t holemask; 587 588 xfs_inobt_btrec_to_irec(mp, rec, &irec); 589 if (xfs_inobt_check_irec(bs->cur, &irec) != NULL) { 590 xchk_btree_set_corrupt(bs->sc, bs->cur, 0); 591 return 0; 592 } 593 594 agino = irec.ir_startino; 595 596 xchk_iallocbt_rec_alignment(bs, &irec); 597 if (bs->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 598 goto out; 599 600 iabt->inodes += irec.ir_count; 601 602 /* Handle non-sparse inodes */ 603 if (!xfs_inobt_issparse(irec.ir_holemask)) { 604 if (irec.ir_count != XFS_INODES_PER_CHUNK) 605 xchk_btree_set_corrupt(bs->sc, bs->cur, 0); 606 607 if (!xchk_iallocbt_chunk(bs, &irec, agino, 608 XFS_INODES_PER_CHUNK)) 609 goto out; 610 goto check_clusters; 611 } 612 613 /* Check each chunk of a sparse inode cluster. */ 614 holemask = irec.ir_holemask; 615 holecount = 0; 616 holes = ~xfs_inobt_irec_to_allocmask(&irec); 617 if ((holes & irec.ir_free) != holes || 618 irec.ir_freecount > irec.ir_count) 619 xchk_btree_set_corrupt(bs->sc, bs->cur, 0); 620 621 for (i = 0; i < XFS_INOBT_HOLEMASK_BITS; i++) { 622 if (holemask & 1) 623 holecount += XFS_INODES_PER_HOLEMASK_BIT; 624 else if (!xchk_iallocbt_chunk(bs, &irec, agino, 625 XFS_INODES_PER_HOLEMASK_BIT)) 626 goto out; 627 holemask >>= 1; 628 agino += XFS_INODES_PER_HOLEMASK_BIT; 629 } 630 631 if (holecount > XFS_INODES_PER_CHUNK || 632 holecount + irec.ir_count != XFS_INODES_PER_CHUNK) 633 xchk_btree_set_corrupt(bs->sc, bs->cur, 0); 634 635 check_clusters: 636 if (bs->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 637 goto out; 638 639 error = xchk_iallocbt_check_clusters(bs, &irec); 640 if (error) 641 goto out; 642 643 out: 644 return error; 645 } 646 647 /* 648 * Make sure the inode btrees are as large as the rmap thinks they are. 649 * Don't bother if we're missing btree cursors, as we're already corrupt. 650 */ 651 STATIC void 652 xchk_iallocbt_xref_rmap_btreeblks( 653 struct xfs_scrub *sc, 654 int which) 655 { 656 xfs_filblks_t blocks; 657 xfs_extlen_t inobt_blocks = 0; 658 xfs_extlen_t finobt_blocks = 0; 659 int error; 660 661 if (!sc->sa.ino_cur || !sc->sa.rmap_cur || 662 (xfs_has_finobt(sc->mp) && !sc->sa.fino_cur) || 663 xchk_skip_xref(sc->sm)) 664 return; 665 666 /* Check that we saw as many inobt blocks as the rmap says. */ 667 error = xfs_btree_count_blocks(sc->sa.ino_cur, &inobt_blocks); 668 if (!xchk_process_error(sc, 0, 0, &error)) 669 return; 670 671 if (sc->sa.fino_cur) { 672 error = xfs_btree_count_blocks(sc->sa.fino_cur, &finobt_blocks); 673 if (!xchk_process_error(sc, 0, 0, &error)) 674 return; 675 } 676 677 error = xchk_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur, 678 &XFS_RMAP_OINFO_INOBT, &blocks); 679 if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur)) 680 return; 681 if (blocks != inobt_blocks + finobt_blocks) 682 xchk_btree_set_corrupt(sc, sc->sa.ino_cur, 0); 683 } 684 685 /* 686 * Make sure that the inobt records point to the same number of blocks as 687 * the rmap says are owned by inodes. 688 */ 689 STATIC void 690 xchk_iallocbt_xref_rmap_inodes( 691 struct xfs_scrub *sc, 692 int which, 693 unsigned long long inodes) 694 { 695 xfs_filblks_t blocks; 696 xfs_filblks_t inode_blocks; 697 int error; 698 699 if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm)) 700 return; 701 702 /* Check that we saw as many inode blocks as the rmap knows about. */ 703 error = xchk_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur, 704 &XFS_RMAP_OINFO_INODES, &blocks); 705 if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur)) 706 return; 707 inode_blocks = XFS_B_TO_FSB(sc->mp, inodes * sc->mp->m_sb.sb_inodesize); 708 if (blocks != inode_blocks) 709 xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0); 710 } 711 712 /* Scrub the inode btrees for some AG. */ 713 STATIC int 714 xchk_iallocbt( 715 struct xfs_scrub *sc, 716 xfs_btnum_t which) 717 { 718 struct xfs_btree_cur *cur; 719 struct xchk_iallocbt iabt = { 720 .inodes = 0, 721 .next_startino = NULLAGINO, 722 .next_cluster_ino = NULLAGINO, 723 }; 724 int error; 725 726 cur = which == XFS_BTNUM_INO ? sc->sa.ino_cur : sc->sa.fino_cur; 727 error = xchk_btree(sc, cur, xchk_iallocbt_rec, &XFS_RMAP_OINFO_INOBT, 728 &iabt); 729 if (error) 730 return error; 731 732 xchk_iallocbt_xref_rmap_btreeblks(sc, which); 733 734 /* 735 * If we're scrubbing the inode btree, inode_blocks is the number of 736 * blocks pointed to by all the inode chunk records. Therefore, we 737 * should compare to the number of inode chunk blocks that the rmap 738 * knows about. We can't do this for the finobt since it only points 739 * to inode chunks with free inodes. 740 */ 741 if (which == XFS_BTNUM_INO) 742 xchk_iallocbt_xref_rmap_inodes(sc, which, iabt.inodes); 743 744 return error; 745 } 746 747 int 748 xchk_inobt( 749 struct xfs_scrub *sc) 750 { 751 return xchk_iallocbt(sc, XFS_BTNUM_INO); 752 } 753 754 int 755 xchk_finobt( 756 struct xfs_scrub *sc) 757 { 758 return xchk_iallocbt(sc, XFS_BTNUM_FINO); 759 } 760 761 /* See if an inode btree has (or doesn't have) an inode chunk record. */ 762 static inline void 763 xchk_xref_inode_check( 764 struct xfs_scrub *sc, 765 xfs_agblock_t agbno, 766 xfs_extlen_t len, 767 struct xfs_btree_cur **icur, 768 enum xbtree_recpacking expected) 769 { 770 enum xbtree_recpacking outcome; 771 int error; 772 773 if (!(*icur) || xchk_skip_xref(sc->sm)) 774 return; 775 776 error = xfs_ialloc_has_inodes_at_extent(*icur, agbno, len, &outcome); 777 if (!xchk_should_check_xref(sc, &error, icur)) 778 return; 779 if (outcome != expected) 780 xchk_btree_xref_set_corrupt(sc, *icur, 0); 781 } 782 783 /* xref check that the extent is not covered by inodes */ 784 void 785 xchk_xref_is_not_inode_chunk( 786 struct xfs_scrub *sc, 787 xfs_agblock_t agbno, 788 xfs_extlen_t len) 789 { 790 xchk_xref_inode_check(sc, agbno, len, &sc->sa.ino_cur, 791 XBTREE_RECPACKING_EMPTY); 792 xchk_xref_inode_check(sc, agbno, len, &sc->sa.fino_cur, 793 XBTREE_RECPACKING_EMPTY); 794 } 795 796 /* xref check that the extent is covered by inodes */ 797 void 798 xchk_xref_is_inode_chunk( 799 struct xfs_scrub *sc, 800 xfs_agblock_t agbno, 801 xfs_extlen_t len) 802 { 803 xchk_xref_inode_check(sc, agbno, len, &sc->sa.ino_cur, 804 XBTREE_RECPACKING_FULL); 805 } 806