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_attr.h" 19 #include "xfs_parent.h" 20 #include "scrub/scrub.h" 21 #include "scrub/common.h" 22 #include "scrub/readdir.h" 23 #include "scrub/tempfile.h" 24 #include "scrub/repair.h" 25 #include "scrub/listxattr.h" 26 #include "scrub/xfile.h" 27 #include "scrub/xfarray.h" 28 #include "scrub/xfblob.h" 29 #include "scrub/trace.h" 30 31 /* Set us up to scrub parents. */ 32 int 33 xchk_setup_parent( 34 struct xfs_scrub *sc) 35 { 36 int error; 37 38 if (xchk_could_repair(sc)) { 39 error = xrep_setup_parent(sc); 40 if (error) 41 return error; 42 } 43 44 return xchk_setup_inode_contents(sc, 0); 45 } 46 47 /* Parent pointers */ 48 49 /* Look for an entry in a parent pointing to this inode. */ 50 51 struct xchk_parent_ctx { 52 struct xfs_scrub *sc; 53 xfs_nlink_t nlink; 54 }; 55 56 /* Look for a single entry in a directory pointing to an inode. */ 57 STATIC int 58 xchk_parent_actor( 59 struct xfs_scrub *sc, 60 struct xfs_inode *dp, 61 xfs_dir2_dataptr_t dapos, 62 const struct xfs_name *name, 63 xfs_ino_t ino, 64 void *priv) 65 { 66 struct xchk_parent_ctx *spc = priv; 67 int error = 0; 68 69 /* Does this name make sense? */ 70 if (!xfs_dir2_namecheck(name->name, name->len)) 71 error = -EFSCORRUPTED; 72 if (!xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, 0, &error)) 73 return error; 74 75 if (sc->ip->i_ino == ino) 76 spc->nlink++; 77 78 if (xchk_should_terminate(spc->sc, &error)) 79 return error; 80 81 return 0; 82 } 83 84 /* 85 * Try to lock a parent directory for checking dirents. Returns the inode 86 * flags for the locks we now hold, or zero if we failed. 87 */ 88 STATIC unsigned int 89 xchk_parent_ilock_dir( 90 struct xfs_inode *dp) 91 { 92 if (!xfs_ilock_nowait(dp, XFS_ILOCK_SHARED)) 93 return 0; 94 95 if (!xfs_need_iread_extents(&dp->i_df)) 96 return XFS_ILOCK_SHARED; 97 98 xfs_iunlock(dp, XFS_ILOCK_SHARED); 99 100 if (!xfs_ilock_nowait(dp, XFS_ILOCK_EXCL)) 101 return 0; 102 103 return XFS_ILOCK_EXCL; 104 } 105 106 /* 107 * Given the inode number of the alleged parent of the inode being scrubbed, 108 * try to validate that the parent has exactly one directory entry pointing 109 * back to the inode being scrubbed. Returns -EAGAIN if we need to revalidate 110 * the dotdot entry. 111 */ 112 STATIC int 113 xchk_parent_validate( 114 struct xfs_scrub *sc, 115 xfs_ino_t parent_ino) 116 { 117 struct xchk_parent_ctx spc = { 118 .sc = sc, 119 .nlink = 0, 120 }; 121 struct xfs_mount *mp = sc->mp; 122 struct xfs_inode *dp = NULL; 123 xfs_nlink_t expected_nlink; 124 unsigned int lock_mode; 125 int error = 0; 126 127 /* Is this the root dir? Then '..' must point to itself. */ 128 if (sc->ip == mp->m_rootip) { 129 if (sc->ip->i_ino != mp->m_sb.sb_rootino || 130 sc->ip->i_ino != parent_ino) 131 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); 132 return 0; 133 } 134 135 /* '..' must not point to ourselves. */ 136 if (sc->ip->i_ino == parent_ino) { 137 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); 138 return 0; 139 } 140 141 /* 142 * If we're an unlinked directory, the parent /won't/ have a link 143 * to us. Otherwise, it should have one link. 144 */ 145 expected_nlink = VFS_I(sc->ip)->i_nlink == 0 ? 0 : 1; 146 147 /* 148 * Grab the parent directory inode. This must be released before we 149 * cancel the scrub transaction. 150 * 151 * If _iget returns -EINVAL or -ENOENT then the parent inode number is 152 * garbage and the directory is corrupt. If the _iget returns 153 * -EFSCORRUPTED or -EFSBADCRC then the parent is corrupt which is a 154 * cross referencing error. Any other error is an operational error. 155 */ 156 error = xchk_iget(sc, parent_ino, &dp); 157 if (error == -EINVAL || error == -ENOENT) { 158 error = -EFSCORRUPTED; 159 xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error); 160 return error; 161 } 162 if (!xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, 0, &error)) 163 return error; 164 if (dp == sc->ip || xrep_is_tempfile(dp) || 165 !S_ISDIR(VFS_I(dp)->i_mode)) { 166 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); 167 goto out_rele; 168 } 169 170 lock_mode = xchk_parent_ilock_dir(dp); 171 if (!lock_mode) { 172 xchk_iunlock(sc, XFS_ILOCK_EXCL); 173 xchk_ilock(sc, XFS_ILOCK_EXCL); 174 error = -EAGAIN; 175 goto out_rele; 176 } 177 178 /* 179 * We cannot yet validate this parent pointer if the directory looks as 180 * though it has been zapped by the inode record repair code. 181 */ 182 if (xchk_dir_looks_zapped(dp)) { 183 error = -EBUSY; 184 xchk_set_incomplete(sc); 185 goto out_unlock; 186 } 187 188 /* Look for a directory entry in the parent pointing to the child. */ 189 error = xchk_dir_walk(sc, dp, xchk_parent_actor, &spc); 190 if (!xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, 0, &error)) 191 goto out_unlock; 192 193 /* 194 * Ensure that the parent has as many links to the child as the child 195 * thinks it has to the parent. 196 */ 197 if (spc.nlink != expected_nlink) 198 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); 199 200 out_unlock: 201 xfs_iunlock(dp, lock_mode); 202 out_rele: 203 xchk_irele(sc, dp); 204 return error; 205 } 206 207 /* 208 * Checking of Parent Pointers 209 * =========================== 210 * 211 * On filesystems with directory parent pointers, we check the referential 212 * integrity by visiting each parent pointer of a child file and checking that 213 * the directory referenced by the pointer actually has a dirent pointing 214 * forward to the child file. 215 */ 216 217 /* Deferred parent pointer entry that we saved for later. */ 218 struct xchk_pptr { 219 /* Cookie for retrieval of the pptr name. */ 220 xfblob_cookie name_cookie; 221 222 /* Parent pointer record. */ 223 struct xfs_parent_rec pptr_rec; 224 225 /* Length of the pptr name. */ 226 uint8_t namelen; 227 }; 228 229 struct xchk_pptrs { 230 struct xfs_scrub *sc; 231 232 /* How many parent pointers did we find at the end? */ 233 unsigned long long pptrs_found; 234 235 /* Parent of this directory. */ 236 xfs_ino_t parent_ino; 237 238 /* Fixed-size array of xchk_pptr structures. */ 239 struct xfarray *pptr_entries; 240 241 /* Blobs containing parent pointer names. */ 242 struct xfblob *pptr_names; 243 244 /* Scratch buffer for scanning pptr xattrs */ 245 struct xfs_da_args pptr_args; 246 247 /* If we've cycled the ILOCK, we must revalidate all deferred pptrs. */ 248 bool need_revalidate; 249 250 /* Name buffer */ 251 struct xfs_name xname; 252 char namebuf[MAXNAMELEN]; 253 }; 254 255 /* Does this parent pointer match the dotdot entry? */ 256 STATIC int 257 xchk_parent_scan_dotdot( 258 struct xfs_scrub *sc, 259 struct xfs_inode *ip, 260 unsigned int attr_flags, 261 const unsigned char *name, 262 unsigned int namelen, 263 const void *value, 264 unsigned int valuelen, 265 void *priv) 266 { 267 struct xchk_pptrs *pp = priv; 268 xfs_ino_t parent_ino; 269 int error; 270 271 if (!(attr_flags & XFS_ATTR_PARENT)) 272 return 0; 273 274 error = xfs_parent_from_attr(sc->mp, attr_flags, name, namelen, value, 275 valuelen, &parent_ino, NULL); 276 if (error) 277 return error; 278 279 if (pp->parent_ino == parent_ino) 280 return -ECANCELED; 281 282 return 0; 283 } 284 285 /* Look up the dotdot entry so that we can check it as we walk the pptrs. */ 286 STATIC int 287 xchk_parent_pptr_and_dotdot( 288 struct xchk_pptrs *pp) 289 { 290 struct xfs_scrub *sc = pp->sc; 291 int error; 292 293 /* Look up '..' */ 294 error = xchk_dir_lookup(sc, sc->ip, &xfs_name_dotdot, &pp->parent_ino); 295 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error)) 296 return error; 297 if (!xfs_verify_dir_ino(sc->mp, pp->parent_ino)) { 298 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); 299 return 0; 300 } 301 302 /* Is this the root dir? Then '..' must point to itself. */ 303 if (sc->ip == sc->mp->m_rootip) { 304 if (sc->ip->i_ino != pp->parent_ino) 305 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); 306 return 0; 307 } 308 309 /* 310 * If this is now an unlinked directory, the dotdot value is 311 * meaningless as long as it points to a valid inode. 312 */ 313 if (VFS_I(sc->ip)->i_nlink == 0) 314 return 0; 315 316 if (pp->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 317 return 0; 318 319 /* Otherwise, walk the pptrs again, and check. */ 320 error = xchk_xattr_walk(sc, sc->ip, xchk_parent_scan_dotdot, NULL, pp); 321 if (error == -ECANCELED) { 322 /* Found a parent pointer that matches dotdot. */ 323 return 0; 324 } 325 if (!error || error == -EFSCORRUPTED) { 326 /* Found a broken parent pointer or no match. */ 327 xchk_fblock_set_corrupt(sc, XFS_ATTR_FORK, 0); 328 return 0; 329 } 330 return error; 331 } 332 333 /* 334 * Try to lock a parent directory for checking dirents. Returns the inode 335 * flags for the locks we now hold, or zero if we failed. 336 */ 337 STATIC unsigned int 338 xchk_parent_lock_dir( 339 struct xfs_scrub *sc, 340 struct xfs_inode *dp) 341 { 342 if (!xfs_ilock_nowait(dp, XFS_IOLOCK_SHARED)) 343 return 0; 344 345 if (!xfs_ilock_nowait(dp, XFS_ILOCK_SHARED)) { 346 xfs_iunlock(dp, XFS_IOLOCK_SHARED); 347 return 0; 348 } 349 350 if (!xfs_need_iread_extents(&dp->i_df)) 351 return XFS_IOLOCK_SHARED | XFS_ILOCK_SHARED; 352 353 xfs_iunlock(dp, XFS_ILOCK_SHARED); 354 355 if (!xfs_ilock_nowait(dp, XFS_ILOCK_EXCL)) { 356 xfs_iunlock(dp, XFS_IOLOCK_SHARED); 357 return 0; 358 } 359 360 return XFS_IOLOCK_SHARED | XFS_ILOCK_EXCL; 361 } 362 363 /* Check the forward link (dirent) associated with this parent pointer. */ 364 STATIC int 365 xchk_parent_dirent( 366 struct xchk_pptrs *pp, 367 const struct xfs_name *xname, 368 struct xfs_inode *dp) 369 { 370 struct xfs_scrub *sc = pp->sc; 371 xfs_ino_t child_ino; 372 int error; 373 374 /* 375 * Use the name attached to this parent pointer to look up the 376 * directory entry in the alleged parent. 377 */ 378 error = xchk_dir_lookup(sc, dp, xname, &child_ino); 379 if (error == -ENOENT) { 380 xchk_fblock_xref_set_corrupt(sc, XFS_ATTR_FORK, 0); 381 return 0; 382 } 383 if (!xchk_fblock_xref_process_error(sc, XFS_ATTR_FORK, 0, &error)) 384 return error; 385 386 /* Does the inode number match? */ 387 if (child_ino != sc->ip->i_ino) { 388 xchk_fblock_xref_set_corrupt(sc, XFS_ATTR_FORK, 0); 389 return 0; 390 } 391 392 return 0; 393 } 394 395 /* Try to grab a parent directory. */ 396 STATIC int 397 xchk_parent_iget( 398 struct xchk_pptrs *pp, 399 const struct xfs_parent_rec *pptr, 400 struct xfs_inode **dpp) 401 { 402 struct xfs_scrub *sc = pp->sc; 403 struct xfs_inode *ip; 404 xfs_ino_t parent_ino = be64_to_cpu(pptr->p_ino); 405 int error; 406 407 /* Validate inode number. */ 408 error = xfs_dir_ino_validate(sc->mp, parent_ino); 409 if (error) { 410 xchk_fblock_set_corrupt(sc, XFS_ATTR_FORK, 0); 411 return -ECANCELED; 412 } 413 414 error = xchk_iget(sc, parent_ino, &ip); 415 if (error == -EINVAL || error == -ENOENT) { 416 xchk_fblock_set_corrupt(sc, XFS_ATTR_FORK, 0); 417 return -ECANCELED; 418 } 419 if (!xchk_fblock_xref_process_error(sc, XFS_ATTR_FORK, 0, &error)) 420 return error; 421 422 /* The parent must be a directory. */ 423 if (!S_ISDIR(VFS_I(ip)->i_mode)) { 424 xchk_fblock_xref_set_corrupt(sc, XFS_ATTR_FORK, 0); 425 goto out_rele; 426 } 427 428 /* Validate generation number. */ 429 if (VFS_I(ip)->i_generation != be32_to_cpu(pptr->p_gen)) { 430 xchk_fblock_xref_set_corrupt(sc, XFS_ATTR_FORK, 0); 431 goto out_rele; 432 } 433 434 *dpp = ip; 435 return 0; 436 out_rele: 437 xchk_irele(sc, ip); 438 return 0; 439 } 440 441 /* 442 * Walk an xattr of a file. If this xattr is a parent pointer, follow it up 443 * to a parent directory and check that the parent has a dirent pointing back 444 * to us. 445 */ 446 STATIC int 447 xchk_parent_scan_attr( 448 struct xfs_scrub *sc, 449 struct xfs_inode *ip, 450 unsigned int attr_flags, 451 const unsigned char *name, 452 unsigned int namelen, 453 const void *value, 454 unsigned int valuelen, 455 void *priv) 456 { 457 struct xfs_name xname = { 458 .name = name, 459 .len = namelen, 460 }; 461 struct xchk_pptrs *pp = priv; 462 struct xfs_inode *dp = NULL; 463 const struct xfs_parent_rec *pptr_rec = value; 464 xfs_ino_t parent_ino; 465 unsigned int lockmode; 466 int error; 467 468 if (!(attr_flags & XFS_ATTR_PARENT)) 469 return 0; 470 471 error = xfs_parent_from_attr(sc->mp, attr_flags, name, namelen, value, 472 valuelen, &parent_ino, NULL); 473 if (error) { 474 xchk_fblock_set_corrupt(sc, XFS_ATTR_FORK, 0); 475 return error; 476 } 477 478 /* No self-referential parent pointers. */ 479 if (parent_ino == sc->ip->i_ino) { 480 xchk_fblock_set_corrupt(sc, XFS_ATTR_FORK, 0); 481 return -ECANCELED; 482 } 483 484 pp->pptrs_found++; 485 486 error = xchk_parent_iget(pp, pptr_rec, &dp); 487 if (error) 488 return error; 489 if (!dp) 490 return 0; 491 492 /* Try to lock the inode. */ 493 lockmode = xchk_parent_lock_dir(sc, dp); 494 if (!lockmode) { 495 struct xchk_pptr save_pp = { 496 .pptr_rec = *pptr_rec, /* struct copy */ 497 .namelen = namelen, 498 }; 499 500 /* Couldn't lock the inode, so save the pptr for later. */ 501 trace_xchk_parent_defer(sc->ip, &xname, dp->i_ino); 502 503 error = xfblob_storename(pp->pptr_names, &save_pp.name_cookie, 504 &xname); 505 if (!xchk_fblock_xref_process_error(sc, XFS_ATTR_FORK, 0, 506 &error)) 507 goto out_rele; 508 509 error = xfarray_append(pp->pptr_entries, &save_pp); 510 if (!xchk_fblock_xref_process_error(sc, XFS_ATTR_FORK, 0, 511 &error)) 512 goto out_rele; 513 514 goto out_rele; 515 } 516 517 error = xchk_parent_dirent(pp, &xname, dp); 518 if (error) 519 goto out_unlock; 520 521 out_unlock: 522 xfs_iunlock(dp, lockmode); 523 out_rele: 524 xchk_irele(sc, dp); 525 return error; 526 } 527 528 /* 529 * Revalidate a parent pointer that we collected in the past but couldn't check 530 * because of lock contention. Returns 0 if the parent pointer is still valid, 531 * -ENOENT if it has gone away on us, or a negative errno. 532 */ 533 STATIC int 534 xchk_parent_revalidate_pptr( 535 struct xchk_pptrs *pp, 536 const struct xfs_name *xname, 537 struct xfs_parent_rec *pptr) 538 { 539 struct xfs_scrub *sc = pp->sc; 540 int error; 541 542 error = xfs_parent_lookup(sc->tp, sc->ip, xname, pptr, &pp->pptr_args); 543 if (error == -ENOATTR) { 544 /* Parent pointer went away, nothing to revalidate. */ 545 return -ENOENT; 546 } 547 548 return error; 549 } 550 551 /* 552 * Check a parent pointer the slow way, which means we cycle locks a bunch 553 * and put up with revalidation until we get it done. 554 */ 555 STATIC int 556 xchk_parent_slow_pptr( 557 struct xchk_pptrs *pp, 558 const struct xfs_name *xname, 559 struct xfs_parent_rec *pptr) 560 { 561 struct xfs_scrub *sc = pp->sc; 562 struct xfs_inode *dp = NULL; 563 unsigned int lockmode; 564 int error; 565 566 /* Check that the deferred parent pointer still exists. */ 567 if (pp->need_revalidate) { 568 error = xchk_parent_revalidate_pptr(pp, xname, pptr); 569 if (error == -ENOENT) 570 return 0; 571 if (!xchk_fblock_xref_process_error(sc, XFS_ATTR_FORK, 0, 572 &error)) 573 return error; 574 } 575 576 error = xchk_parent_iget(pp, pptr, &dp); 577 if (error) 578 return error; 579 if (!dp) 580 return 0; 581 582 /* 583 * If we can grab both IOLOCK and ILOCK of the alleged parent, we 584 * can proceed with the validation. 585 */ 586 lockmode = xchk_parent_lock_dir(sc, dp); 587 if (lockmode) { 588 trace_xchk_parent_slowpath(sc->ip, xname, dp->i_ino); 589 goto check_dirent; 590 } 591 592 /* 593 * We couldn't lock the parent dir. Drop all the locks and try to 594 * get them again, one at a time. 595 */ 596 xchk_iunlock(sc, sc->ilock_flags); 597 pp->need_revalidate = true; 598 599 trace_xchk_parent_ultraslowpath(sc->ip, xname, dp->i_ino); 600 601 error = xchk_dir_trylock_for_pptrs(sc, dp, &lockmode); 602 if (error) 603 goto out_rele; 604 605 /* Revalidate the parent pointer now that we cycled locks. */ 606 error = xchk_parent_revalidate_pptr(pp, xname, pptr); 607 if (error == -ENOENT) { 608 error = 0; 609 goto out_unlock; 610 } 611 if (!xchk_fblock_xref_process_error(sc, XFS_ATTR_FORK, 0, &error)) 612 goto out_unlock; 613 614 check_dirent: 615 error = xchk_parent_dirent(pp, xname, dp); 616 out_unlock: 617 xfs_iunlock(dp, lockmode); 618 out_rele: 619 xchk_irele(sc, dp); 620 return error; 621 } 622 623 /* Check all the parent pointers that we deferred the first time around. */ 624 STATIC int 625 xchk_parent_finish_slow_pptrs( 626 struct xchk_pptrs *pp) 627 { 628 xfarray_idx_t array_cur; 629 int error; 630 631 foreach_xfarray_idx(pp->pptr_entries, array_cur) { 632 struct xchk_pptr pptr; 633 634 if (pp->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 635 return 0; 636 637 error = xfarray_load(pp->pptr_entries, array_cur, &pptr); 638 if (error) 639 return error; 640 641 error = xfblob_loadname(pp->pptr_names, pptr.name_cookie, 642 &pp->xname, pptr.namelen); 643 if (error) 644 return error; 645 646 error = xchk_parent_slow_pptr(pp, &pp->xname, &pptr.pptr_rec); 647 if (error) 648 return error; 649 } 650 651 /* Empty out both xfiles now that we've checked everything. */ 652 xfarray_truncate(pp->pptr_entries); 653 xfblob_truncate(pp->pptr_names); 654 return 0; 655 } 656 657 /* Count the number of parent pointers. */ 658 STATIC int 659 xchk_parent_count_pptr( 660 struct xfs_scrub *sc, 661 struct xfs_inode *ip, 662 unsigned int attr_flags, 663 const unsigned char *name, 664 unsigned int namelen, 665 const void *value, 666 unsigned int valuelen, 667 void *priv) 668 { 669 struct xchk_pptrs *pp = priv; 670 int error; 671 672 if (!(attr_flags & XFS_ATTR_PARENT)) 673 return 0; 674 675 error = xfs_parent_from_attr(sc->mp, attr_flags, name, namelen, value, 676 valuelen, NULL, NULL); 677 if (error) 678 return error; 679 680 pp->pptrs_found++; 681 return 0; 682 } 683 684 /* 685 * Compare the number of parent pointers to the link count. For 686 * non-directories these should be the same. For unlinked directories the 687 * count should be zero; for linked directories, it should be nonzero. 688 */ 689 STATIC int 690 xchk_parent_count_pptrs( 691 struct xchk_pptrs *pp) 692 { 693 struct xfs_scrub *sc = pp->sc; 694 int error; 695 696 /* 697 * If we cycled the ILOCK while cross-checking parent pointers with 698 * dirents, then we need to recalculate the number of parent pointers. 699 */ 700 if (pp->need_revalidate) { 701 pp->pptrs_found = 0; 702 error = xchk_xattr_walk(sc, sc->ip, xchk_parent_count_pptr, 703 NULL, pp); 704 if (error == -EFSCORRUPTED) { 705 /* Found a bad parent pointer */ 706 xchk_fblock_set_corrupt(sc, XFS_ATTR_FORK, 0); 707 return 0; 708 } 709 if (error) 710 return error; 711 } 712 713 if (S_ISDIR(VFS_I(sc->ip)->i_mode)) { 714 if (sc->ip == sc->mp->m_rootip) 715 pp->pptrs_found++; 716 717 if (VFS_I(sc->ip)->i_nlink == 0 && pp->pptrs_found > 0) 718 xchk_ino_set_corrupt(sc, sc->ip->i_ino); 719 else if (VFS_I(sc->ip)->i_nlink > 0 && 720 pp->pptrs_found == 0) 721 xchk_ino_set_corrupt(sc, sc->ip->i_ino); 722 } else { 723 if (VFS_I(sc->ip)->i_nlink != pp->pptrs_found) 724 xchk_ino_set_corrupt(sc, sc->ip->i_ino); 725 } 726 727 return 0; 728 } 729 730 /* Check parent pointers of a file. */ 731 STATIC int 732 xchk_parent_pptr( 733 struct xfs_scrub *sc) 734 { 735 struct xchk_pptrs *pp; 736 char *descr; 737 int error; 738 739 pp = kvzalloc(sizeof(struct xchk_pptrs), XCHK_GFP_FLAGS); 740 if (!pp) 741 return -ENOMEM; 742 pp->sc = sc; 743 pp->xname.name = pp->namebuf; 744 745 /* 746 * Set up some staging memory for parent pointers that we can't check 747 * due to locking contention. 748 */ 749 descr = xchk_xfile_ino_descr(sc, "slow parent pointer entries"); 750 error = xfarray_create(descr, 0, sizeof(struct xchk_pptr), 751 &pp->pptr_entries); 752 kfree(descr); 753 if (error) 754 goto out_pp; 755 756 descr = xchk_xfile_ino_descr(sc, "slow parent pointer names"); 757 error = xfblob_create(descr, &pp->pptr_names); 758 kfree(descr); 759 if (error) 760 goto out_entries; 761 762 error = xchk_xattr_walk(sc, sc->ip, xchk_parent_scan_attr, NULL, pp); 763 if (error == -ECANCELED) { 764 error = 0; 765 goto out_names; 766 } 767 if (error) 768 goto out_names; 769 770 error = xchk_parent_finish_slow_pptrs(pp); 771 if (error == -ETIMEDOUT) { 772 /* Couldn't grab a lock, scrub was marked incomplete */ 773 error = 0; 774 goto out_names; 775 } 776 if (error) 777 goto out_names; 778 779 if (pp->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 780 goto out_names; 781 782 /* 783 * For subdirectories, make sure the dotdot entry references the same 784 * inode as the parent pointers. 785 * 786 * If we're scanning a /consistent/ directory, there should only be 787 * one parent pointer, and it should point to the same directory as 788 * the dotdot entry. 789 * 790 * However, a corrupt directory tree might feature a subdirectory with 791 * multiple parents. The directory loop scanner is responsible for 792 * correcting that kind of problem, so for now we only validate that 793 * the dotdot entry matches /one/ of the parents. 794 */ 795 if (S_ISDIR(VFS_I(sc->ip)->i_mode)) { 796 error = xchk_parent_pptr_and_dotdot(pp); 797 if (error) 798 goto out_names; 799 } 800 801 if (pp->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 802 goto out_names; 803 804 /* 805 * Complain if the number of parent pointers doesn't match the link 806 * count. This could be a sign of missing parent pointers (or an 807 * incorrect link count). 808 */ 809 error = xchk_parent_count_pptrs(pp); 810 if (error) 811 goto out_names; 812 813 out_names: 814 xfblob_destroy(pp->pptr_names); 815 out_entries: 816 xfarray_destroy(pp->pptr_entries); 817 out_pp: 818 kvfree(pp); 819 return error; 820 } 821 822 /* Scrub a parent pointer. */ 823 int 824 xchk_parent( 825 struct xfs_scrub *sc) 826 { 827 struct xfs_mount *mp = sc->mp; 828 xfs_ino_t parent_ino; 829 int error = 0; 830 831 if (xfs_has_parent(mp)) 832 return xchk_parent_pptr(sc); 833 834 /* 835 * If we're a directory, check that the '..' link points up to 836 * a directory that has one entry pointing to us. 837 */ 838 if (!S_ISDIR(VFS_I(sc->ip)->i_mode)) 839 return -ENOENT; 840 841 /* We're not a special inode, are we? */ 842 if (!xfs_verify_dir_ino(mp, sc->ip->i_ino)) { 843 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); 844 return 0; 845 } 846 847 do { 848 if (xchk_should_terminate(sc, &error)) 849 break; 850 851 /* Look up '..' */ 852 error = xchk_dir_lookup(sc, sc->ip, &xfs_name_dotdot, 853 &parent_ino); 854 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error)) 855 return error; 856 if (!xfs_verify_dir_ino(mp, parent_ino)) { 857 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); 858 return 0; 859 } 860 861 /* 862 * Check that the dotdot entry points to a parent directory 863 * containing a dirent pointing to this subdirectory. 864 */ 865 error = xchk_parent_validate(sc, parent_ino); 866 } while (error == -EAGAIN); 867 if (error == -EBUSY) { 868 /* 869 * We could not scan a directory, so we marked the check 870 * incomplete. No further error return is necessary. 871 */ 872 return 0; 873 } 874 875 return error; 876 } 877 878 /* 879 * Decide if this file's extended attributes (and therefore its parent 880 * pointers) have been zapped to satisfy the inode and ifork verifiers. 881 * Checking and repairing should be postponed until the extended attribute 882 * structure is fixed. 883 */ 884 bool 885 xchk_pptr_looks_zapped( 886 struct xfs_inode *ip) 887 { 888 struct xfs_mount *mp = ip->i_mount; 889 struct inode *inode = VFS_I(ip); 890 891 ASSERT(xfs_has_parent(mp)); 892 893 /* 894 * Temporary files that cannot be linked into the directory tree do not 895 * have attr forks because they cannot ever have parents. 896 */ 897 if (inode->i_nlink == 0 && !(inode->i_state & I_LINKABLE)) 898 return false; 899 900 /* 901 * Directory tree roots do not have parents, so the expected outcome 902 * of a parent pointer scan is always the empty set. It's safe to scan 903 * them even if the attr fork was zapped. 904 */ 905 if (ip == mp->m_rootip) 906 return false; 907 908 /* 909 * Metadata inodes are all rooted in the superblock and do not have 910 * any parents. Hence the attr fork will not be initialized, but 911 * there are no parent pointers that might have been zapped. 912 */ 913 if (xfs_is_metadata_inode(ip)) 914 return false; 915 916 /* 917 * Linked and linkable non-rootdir files should always have an 918 * attribute fork because that is where parent pointers are 919 * stored. If the fork is absent, something is amiss. 920 */ 921 if (!xfs_inode_has_attr_fork(ip)) 922 return true; 923 924 /* Repair zapped this file's attr fork a short time ago */ 925 if (xfs_ifork_zapped(ip, XFS_ATTR_FORK)) 926 return true; 927 928 /* 929 * If the dinode repair found a bad attr fork, it will reset the fork 930 * to extents format with zero records and wait for the bmapbta 931 * scrubber to reconstruct the block mappings. The extended attribute 932 * structure always contain some content when parent pointers are 933 * enabled, so this is a clear sign of a zapped attr fork. 934 */ 935 return ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS && 936 ip->i_af.if_nextents == 0; 937 } 938
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.