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_log_format.h" 13 #include "xfs_trans.h" 14 #include "xfs_inode.h" 15 #include "xfs_icache.h" 16 #include "xfs_dir2.h" 17 #include "xfs_dir2_priv.h" 18 #include "xfs_health.h" 19 #include "scrub/scrub.h" 20 #include "scrub/common.h" 21 #include "scrub/dabtree.h" 22 #include "scrub/readdir.h" 23 #include "scrub/health.h" 24 25 /* Set us up to scrub directories. */ 26 int 27 xchk_setup_directory( 28 struct xfs_scrub *sc) 29 { 30 return xchk_setup_inode_contents(sc, 0); 31 } 32 33 /* Directories */ 34 35 /* Scrub a directory entry. */ 36 37 /* Check that an inode's mode matches a given XFS_DIR3_FT_* type. */ 38 STATIC void 39 xchk_dir_check_ftype( 40 struct xfs_scrub *sc, 41 xfs_fileoff_t offset, 42 struct xfs_inode *ip, 43 int ftype) 44 { 45 struct xfs_mount *mp = sc->mp; 46 47 if (!xfs_has_ftype(mp)) { 48 if (ftype != XFS_DIR3_FT_UNKNOWN && ftype != XFS_DIR3_FT_DIR) 49 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); 50 return; 51 } 52 53 if (xfs_mode_to_ftype(VFS_I(ip)->i_mode) != ftype) 54 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); 55 } 56 57 /* 58 * Scrub a single directory entry. 59 * 60 * Check the inode number to make sure it's sane, then we check that we can 61 * look up this filename. Finally, we check the ftype. 62 */ 63 STATIC int 64 xchk_dir_actor( 65 struct xfs_scrub *sc, 66 struct xfs_inode *dp, 67 xfs_dir2_dataptr_t dapos, 68 const struct xfs_name *name, 69 xfs_ino_t ino, 70 void *priv) 71 { 72 struct xfs_mount *mp = dp->i_mount; 73 struct xfs_inode *ip; 74 xfs_ino_t lookup_ino; 75 xfs_dablk_t offset; 76 int error = 0; 77 78 offset = xfs_dir2_db_to_da(mp->m_dir_geo, 79 xfs_dir2_dataptr_to_db(mp->m_dir_geo, dapos)); 80 81 if (xchk_should_terminate(sc, &error)) 82 return error; 83 84 /* Does this inode number make sense? */ 85 if (!xfs_verify_dir_ino(mp, ino)) { 86 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); 87 return -ECANCELED; 88 } 89 90 /* Does this name make sense? */ 91 if (!xfs_dir2_namecheck(name->name, name->len)) { 92 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); 93 return -ECANCELED; 94 } 95 96 if (!strncmp(".", name->name, name->len)) { 97 /* If this is "." then check that the inum matches the dir. */ 98 if (ino != dp->i_ino) 99 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); 100 } else if (!strncmp("..", name->name, name->len)) { 101 /* 102 * If this is ".." in the root inode, check that the inum 103 * matches this dir. 104 */ 105 if (dp->i_ino == mp->m_sb.sb_rootino && ino != dp->i_ino) 106 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); 107 } 108 109 /* Verify that we can look up this name by hash. */ 110 error = xchk_dir_lookup(sc, dp, name, &lookup_ino); 111 /* ENOENT means the hash lookup failed and the dir is corrupt */ 112 if (error == -ENOENT) 113 error = -EFSCORRUPTED; 114 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, offset, &error)) 115 goto out; 116 if (lookup_ino != ino) { 117 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); 118 return -ECANCELED; 119 } 120 121 /* 122 * Grab the inode pointed to by the dirent. We release the inode 123 * before we cancel the scrub transaction. 124 * 125 * If _iget returns -EINVAL or -ENOENT then the child inode number is 126 * garbage and the directory is corrupt. If the _iget returns 127 * -EFSCORRUPTED or -EFSBADCRC then the child is corrupt which is a 128 * cross referencing error. Any other error is an operational error. 129 */ 130 error = xchk_iget(sc, ino, &ip); 131 if (error == -EINVAL || error == -ENOENT) { 132 error = -EFSCORRUPTED; 133 xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error); 134 goto out; 135 } 136 if (!xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, offset, &error)) 137 goto out; 138 139 xchk_dir_check_ftype(sc, offset, ip, name->type); 140 xchk_irele(sc, ip); 141 out: 142 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 143 return -ECANCELED; 144 return error; 145 } 146 147 /* Scrub a directory btree record. */ 148 STATIC int 149 xchk_dir_rec( 150 struct xchk_da_btree *ds, 151 int level) 152 { 153 struct xfs_name dname = { }; 154 struct xfs_da_state_blk *blk = &ds->state->path.blk[level]; 155 struct xfs_mount *mp = ds->state->mp; 156 struct xfs_inode *dp = ds->dargs.dp; 157 struct xfs_da_geometry *geo = mp->m_dir_geo; 158 struct xfs_dir2_data_entry *dent; 159 struct xfs_buf *bp; 160 struct xfs_dir2_leaf_entry *ent; 161 unsigned int end; 162 unsigned int iter_off; 163 xfs_ino_t ino; 164 xfs_dablk_t rec_bno; 165 xfs_dir2_db_t db; 166 xfs_dir2_data_aoff_t off; 167 xfs_dir2_dataptr_t ptr; 168 xfs_dahash_t calc_hash; 169 xfs_dahash_t hash; 170 struct xfs_dir3_icleaf_hdr hdr; 171 unsigned int tag; 172 int error; 173 174 ASSERT(blk->magic == XFS_DIR2_LEAF1_MAGIC || 175 blk->magic == XFS_DIR2_LEAFN_MAGIC); 176 177 xfs_dir2_leaf_hdr_from_disk(mp, &hdr, blk->bp->b_addr); 178 ent = hdr.ents + blk->index; 179 180 /* Check the hash of the entry. */ 181 error = xchk_da_btree_hash(ds, level, &ent->hashval); 182 if (error) 183 goto out; 184 185 /* Valid hash pointer? */ 186 ptr = be32_to_cpu(ent->address); 187 if (ptr == 0) 188 return 0; 189 190 /* Find the directory entry's location. */ 191 db = xfs_dir2_dataptr_to_db(geo, ptr); 192 off = xfs_dir2_dataptr_to_off(geo, ptr); 193 rec_bno = xfs_dir2_db_to_da(geo, db); 194 195 if (rec_bno >= geo->leafblk) { 196 xchk_da_set_corrupt(ds, level); 197 goto out; 198 } 199 error = xfs_dir3_data_read(ds->dargs.trans, dp, rec_bno, 200 XFS_DABUF_MAP_HOLE_OK, &bp); 201 if (!xchk_fblock_process_error(ds->sc, XFS_DATA_FORK, rec_bno, 202 &error)) 203 goto out; 204 if (!bp) { 205 xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); 206 goto out; 207 } 208 xchk_buffer_recheck(ds->sc, bp); 209 210 if (ds->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 211 goto out_relse; 212 213 dent = bp->b_addr + off; 214 215 /* Make sure we got a real directory entry. */ 216 iter_off = geo->data_entry_offset; 217 end = xfs_dir3_data_end_offset(geo, bp->b_addr); 218 if (!end) { 219 xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); 220 goto out_relse; 221 } 222 for (;;) { 223 struct xfs_dir2_data_entry *dep = bp->b_addr + iter_off; 224 struct xfs_dir2_data_unused *dup = bp->b_addr + iter_off; 225 226 if (iter_off >= end) { 227 xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); 228 goto out_relse; 229 } 230 231 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { 232 iter_off += be16_to_cpu(dup->length); 233 continue; 234 } 235 if (dep == dent) 236 break; 237 iter_off += xfs_dir2_data_entsize(mp, dep->namelen); 238 } 239 240 /* Retrieve the entry, sanity check it, and compare hashes. */ 241 ino = be64_to_cpu(dent->inumber); 242 hash = be32_to_cpu(ent->hashval); 243 tag = be16_to_cpup(xfs_dir2_data_entry_tag_p(mp, dent)); 244 if (!xfs_verify_dir_ino(mp, ino) || tag != off) 245 xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); 246 if (dent->namelen == 0) { 247 xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); 248 goto out_relse; 249 } 250 251 /* Does the directory hash match? */ 252 dname.name = dent->name; 253 dname.len = dent->namelen; 254 calc_hash = xfs_dir2_hashname(mp, &dname); 255 if (calc_hash != hash) 256 xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); 257 258 out_relse: 259 xfs_trans_brelse(ds->dargs.trans, bp); 260 out: 261 return error; 262 } 263 264 /* 265 * Is this unused entry either in the bestfree or smaller than all of 266 * them? We've already checked that the bestfrees are sorted longest to 267 * shortest, and that there aren't any bogus entries. 268 */ 269 STATIC void 270 xchk_directory_check_free_entry( 271 struct xfs_scrub *sc, 272 xfs_dablk_t lblk, 273 struct xfs_dir2_data_free *bf, 274 struct xfs_dir2_data_unused *dup) 275 { 276 struct xfs_dir2_data_free *dfp; 277 unsigned int dup_length; 278 279 dup_length = be16_to_cpu(dup->length); 280 281 /* Unused entry is shorter than any of the bestfrees */ 282 if (dup_length < be16_to_cpu(bf[XFS_DIR2_DATA_FD_COUNT - 1].length)) 283 return; 284 285 for (dfp = &bf[XFS_DIR2_DATA_FD_COUNT - 1]; dfp >= bf; dfp--) 286 if (dup_length == be16_to_cpu(dfp->length)) 287 return; 288 289 /* Unused entry should be in the bestfrees but wasn't found. */ 290 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 291 } 292 293 /* Check free space info in a directory data block. */ 294 STATIC int 295 xchk_directory_data_bestfree( 296 struct xfs_scrub *sc, 297 xfs_dablk_t lblk, 298 bool is_block) 299 { 300 struct xfs_dir2_data_unused *dup; 301 struct xfs_dir2_data_free *dfp; 302 struct xfs_buf *bp; 303 struct xfs_dir2_data_free *bf; 304 struct xfs_mount *mp = sc->mp; 305 u16 tag; 306 unsigned int nr_bestfrees = 0; 307 unsigned int nr_frees = 0; 308 unsigned int smallest_bestfree; 309 int newlen; 310 unsigned int offset; 311 unsigned int end; 312 int error; 313 314 if (is_block) { 315 /* dir block format */ 316 if (lblk != XFS_B_TO_FSBT(mp, XFS_DIR2_DATA_OFFSET)) 317 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 318 error = xfs_dir3_block_read(sc->tp, sc->ip, &bp); 319 } else { 320 /* dir data format */ 321 error = xfs_dir3_data_read(sc->tp, sc->ip, lblk, 0, &bp); 322 } 323 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) 324 goto out; 325 xchk_buffer_recheck(sc, bp); 326 327 /* XXX: Check xfs_dir3_data_hdr.pad is zero once we start setting it. */ 328 329 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 330 goto out_buf; 331 332 /* Do the bestfrees correspond to actual free space? */ 333 bf = xfs_dir2_data_bestfree_p(mp, bp->b_addr); 334 smallest_bestfree = UINT_MAX; 335 for (dfp = &bf[0]; dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; dfp++) { 336 offset = be16_to_cpu(dfp->offset); 337 if (offset == 0) 338 continue; 339 if (offset >= mp->m_dir_geo->blksize) { 340 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 341 goto out_buf; 342 } 343 dup = bp->b_addr + offset; 344 tag = be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)); 345 346 /* bestfree doesn't match the entry it points at? */ 347 if (dup->freetag != cpu_to_be16(XFS_DIR2_DATA_FREE_TAG) || 348 be16_to_cpu(dup->length) != be16_to_cpu(dfp->length) || 349 tag != offset) { 350 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 351 goto out_buf; 352 } 353 354 /* bestfree records should be ordered largest to smallest */ 355 if (smallest_bestfree < be16_to_cpu(dfp->length)) { 356 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 357 goto out_buf; 358 } 359 360 smallest_bestfree = be16_to_cpu(dfp->length); 361 nr_bestfrees++; 362 } 363 364 /* Make sure the bestfrees are actually the best free spaces. */ 365 offset = mp->m_dir_geo->data_entry_offset; 366 end = xfs_dir3_data_end_offset(mp->m_dir_geo, bp->b_addr); 367 368 /* Iterate the entries, stopping when we hit or go past the end. */ 369 while (offset < end) { 370 dup = bp->b_addr + offset; 371 372 /* Skip real entries */ 373 if (dup->freetag != cpu_to_be16(XFS_DIR2_DATA_FREE_TAG)) { 374 struct xfs_dir2_data_entry *dep = bp->b_addr + offset; 375 376 newlen = xfs_dir2_data_entsize(mp, dep->namelen); 377 if (newlen <= 0) { 378 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 379 lblk); 380 goto out_buf; 381 } 382 offset += newlen; 383 continue; 384 } 385 386 /* Spot check this free entry */ 387 tag = be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)); 388 if (tag != offset) { 389 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 390 goto out_buf; 391 } 392 393 /* 394 * Either this entry is a bestfree or it's smaller than 395 * any of the bestfrees. 396 */ 397 xchk_directory_check_free_entry(sc, lblk, bf, dup); 398 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 399 goto out_buf; 400 401 /* Move on. */ 402 newlen = be16_to_cpu(dup->length); 403 if (newlen <= 0) { 404 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 405 goto out_buf; 406 } 407 offset += newlen; 408 if (offset <= end) 409 nr_frees++; 410 } 411 412 /* We're required to fill all the space. */ 413 if (offset != end) 414 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 415 416 /* Did we see at least as many free slots as there are bestfrees? */ 417 if (nr_frees < nr_bestfrees) 418 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 419 out_buf: 420 xfs_trans_brelse(sc->tp, bp); 421 out: 422 return error; 423 } 424 425 /* 426 * Does the free space length in the free space index block ($len) match 427 * the longest length in the directory data block's bestfree array? 428 * Assume that we've already checked that the data block's bestfree 429 * array is in order. 430 */ 431 STATIC void 432 xchk_directory_check_freesp( 433 struct xfs_scrub *sc, 434 xfs_dablk_t lblk, 435 struct xfs_buf *dbp, 436 unsigned int len) 437 { 438 struct xfs_dir2_data_free *dfp; 439 440 dfp = xfs_dir2_data_bestfree_p(sc->mp, dbp->b_addr); 441 442 if (len != be16_to_cpu(dfp->length)) 443 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 444 445 if (len > 0 && be16_to_cpu(dfp->offset) == 0) 446 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 447 } 448 449 /* Check free space info in a directory leaf1 block. */ 450 STATIC int 451 xchk_directory_leaf1_bestfree( 452 struct xfs_scrub *sc, 453 struct xfs_da_args *args, 454 xfs_dir2_db_t last_data_db, 455 xfs_dablk_t lblk) 456 { 457 struct xfs_dir3_icleaf_hdr leafhdr; 458 struct xfs_dir2_leaf_tail *ltp; 459 struct xfs_dir2_leaf *leaf; 460 struct xfs_buf *dbp; 461 struct xfs_buf *bp; 462 struct xfs_da_geometry *geo = sc->mp->m_dir_geo; 463 __be16 *bestp; 464 __u16 best; 465 __u32 hash; 466 __u32 lasthash = 0; 467 __u32 bestcount; 468 unsigned int stale = 0; 469 int i; 470 int error; 471 472 /* Read the free space block. */ 473 error = xfs_dir3_leaf_read(sc->tp, sc->ip, lblk, &bp); 474 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) 475 return error; 476 xchk_buffer_recheck(sc, bp); 477 478 leaf = bp->b_addr; 479 xfs_dir2_leaf_hdr_from_disk(sc->ip->i_mount, &leafhdr, leaf); 480 ltp = xfs_dir2_leaf_tail_p(geo, leaf); 481 bestcount = be32_to_cpu(ltp->bestcount); 482 bestp = xfs_dir2_leaf_bests_p(ltp); 483 484 if (xfs_has_crc(sc->mp)) { 485 struct xfs_dir3_leaf_hdr *hdr3 = bp->b_addr; 486 487 if (hdr3->pad != cpu_to_be32(0)) 488 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 489 } 490 491 /* 492 * There must be enough bestfree slots to cover all the directory data 493 * blocks that we scanned. It is possible for there to be a hole 494 * between the last data block and i_disk_size. This seems like an 495 * oversight to the scrub author, but as we have been writing out 496 * directories like this (and xfs_repair doesn't mind them) for years, 497 * that's what we have to check. 498 */ 499 if (bestcount != last_data_db + 1) { 500 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 501 goto out; 502 } 503 504 /* Is the leaf count even remotely sane? */ 505 if (leafhdr.count > geo->leaf_max_ents) { 506 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 507 goto out; 508 } 509 510 /* Leaves and bests don't overlap in leaf format. */ 511 if ((char *)&leafhdr.ents[leafhdr.count] > (char *)bestp) { 512 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 513 goto out; 514 } 515 516 /* Check hash value order, count stale entries. */ 517 for (i = 0; i < leafhdr.count; i++) { 518 hash = be32_to_cpu(leafhdr.ents[i].hashval); 519 if (i > 0 && lasthash > hash) 520 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 521 lasthash = hash; 522 if (leafhdr.ents[i].address == 523 cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) 524 stale++; 525 } 526 if (leafhdr.stale != stale) 527 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 528 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 529 goto out; 530 531 /* Check all the bestfree entries. */ 532 for (i = 0; i < bestcount; i++, bestp++) { 533 best = be16_to_cpu(*bestp); 534 error = xfs_dir3_data_read(sc->tp, sc->ip, 535 xfs_dir2_db_to_da(args->geo, i), 536 XFS_DABUF_MAP_HOLE_OK, 537 &dbp); 538 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, 539 &error)) 540 break; 541 542 if (!dbp) { 543 if (best != NULLDATAOFF) { 544 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 545 lblk); 546 break; 547 } 548 continue; 549 } 550 551 if (best == NULLDATAOFF) 552 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 553 else 554 xchk_directory_check_freesp(sc, lblk, dbp, best); 555 xfs_trans_brelse(sc->tp, dbp); 556 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 557 break; 558 } 559 out: 560 xfs_trans_brelse(sc->tp, bp); 561 return error; 562 } 563 564 /* Check free space info in a directory freespace block. */ 565 STATIC int 566 xchk_directory_free_bestfree( 567 struct xfs_scrub *sc, 568 struct xfs_da_args *args, 569 xfs_dablk_t lblk) 570 { 571 struct xfs_dir3_icfree_hdr freehdr; 572 struct xfs_buf *dbp; 573 struct xfs_buf *bp; 574 __u16 best; 575 unsigned int stale = 0; 576 int i; 577 int error; 578 579 /* Read the free space block */ 580 error = xfs_dir2_free_read(sc->tp, sc->ip, lblk, &bp); 581 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) 582 return error; 583 xchk_buffer_recheck(sc, bp); 584 585 if (xfs_has_crc(sc->mp)) { 586 struct xfs_dir3_free_hdr *hdr3 = bp->b_addr; 587 588 if (hdr3->pad != cpu_to_be32(0)) 589 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 590 } 591 592 /* Check all the entries. */ 593 xfs_dir2_free_hdr_from_disk(sc->ip->i_mount, &freehdr, bp->b_addr); 594 for (i = 0; i < freehdr.nvalid; i++) { 595 best = be16_to_cpu(freehdr.bests[i]); 596 if (best == NULLDATAOFF) { 597 stale++; 598 continue; 599 } 600 error = xfs_dir3_data_read(sc->tp, sc->ip, 601 (freehdr.firstdb + i) * args->geo->fsbcount, 602 0, &dbp); 603 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, 604 &error)) 605 goto out; 606 xchk_directory_check_freesp(sc, lblk, dbp, best); 607 xfs_trans_brelse(sc->tp, dbp); 608 } 609 610 if (freehdr.nused + stale != freehdr.nvalid) 611 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 612 out: 613 xfs_trans_brelse(sc->tp, bp); 614 return error; 615 } 616 617 /* Check free space information in directories. */ 618 STATIC int 619 xchk_directory_blocks( 620 struct xfs_scrub *sc) 621 { 622 struct xfs_bmbt_irec got; 623 struct xfs_da_args args = { 624 .dp = sc ->ip, 625 .whichfork = XFS_DATA_FORK, 626 .geo = sc->mp->m_dir_geo, 627 .trans = sc->tp, 628 }; 629 struct xfs_ifork *ifp = xfs_ifork_ptr(sc->ip, XFS_DATA_FORK); 630 struct xfs_mount *mp = sc->mp; 631 xfs_fileoff_t leaf_lblk; 632 xfs_fileoff_t free_lblk; 633 xfs_fileoff_t lblk; 634 struct xfs_iext_cursor icur; 635 xfs_dablk_t dabno; 636 xfs_dir2_db_t last_data_db = 0; 637 bool found; 638 bool is_block = false; 639 int error; 640 641 /* Ignore local format directories. */ 642 if (ifp->if_format != XFS_DINODE_FMT_EXTENTS && 643 ifp->if_format != XFS_DINODE_FMT_BTREE) 644 return 0; 645 646 lblk = XFS_B_TO_FSB(mp, XFS_DIR2_DATA_OFFSET); 647 leaf_lblk = XFS_B_TO_FSB(mp, XFS_DIR2_LEAF_OFFSET); 648 free_lblk = XFS_B_TO_FSB(mp, XFS_DIR2_FREE_OFFSET); 649 650 /* Is this a block dir? */ 651 error = xfs_dir2_isblock(&args, &is_block); 652 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) 653 goto out; 654 655 /* Iterate all the data extents in the directory... */ 656 found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &icur, &got); 657 while (found && !(sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) { 658 /* No more data blocks... */ 659 if (got.br_startoff >= leaf_lblk) 660 break; 661 662 /* 663 * Check each data block's bestfree data. 664 * 665 * Iterate all the fsbcount-aligned block offsets in 666 * this directory. The directory block reading code is 667 * smart enough to do its own bmap lookups to handle 668 * discontiguous directory blocks. When we're done 669 * with the extent record, re-query the bmap at the 670 * next fsbcount-aligned offset to avoid redundant 671 * block checks. 672 */ 673 for (lblk = roundup((xfs_dablk_t)got.br_startoff, 674 args.geo->fsbcount); 675 lblk < got.br_startoff + got.br_blockcount; 676 lblk += args.geo->fsbcount) { 677 last_data_db = xfs_dir2_da_to_db(args.geo, lblk); 678 error = xchk_directory_data_bestfree(sc, lblk, 679 is_block); 680 if (error) 681 goto out; 682 } 683 dabno = got.br_startoff + got.br_blockcount; 684 lblk = roundup(dabno, args.geo->fsbcount); 685 found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &icur, &got); 686 } 687 688 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 689 goto out; 690 691 /* Look for a leaf1 block, which has free info. */ 692 if (xfs_iext_lookup_extent(sc->ip, ifp, leaf_lblk, &icur, &got) && 693 got.br_startoff == leaf_lblk && 694 got.br_blockcount == args.geo->fsbcount && 695 !xfs_iext_next_extent(ifp, &icur, &got)) { 696 if (is_block) { 697 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 698 goto out; 699 } 700 error = xchk_directory_leaf1_bestfree(sc, &args, last_data_db, 701 leaf_lblk); 702 if (error) 703 goto out; 704 } 705 706 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 707 goto out; 708 709 /* Scan for free blocks */ 710 lblk = free_lblk; 711 found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &icur, &got); 712 while (found && !(sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) { 713 /* 714 * Dirs can't have blocks mapped above 2^32. 715 * Single-block dirs shouldn't even be here. 716 */ 717 lblk = got.br_startoff; 718 if (lblk & ~0xFFFFFFFFULL) { 719 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 720 goto out; 721 } 722 if (is_block) { 723 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 724 goto out; 725 } 726 727 /* 728 * Check each dir free block's bestfree data. 729 * 730 * Iterate all the fsbcount-aligned block offsets in 731 * this directory. The directory block reading code is 732 * smart enough to do its own bmap lookups to handle 733 * discontiguous directory blocks. When we're done 734 * with the extent record, re-query the bmap at the 735 * next fsbcount-aligned offset to avoid redundant 736 * block checks. 737 */ 738 for (lblk = roundup((xfs_dablk_t)got.br_startoff, 739 args.geo->fsbcount); 740 lblk < got.br_startoff + got.br_blockcount; 741 lblk += args.geo->fsbcount) { 742 error = xchk_directory_free_bestfree(sc, &args, 743 lblk); 744 if (error) 745 goto out; 746 } 747 dabno = got.br_startoff + got.br_blockcount; 748 lblk = roundup(dabno, args.geo->fsbcount); 749 found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &icur, &got); 750 } 751 out: 752 return error; 753 } 754 755 /* Scrub a whole directory. */ 756 int 757 xchk_directory( 758 struct xfs_scrub *sc) 759 { 760 int error; 761 762 if (!S_ISDIR(VFS_I(sc->ip)->i_mode)) 763 return -ENOENT; 764 765 if (xchk_file_looks_zapped(sc, XFS_SICK_INO_DIR_ZAPPED)) { 766 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); 767 return 0; 768 } 769 770 /* Plausible size? */ 771 if (sc->ip->i_disk_size < xfs_dir2_sf_hdr_size(0)) { 772 xchk_ino_set_corrupt(sc, sc->ip->i_ino); 773 return 0; 774 } 775 776 /* Check directory tree structure */ 777 error = xchk_da_btree(sc, XFS_DATA_FORK, xchk_dir_rec, NULL); 778 if (error) 779 return error; 780 781 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 782 return 0; 783 784 /* Check the freespace. */ 785 error = xchk_directory_blocks(sc); 786 if (error) 787 return error; 788 789 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 790 return 0; 791 792 /* Look up every name in this directory by hash. */ 793 error = xchk_dir_walk(sc, sc->ip, xchk_dir_actor, NULL); 794 if (error && error != -ECANCELED) 795 return error; 796 797 /* If the dir is clean, it is clearly not zapped. */ 798 xchk_mark_healthy_if_clean(sc, XFS_SICK_INO_DIR_ZAPPED); 799 return 0; 800 } 801 802 /* 803 * Decide if this directory has been zapped to satisfy the inode and ifork 804 * verifiers. Checking and repairing should be postponed until the directory 805 * is fixed. 806 */ 807 bool 808 xchk_dir_looks_zapped( 809 struct xfs_inode *dp) 810 { 811 /* Repair zapped this dir's data fork a short time ago */ 812 if (xfs_ifork_zapped(dp, XFS_DATA_FORK)) 813 return true; 814 815 /* 816 * If the dinode repair found a bad data fork, it will reset the fork 817 * to extents format with zero records and wait for the bmapbtd 818 * scrubber to reconstruct the block mappings. Directories always 819 * contain some content, so this is a clear sign of a zapped directory. 820 * The state checked by xfs_ifork_zapped is not persisted, so this is 821 * the secondary strategy if repairs are interrupted by a crash or an 822 * unmount. 823 */ 824 return dp->i_df.if_format == XFS_DINODE_FMT_EXTENTS && 825 dp->i_df.if_nextents == 0; 826 } 827