1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2017 Oracle. All Rights Reserved. 4 * Author: Darrick J. Wong <darrick.wong@oracle.com> 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_dir2.h" 16 #include "xfs_dir2_priv.h" 17 #include "xfs_attr_leaf.h" 18 #include "scrub/scrub.h" 19 #include "scrub/common.h" 20 #include "scrub/trace.h" 21 #include "scrub/dabtree.h" 22 23 /* Directory/Attribute Btree */ 24 25 /* 26 * Check for da btree operation errors. See the section about handling 27 * operational errors in common.c. 28 */ 29 bool 30 xchk_da_process_error( 31 struct xchk_da_btree *ds, 32 int level, 33 int *error) 34 { 35 struct xfs_scrub *sc = ds->sc; 36 37 if (*error == 0) 38 return true; 39 40 switch (*error) { 41 case -EDEADLOCK: 42 /* Used to restart an op with deadlock avoidance. */ 43 trace_xchk_deadlock_retry(sc->ip, sc->sm, *error); 44 break; 45 case -EFSBADCRC: 46 case -EFSCORRUPTED: 47 /* Note the badness but don't abort. */ 48 sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; 49 *error = 0; 50 /* fall through */ 51 default: 52 trace_xchk_file_op_error(sc, ds->dargs.whichfork, 53 xfs_dir2_da_to_db(ds->dargs.geo, 54 ds->state->path.blk[level].blkno), 55 *error, __return_address); 56 break; 57 } 58 return false; 59 } 60 61 /* 62 * Check for da btree corruption. See the section about handling 63 * operational errors in common.c. 64 */ 65 void 66 xchk_da_set_corrupt( 67 struct xchk_da_btree *ds, 68 int level) 69 { 70 struct xfs_scrub *sc = ds->sc; 71 72 sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; 73 74 trace_xchk_fblock_error(sc, ds->dargs.whichfork, 75 xfs_dir2_da_to_db(ds->dargs.geo, 76 ds->state->path.blk[level].blkno), 77 __return_address); 78 } 79 80 static struct xfs_da_node_entry * 81 xchk_da_btree_node_entry( 82 struct xchk_da_btree *ds, 83 int level) 84 { 85 struct xfs_da_state_blk *blk = &ds->state->path.blk[level]; 86 struct xfs_da3_icnode_hdr hdr; 87 88 ASSERT(blk->magic == XFS_DA_NODE_MAGIC); 89 90 xfs_da3_node_hdr_from_disk(ds->sc->mp, &hdr, blk->bp->b_addr); 91 return hdr.btree + blk->index; 92 } 93 94 /* Scrub a da btree hash (key). */ 95 int 96 xchk_da_btree_hash( 97 struct xchk_da_btree *ds, 98 int level, 99 __be32 *hashp) 100 { 101 struct xfs_da_node_entry *entry; 102 xfs_dahash_t hash; 103 xfs_dahash_t parent_hash; 104 105 /* Is this hash in order? */ 106 hash = be32_to_cpu(*hashp); 107 if (hash < ds->hashes[level]) 108 xchk_da_set_corrupt(ds, level); 109 ds->hashes[level] = hash; 110 111 if (level == 0) 112 return 0; 113 114 /* Is this hash no larger than the parent hash? */ 115 entry = xchk_da_btree_node_entry(ds, level - 1); 116 parent_hash = be32_to_cpu(entry->hashval); 117 if (parent_hash < hash) 118 xchk_da_set_corrupt(ds, level); 119 120 return 0; 121 } 122 123 /* 124 * Check a da btree pointer. Returns true if it's ok to use this 125 * pointer. 126 */ 127 STATIC bool 128 xchk_da_btree_ptr_ok( 129 struct xchk_da_btree *ds, 130 int level, 131 xfs_dablk_t blkno) 132 { 133 if (blkno < ds->lowest || (ds->highest != 0 && blkno >= ds->highest)) { 134 xchk_da_set_corrupt(ds, level); 135 return false; 136 } 137 138 return true; 139 } 140 141 /* 142 * The da btree scrubber can handle leaf1 blocks as a degenerate 143 * form of leafn blocks. Since the regular da code doesn't handle 144 * leaf1, we must multiplex the verifiers. 145 */ 146 static void 147 xchk_da_btree_read_verify( 148 struct xfs_buf *bp) 149 { 150 struct xfs_da_blkinfo *info = bp->b_addr; 151 152 switch (be16_to_cpu(info->magic)) { 153 case XFS_DIR2_LEAF1_MAGIC: 154 case XFS_DIR3_LEAF1_MAGIC: 155 bp->b_ops = &xfs_dir3_leaf1_buf_ops; 156 bp->b_ops->verify_read(bp); 157 return; 158 default: 159 /* 160 * xfs_da3_node_buf_ops already know how to handle 161 * DA*_NODE, ATTR*_LEAF, and DIR*_LEAFN blocks. 162 */ 163 bp->b_ops = &xfs_da3_node_buf_ops; 164 bp->b_ops->verify_read(bp); 165 return; 166 } 167 } 168 static void 169 xchk_da_btree_write_verify( 170 struct xfs_buf *bp) 171 { 172 struct xfs_da_blkinfo *info = bp->b_addr; 173 174 switch (be16_to_cpu(info->magic)) { 175 case XFS_DIR2_LEAF1_MAGIC: 176 case XFS_DIR3_LEAF1_MAGIC: 177 bp->b_ops = &xfs_dir3_leaf1_buf_ops; 178 bp->b_ops->verify_write(bp); 179 return; 180 default: 181 /* 182 * xfs_da3_node_buf_ops already know how to handle 183 * DA*_NODE, ATTR*_LEAF, and DIR*_LEAFN blocks. 184 */ 185 bp->b_ops = &xfs_da3_node_buf_ops; 186 bp->b_ops->verify_write(bp); 187 return; 188 } 189 } 190 static void * 191 xchk_da_btree_verify( 192 struct xfs_buf *bp) 193 { 194 struct xfs_da_blkinfo *info = bp->b_addr; 195 196 switch (be16_to_cpu(info->magic)) { 197 case XFS_DIR2_LEAF1_MAGIC: 198 case XFS_DIR3_LEAF1_MAGIC: 199 bp->b_ops = &xfs_dir3_leaf1_buf_ops; 200 return bp->b_ops->verify_struct(bp); 201 default: 202 bp->b_ops = &xfs_da3_node_buf_ops; 203 return bp->b_ops->verify_struct(bp); 204 } 205 } 206 207 static const struct xfs_buf_ops xchk_da_btree_buf_ops = { 208 .name = "xchk_da_btree", 209 .verify_read = xchk_da_btree_read_verify, 210 .verify_write = xchk_da_btree_write_verify, 211 .verify_struct = xchk_da_btree_verify, 212 }; 213 214 /* Check a block's sibling. */ 215 STATIC int 216 xchk_da_btree_block_check_sibling( 217 struct xchk_da_btree *ds, 218 int level, 219 int direction, 220 xfs_dablk_t sibling) 221 { 222 int retval; 223 int error; 224 225 memcpy(&ds->state->altpath, &ds->state->path, 226 sizeof(ds->state->altpath)); 227 228 /* 229 * If the pointer is null, we shouldn't be able to move the upper 230 * level pointer anywhere. 231 */ 232 if (sibling == 0) { 233 error = xfs_da3_path_shift(ds->state, &ds->state->altpath, 234 direction, false, &retval); 235 if (error == 0 && retval == 0) 236 xchk_da_set_corrupt(ds, level); 237 error = 0; 238 goto out; 239 } 240 241 /* Move the alternate cursor one block in the direction given. */ 242 error = xfs_da3_path_shift(ds->state, &ds->state->altpath, 243 direction, false, &retval); 244 if (!xchk_da_process_error(ds, level, &error)) 245 return error; 246 if (retval) { 247 xchk_da_set_corrupt(ds, level); 248 return error; 249 } 250 if (ds->state->altpath.blk[level].bp) 251 xchk_buffer_recheck(ds->sc, 252 ds->state->altpath.blk[level].bp); 253 254 /* Compare upper level pointer to sibling pointer. */ 255 if (ds->state->altpath.blk[level].blkno != sibling) 256 xchk_da_set_corrupt(ds, level); 257 if (ds->state->altpath.blk[level].bp) { 258 xfs_trans_brelse(ds->dargs.trans, 259 ds->state->altpath.blk[level].bp); 260 ds->state->altpath.blk[level].bp = NULL; 261 } 262 out: 263 return error; 264 } 265 266 /* Check a block's sibling pointers. */ 267 STATIC int 268 xchk_da_btree_block_check_siblings( 269 struct xchk_da_btree *ds, 270 int level, 271 struct xfs_da_blkinfo *hdr) 272 { 273 xfs_dablk_t forw; 274 xfs_dablk_t back; 275 int error = 0; 276 277 forw = be32_to_cpu(hdr->forw); 278 back = be32_to_cpu(hdr->back); 279 280 /* Top level blocks should not have sibling pointers. */ 281 if (level == 0) { 282 if (forw != 0 || back != 0) 283 xchk_da_set_corrupt(ds, level); 284 return 0; 285 } 286 287 /* 288 * Check back (left) and forw (right) pointers. These functions 289 * absorb error codes for us. 290 */ 291 error = xchk_da_btree_block_check_sibling(ds, level, 0, back); 292 if (error) 293 goto out; 294 error = xchk_da_btree_block_check_sibling(ds, level, 1, forw); 295 296 out: 297 memset(&ds->state->altpath, 0, sizeof(ds->state->altpath)); 298 return error; 299 } 300 301 /* Load a dir/attribute block from a btree. */ 302 STATIC int 303 xchk_da_btree_block( 304 struct xchk_da_btree *ds, 305 int level, 306 xfs_dablk_t blkno) 307 { 308 struct xfs_da_state_blk *blk; 309 struct xfs_da_intnode *node; 310 struct xfs_da_node_entry *btree; 311 struct xfs_da3_blkinfo *hdr3; 312 struct xfs_da_args *dargs = &ds->dargs; 313 struct xfs_inode *ip = ds->dargs.dp; 314 xfs_ino_t owner; 315 int *pmaxrecs; 316 struct xfs_da3_icnode_hdr nodehdr; 317 int error = 0; 318 319 blk = &ds->state->path.blk[level]; 320 ds->state->path.active = level + 1; 321 322 /* Release old block. */ 323 if (blk->bp) { 324 xfs_trans_brelse(dargs->trans, blk->bp); 325 blk->bp = NULL; 326 } 327 328 /* Check the pointer. */ 329 blk->blkno = blkno; 330 if (!xchk_da_btree_ptr_ok(ds, level, blkno)) 331 goto out_nobuf; 332 333 /* Read the buffer. */ 334 error = xfs_da_read_buf(dargs->trans, dargs->dp, blk->blkno, 335 XFS_DABUF_MAP_HOLE_OK, &blk->bp, dargs->whichfork, 336 &xchk_da_btree_buf_ops); 337 if (!xchk_da_process_error(ds, level, &error)) 338 goto out_nobuf; 339 if (blk->bp) 340 xchk_buffer_recheck(ds->sc, blk->bp); 341 342 /* 343 * We didn't find a dir btree root block, which means that 344 * there's no LEAF1/LEAFN tree (at least not where it's supposed 345 * to be), so jump out now. 346 */ 347 if (ds->dargs.whichfork == XFS_DATA_FORK && level == 0 && 348 blk->bp == NULL) 349 goto out_nobuf; 350 351 /* It's /not/ ok for attr trees not to have a da btree. */ 352 if (blk->bp == NULL) { 353 xchk_da_set_corrupt(ds, level); 354 goto out_nobuf; 355 } 356 357 hdr3 = blk->bp->b_addr; 358 blk->magic = be16_to_cpu(hdr3->hdr.magic); 359 pmaxrecs = &ds->maxrecs[level]; 360 361 /* We only started zeroing the header on v5 filesystems. */ 362 if (xfs_sb_version_hascrc(&ds->sc->mp->m_sb) && hdr3->hdr.pad) 363 xchk_da_set_corrupt(ds, level); 364 365 /* Check the owner. */ 366 if (xfs_sb_version_hascrc(&ip->i_mount->m_sb)) { 367 owner = be64_to_cpu(hdr3->owner); 368 if (owner != ip->i_ino) 369 xchk_da_set_corrupt(ds, level); 370 } 371 372 /* Check the siblings. */ 373 error = xchk_da_btree_block_check_siblings(ds, level, &hdr3->hdr); 374 if (error) 375 goto out; 376 377 /* Interpret the buffer. */ 378 switch (blk->magic) { 379 case XFS_ATTR_LEAF_MAGIC: 380 case XFS_ATTR3_LEAF_MAGIC: 381 xfs_trans_buf_set_type(dargs->trans, blk->bp, 382 XFS_BLFT_ATTR_LEAF_BUF); 383 blk->magic = XFS_ATTR_LEAF_MAGIC; 384 blk->hashval = xfs_attr_leaf_lasthash(blk->bp, pmaxrecs); 385 if (ds->tree_level != 0) 386 xchk_da_set_corrupt(ds, level); 387 break; 388 case XFS_DIR2_LEAFN_MAGIC: 389 case XFS_DIR3_LEAFN_MAGIC: 390 xfs_trans_buf_set_type(dargs->trans, blk->bp, 391 XFS_BLFT_DIR_LEAFN_BUF); 392 blk->magic = XFS_DIR2_LEAFN_MAGIC; 393 blk->hashval = xfs_dir2_leaf_lasthash(ip, blk->bp, pmaxrecs); 394 if (ds->tree_level != 0) 395 xchk_da_set_corrupt(ds, level); 396 break; 397 case XFS_DIR2_LEAF1_MAGIC: 398 case XFS_DIR3_LEAF1_MAGIC: 399 xfs_trans_buf_set_type(dargs->trans, blk->bp, 400 XFS_BLFT_DIR_LEAF1_BUF); 401 blk->magic = XFS_DIR2_LEAF1_MAGIC; 402 blk->hashval = xfs_dir2_leaf_lasthash(ip, blk->bp, pmaxrecs); 403 if (ds->tree_level != 0) 404 xchk_da_set_corrupt(ds, level); 405 break; 406 case XFS_DA_NODE_MAGIC: 407 case XFS_DA3_NODE_MAGIC: 408 xfs_trans_buf_set_type(dargs->trans, blk->bp, 409 XFS_BLFT_DA_NODE_BUF); 410 blk->magic = XFS_DA_NODE_MAGIC; 411 node = blk->bp->b_addr; 412 xfs_da3_node_hdr_from_disk(ip->i_mount, &nodehdr, node); 413 btree = nodehdr.btree; 414 *pmaxrecs = nodehdr.count; 415 blk->hashval = be32_to_cpu(btree[*pmaxrecs - 1].hashval); 416 if (level == 0) { 417 if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) { 418 xchk_da_set_corrupt(ds, level); 419 goto out_freebp; 420 } 421 ds->tree_level = nodehdr.level; 422 } else { 423 if (ds->tree_level != nodehdr.level) { 424 xchk_da_set_corrupt(ds, level); 425 goto out_freebp; 426 } 427 } 428 429 /* XXX: Check hdr3.pad32 once we know how to fix it. */ 430 break; 431 default: 432 xchk_da_set_corrupt(ds, level); 433 goto out_freebp; 434 } 435 436 out: 437 return error; 438 out_freebp: 439 xfs_trans_brelse(dargs->trans, blk->bp); 440 blk->bp = NULL; 441 out_nobuf: 442 blk->blkno = 0; 443 return error; 444 } 445 446 /* Visit all nodes and leaves of a da btree. */ 447 int 448 xchk_da_btree( 449 struct xfs_scrub *sc, 450 int whichfork, 451 xchk_da_btree_rec_fn scrub_fn, 452 void *private) 453 { 454 struct xchk_da_btree ds = {}; 455 struct xfs_mount *mp = sc->mp; 456 struct xfs_da_state_blk *blks; 457 struct xfs_da_node_entry *key; 458 xfs_dablk_t blkno; 459 int level; 460 int error; 461 462 /* Skip short format data structures; no btree to scan. */ 463 if (!xfs_ifork_has_extents(sc->ip, whichfork)) 464 return 0; 465 466 /* Set up initial da state. */ 467 ds.dargs.dp = sc->ip; 468 ds.dargs.whichfork = whichfork; 469 ds.dargs.trans = sc->tp; 470 ds.dargs.op_flags = XFS_DA_OP_OKNOENT; 471 ds.state = xfs_da_state_alloc(); 472 ds.state->args = &ds.dargs; 473 ds.state->mp = mp; 474 ds.sc = sc; 475 ds.private = private; 476 if (whichfork == XFS_ATTR_FORK) { 477 ds.dargs.geo = mp->m_attr_geo; 478 ds.lowest = 0; 479 ds.highest = 0; 480 } else { 481 ds.dargs.geo = mp->m_dir_geo; 482 ds.lowest = ds.dargs.geo->leafblk; 483 ds.highest = ds.dargs.geo->freeblk; 484 } 485 blkno = ds.lowest; 486 level = 0; 487 488 /* Find the root of the da tree, if present. */ 489 blks = ds.state->path.blk; 490 error = xchk_da_btree_block(&ds, level, blkno); 491 if (error) 492 goto out_state; 493 /* 494 * We didn't find a block at ds.lowest, which means that there's 495 * no LEAF1/LEAFN tree (at least not where it's supposed to be), 496 * so jump out now. 497 */ 498 if (blks[level].bp == NULL) 499 goto out_state; 500 501 blks[level].index = 0; 502 while (level >= 0 && level < XFS_DA_NODE_MAXDEPTH) { 503 /* Handle leaf block. */ 504 if (blks[level].magic != XFS_DA_NODE_MAGIC) { 505 /* End of leaf, pop back towards the root. */ 506 if (blks[level].index >= ds.maxrecs[level]) { 507 if (level > 0) 508 blks[level - 1].index++; 509 ds.tree_level++; 510 level--; 511 continue; 512 } 513 514 /* Dispatch record scrubbing. */ 515 error = scrub_fn(&ds, level); 516 if (error) 517 break; 518 if (xchk_should_terminate(sc, &error) || 519 (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) 520 break; 521 522 blks[level].index++; 523 continue; 524 } 525 526 527 /* End of node, pop back towards the root. */ 528 if (blks[level].index >= ds.maxrecs[level]) { 529 if (level > 0) 530 blks[level - 1].index++; 531 ds.tree_level++; 532 level--; 533 continue; 534 } 535 536 /* Hashes in order for scrub? */ 537 key = xchk_da_btree_node_entry(&ds, level); 538 error = xchk_da_btree_hash(&ds, level, &key->hashval); 539 if (error) 540 goto out; 541 542 /* Drill another level deeper. */ 543 blkno = be32_to_cpu(key->before); 544 level++; 545 if (level >= XFS_DA_NODE_MAXDEPTH) { 546 /* Too deep! */ 547 xchk_da_set_corrupt(&ds, level - 1); 548 break; 549 } 550 ds.tree_level--; 551 error = xchk_da_btree_block(&ds, level, blkno); 552 if (error) 553 goto out; 554 if (blks[level].bp == NULL) 555 goto out; 556 557 blks[level].index = 0; 558 } 559 560 out: 561 /* Release all the buffers we're tracking. */ 562 for (level = 0; level < XFS_DA_NODE_MAXDEPTH; level++) { 563 if (blks[level].bp == NULL) 564 continue; 565 xfs_trans_brelse(sc->tp, blks[level].bp); 566 blks[level].bp = NULL; 567 } 568 569 out_state: 570 xfs_da_state_free(ds.state); 571 return error; 572 } 573