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_ag.h" 16 #include "xfs_inode.h" 17 #include "xfs_ialloc.h" 18 #include "xfs_icache.h" 19 #include "xfs_da_format.h" 20 #include "xfs_reflink.h" 21 #include "xfs_rmap.h" 22 #include "xfs_bmap_util.h" 23 #include "scrub/scrub.h" 24 #include "scrub/common.h" 25 #include "scrub/btree.h" 26 #include "scrub/trace.h" 27 28 /* Prepare the attached inode for scrubbing. */ 29 static inline int 30 xchk_prepare_iscrub( 31 struct xfs_scrub *sc) 32 { 33 int error; 34 35 xchk_ilock(sc, XFS_IOLOCK_EXCL); 36 37 error = xchk_trans_alloc(sc, 0); 38 if (error) 39 return error; 40 41 xchk_ilock(sc, XFS_ILOCK_EXCL); 42 return 0; 43 } 44 45 /* Install this scrub-by-handle inode and prepare it for scrubbing. */ 46 static inline int 47 xchk_install_handle_iscrub( 48 struct xfs_scrub *sc, 49 struct xfs_inode *ip) 50 { 51 int error; 52 53 error = xchk_install_handle_inode(sc, ip); 54 if (error) 55 return error; 56 57 return xchk_prepare_iscrub(sc); 58 } 59 60 /* 61 * Grab total control of the inode metadata. In the best case, we grab the 62 * incore inode and take all locks on it. If the incore inode cannot be 63 * constructed due to corruption problems, lock the AGI so that we can single 64 * step the loading process to fix everything that can go wrong. 65 */ 66 int 67 xchk_setup_inode( 68 struct xfs_scrub *sc) 69 { 70 struct xfs_imap imap; 71 struct xfs_inode *ip; 72 struct xfs_mount *mp = sc->mp; 73 struct xfs_inode *ip_in = XFS_I(file_inode(sc->file)); 74 struct xfs_buf *agi_bp; 75 struct xfs_perag *pag; 76 xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, sc->sm->sm_ino); 77 int error; 78 79 if (xchk_need_intent_drain(sc)) 80 xchk_fsgates_enable(sc, XCHK_FSGATES_DRAIN); 81 82 /* We want to scan the opened inode, so lock it and exit. */ 83 if (sc->sm->sm_ino == 0 || sc->sm->sm_ino == ip_in->i_ino) { 84 error = xchk_install_live_inode(sc, ip_in); 85 if (error) 86 return error; 87 88 return xchk_prepare_iscrub(sc); 89 } 90 91 /* Reject internal metadata files and obviously bad inode numbers. */ 92 if (xfs_internal_inum(mp, sc->sm->sm_ino)) 93 return -ENOENT; 94 if (!xfs_verify_ino(sc->mp, sc->sm->sm_ino)) 95 return -ENOENT; 96 97 /* Try a safe untrusted iget. */ 98 error = xchk_iget_safe(sc, sc->sm->sm_ino, &ip); 99 if (!error) 100 return xchk_install_handle_iscrub(sc, ip); 101 if (error == -ENOENT) 102 return error; 103 if (error != -EFSCORRUPTED && error != -EFSBADCRC && error != -EINVAL) 104 goto out_error; 105 106 /* 107 * EINVAL with IGET_UNTRUSTED probably means one of several things: 108 * userspace gave us an inode number that doesn't correspond to fs 109 * space; the inode btree lacks a record for this inode; or there is 110 * a record, and it says this inode is free. 111 * 112 * EFSCORRUPTED/EFSBADCRC could mean that the inode was mappable, but 113 * some other metadata corruption (e.g. inode forks) prevented 114 * instantiation of the incore inode. Or it could mean the inobt is 115 * corrupt. 116 * 117 * We want to look up this inode in the inobt directly to distinguish 118 * three different scenarios: (1) the inobt says the inode is free, 119 * in which case there's nothing to do; (2) the inobt is corrupt so we 120 * should flag the corruption and exit to userspace to let it fix the 121 * inobt; and (3) the inobt says the inode is allocated, but loading it 122 * failed due to corruption. 123 * 124 * Allocate a transaction and grab the AGI to prevent inobt activity in 125 * this AG. Retry the iget in case someone allocated a new inode after 126 * the first iget failed. 127 */ 128 error = xchk_trans_alloc(sc, 0); 129 if (error) 130 goto out_error; 131 132 error = xchk_iget_agi(sc, sc->sm->sm_ino, &agi_bp, &ip); 133 if (error == 0) { 134 /* Actually got the incore inode, so install it and proceed. */ 135 xchk_trans_cancel(sc); 136 return xchk_install_handle_iscrub(sc, ip); 137 } 138 if (error == -ENOENT) 139 goto out_gone; 140 if (error != -EFSCORRUPTED && error != -EFSBADCRC && error != -EINVAL) 141 goto out_cancel; 142 143 /* Ensure that we have protected against inode allocation/freeing. */ 144 if (agi_bp == NULL) { 145 ASSERT(agi_bp != NULL); 146 error = -ECANCELED; 147 goto out_cancel; 148 } 149 150 /* 151 * Untrusted iget failed a second time. Let's try an inobt lookup. 152 * If the inobt doesn't think this is an allocated inode then we'll 153 * return ENOENT to signal that the check can be skipped. 154 * 155 * If the lookup signals corruption, we'll mark this inode corrupt and 156 * exit to userspace. There's little chance of fixing anything until 157 * the inobt is straightened out, but there's nothing we can do here. 158 * 159 * If the lookup encounters a runtime error, exit to userspace. 160 */ 161 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, sc->sm->sm_ino)); 162 if (!pag) { 163 error = -EFSCORRUPTED; 164 goto out_cancel; 165 } 166 167 error = xfs_imap(pag, sc->tp, sc->sm->sm_ino, &imap, 168 XFS_IGET_UNTRUSTED); 169 xfs_perag_put(pag); 170 if (error == -EINVAL || error == -ENOENT) 171 goto out_gone; 172 if (error) 173 goto out_cancel; 174 175 /* 176 * The lookup succeeded. Chances are the ondisk inode is corrupt and 177 * preventing iget from reading it. Retain the scrub transaction and 178 * the AGI buffer to prevent anyone from allocating or freeing inodes. 179 * This ensures that we preserve the inconsistency between the inobt 180 * saying the inode is allocated and the icache being unable to load 181 * the inode until we can flag the corruption in xchk_inode. The 182 * scrub function has to note the corruption, since we're not really 183 * supposed to do that from the setup function. 184 */ 185 return 0; 186 187 out_cancel: 188 xchk_trans_cancel(sc); 189 out_error: 190 trace_xchk_op_error(sc, agno, XFS_INO_TO_AGBNO(mp, sc->sm->sm_ino), 191 error, __return_address); 192 return error; 193 out_gone: 194 /* The file is gone, so there's nothing to check. */ 195 xchk_trans_cancel(sc); 196 return -ENOENT; 197 } 198 199 /* Inode core */ 200 201 /* Validate di_extsize hint. */ 202 STATIC void 203 xchk_inode_extsize( 204 struct xfs_scrub *sc, 205 struct xfs_dinode *dip, 206 xfs_ino_t ino, 207 uint16_t mode, 208 uint16_t flags) 209 { 210 xfs_failaddr_t fa; 211 uint32_t value = be32_to_cpu(dip->di_extsize); 212 213 fa = xfs_inode_validate_extsize(sc->mp, value, mode, flags); 214 if (fa) 215 xchk_ino_set_corrupt(sc, ino); 216 217 /* 218 * XFS allows a sysadmin to change the rt extent size when adding a rt 219 * section to a filesystem after formatting. If there are any 220 * directories with extszinherit and rtinherit set, the hint could 221 * become misaligned with the new rextsize. The verifier doesn't check 222 * this, because we allow rtinherit directories even without an rt 223 * device. Flag this as an administrative warning since we will clean 224 * this up eventually. 225 */ 226 if ((flags & XFS_DIFLAG_RTINHERIT) && 227 (flags & XFS_DIFLAG_EXTSZINHERIT) && 228 value % sc->mp->m_sb.sb_rextsize > 0) 229 xchk_ino_set_warning(sc, ino); 230 } 231 232 /* 233 * Validate di_cowextsize hint. 234 * 235 * The rules are documented at xfs_ioctl_setattr_check_cowextsize(). 236 * These functions must be kept in sync with each other. 237 */ 238 STATIC void 239 xchk_inode_cowextsize( 240 struct xfs_scrub *sc, 241 struct xfs_dinode *dip, 242 xfs_ino_t ino, 243 uint16_t mode, 244 uint16_t flags, 245 uint64_t flags2) 246 { 247 xfs_failaddr_t fa; 248 249 fa = xfs_inode_validate_cowextsize(sc->mp, 250 be32_to_cpu(dip->di_cowextsize), mode, flags, 251 flags2); 252 if (fa) 253 xchk_ino_set_corrupt(sc, ino); 254 } 255 256 /* Make sure the di_flags make sense for the inode. */ 257 STATIC void 258 xchk_inode_flags( 259 struct xfs_scrub *sc, 260 struct xfs_dinode *dip, 261 xfs_ino_t ino, 262 uint16_t mode, 263 uint16_t flags) 264 { 265 struct xfs_mount *mp = sc->mp; 266 267 /* di_flags are all taken, last bit cannot be used */ 268 if (flags & ~XFS_DIFLAG_ANY) 269 goto bad; 270 271 /* rt flags require rt device */ 272 if ((flags & XFS_DIFLAG_REALTIME) && !mp->m_rtdev_targp) 273 goto bad; 274 275 /* new rt bitmap flag only valid for rbmino */ 276 if ((flags & XFS_DIFLAG_NEWRTBM) && ino != mp->m_sb.sb_rbmino) 277 goto bad; 278 279 /* directory-only flags */ 280 if ((flags & (XFS_DIFLAG_RTINHERIT | 281 XFS_DIFLAG_EXTSZINHERIT | 282 XFS_DIFLAG_PROJINHERIT | 283 XFS_DIFLAG_NOSYMLINKS)) && 284 !S_ISDIR(mode)) 285 goto bad; 286 287 /* file-only flags */ 288 if ((flags & (XFS_DIFLAG_REALTIME | FS_XFLAG_EXTSIZE)) && 289 !S_ISREG(mode)) 290 goto bad; 291 292 /* filestreams and rt make no sense */ 293 if ((flags & XFS_DIFLAG_FILESTREAM) && (flags & XFS_DIFLAG_REALTIME)) 294 goto bad; 295 296 return; 297 bad: 298 xchk_ino_set_corrupt(sc, ino); 299 } 300 301 /* Make sure the di_flags2 make sense for the inode. */ 302 STATIC void 303 xchk_inode_flags2( 304 struct xfs_scrub *sc, 305 struct xfs_dinode *dip, 306 xfs_ino_t ino, 307 uint16_t mode, 308 uint16_t flags, 309 uint64_t flags2) 310 { 311 struct xfs_mount *mp = sc->mp; 312 313 /* Unknown di_flags2 could be from a future kernel */ 314 if (flags2 & ~XFS_DIFLAG2_ANY) 315 xchk_ino_set_warning(sc, ino); 316 317 /* reflink flag requires reflink feature */ 318 if ((flags2 & XFS_DIFLAG2_REFLINK) && 319 !xfs_has_reflink(mp)) 320 goto bad; 321 322 /* cowextsize flag is checked w.r.t. mode separately */ 323 324 /* file/dir-only flags */ 325 if ((flags2 & XFS_DIFLAG2_DAX) && !(S_ISREG(mode) || S_ISDIR(mode))) 326 goto bad; 327 328 /* file-only flags */ 329 if ((flags2 & XFS_DIFLAG2_REFLINK) && !S_ISREG(mode)) 330 goto bad; 331 332 /* realtime and reflink make no sense, currently */ 333 if ((flags & XFS_DIFLAG_REALTIME) && (flags2 & XFS_DIFLAG2_REFLINK)) 334 goto bad; 335 336 /* no bigtime iflag without the bigtime feature */ 337 if (xfs_dinode_has_bigtime(dip) && !xfs_has_bigtime(mp)) 338 goto bad; 339 340 /* no large extent counts without the filesystem feature */ 341 if ((flags2 & XFS_DIFLAG2_NREXT64) && !xfs_has_large_extent_counts(mp)) 342 goto bad; 343 344 return; 345 bad: 346 xchk_ino_set_corrupt(sc, ino); 347 } 348 349 static inline void 350 xchk_dinode_nsec( 351 struct xfs_scrub *sc, 352 xfs_ino_t ino, 353 struct xfs_dinode *dip, 354 const xfs_timestamp_t ts) 355 { 356 struct timespec64 tv; 357 358 tv = xfs_inode_from_disk_ts(dip, ts); 359 if (tv.tv_nsec < 0 || tv.tv_nsec >= NSEC_PER_SEC) 360 xchk_ino_set_corrupt(sc, ino); 361 } 362 363 /* Scrub all the ondisk inode fields. */ 364 STATIC void 365 xchk_dinode( 366 struct xfs_scrub *sc, 367 struct xfs_dinode *dip, 368 xfs_ino_t ino) 369 { 370 struct xfs_mount *mp = sc->mp; 371 size_t fork_recs; 372 unsigned long long isize; 373 uint64_t flags2; 374 xfs_extnum_t nextents; 375 xfs_extnum_t naextents; 376 prid_t prid; 377 uint16_t flags; 378 uint16_t mode; 379 380 flags = be16_to_cpu(dip->di_flags); 381 if (dip->di_version >= 3) 382 flags2 = be64_to_cpu(dip->di_flags2); 383 else 384 flags2 = 0; 385 386 /* di_mode */ 387 mode = be16_to_cpu(dip->di_mode); 388 switch (mode & S_IFMT) { 389 case S_IFLNK: 390 case S_IFREG: 391 case S_IFDIR: 392 case S_IFCHR: 393 case S_IFBLK: 394 case S_IFIFO: 395 case S_IFSOCK: 396 /* mode is recognized */ 397 break; 398 default: 399 xchk_ino_set_corrupt(sc, ino); 400 break; 401 } 402 403 /* v1/v2 fields */ 404 switch (dip->di_version) { 405 case 1: 406 /* 407 * We autoconvert v1 inodes into v2 inodes on writeout, 408 * so just mark this inode for preening. 409 */ 410 xchk_ino_set_preen(sc, ino); 411 prid = 0; 412 break; 413 case 2: 414 case 3: 415 if (dip->di_onlink != 0) 416 xchk_ino_set_corrupt(sc, ino); 417 418 if (dip->di_mode == 0 && sc->ip) 419 xchk_ino_set_corrupt(sc, ino); 420 421 if (dip->di_projid_hi != 0 && 422 !xfs_has_projid32(mp)) 423 xchk_ino_set_corrupt(sc, ino); 424 425 prid = be16_to_cpu(dip->di_projid_lo); 426 break; 427 default: 428 xchk_ino_set_corrupt(sc, ino); 429 return; 430 } 431 432 if (xfs_has_projid32(mp)) 433 prid |= (prid_t)be16_to_cpu(dip->di_projid_hi) << 16; 434 435 /* 436 * di_uid/di_gid -- -1 isn't invalid, but there's no way that 437 * userspace could have created that. 438 */ 439 if (dip->di_uid == cpu_to_be32(-1U) || 440 dip->di_gid == cpu_to_be32(-1U)) 441 xchk_ino_set_warning(sc, ino); 442 443 /* 444 * project id of -1 isn't supposed to be valid, but the kernel didn't 445 * always validate that. 446 */ 447 if (prid == -1U) 448 xchk_ino_set_warning(sc, ino); 449 450 /* di_format */ 451 switch (dip->di_format) { 452 case XFS_DINODE_FMT_DEV: 453 if (!S_ISCHR(mode) && !S_ISBLK(mode) && 454 !S_ISFIFO(mode) && !S_ISSOCK(mode)) 455 xchk_ino_set_corrupt(sc, ino); 456 break; 457 case XFS_DINODE_FMT_LOCAL: 458 if (!S_ISDIR(mode) && !S_ISLNK(mode)) 459 xchk_ino_set_corrupt(sc, ino); 460 break; 461 case XFS_DINODE_FMT_EXTENTS: 462 if (!S_ISREG(mode) && !S_ISDIR(mode) && !S_ISLNK(mode)) 463 xchk_ino_set_corrupt(sc, ino); 464 break; 465 case XFS_DINODE_FMT_BTREE: 466 if (!S_ISREG(mode) && !S_ISDIR(mode)) 467 xchk_ino_set_corrupt(sc, ino); 468 break; 469 case XFS_DINODE_FMT_UUID: 470 default: 471 xchk_ino_set_corrupt(sc, ino); 472 break; 473 } 474 475 /* di_[amc]time.nsec */ 476 xchk_dinode_nsec(sc, ino, dip, dip->di_atime); 477 xchk_dinode_nsec(sc, ino, dip, dip->di_mtime); 478 xchk_dinode_nsec(sc, ino, dip, dip->di_ctime); 479 480 /* 481 * di_size. xfs_dinode_verify checks for things that screw up 482 * the VFS such as the upper bit being set and zero-length 483 * symlinks/directories, but we can do more here. 484 */ 485 isize = be64_to_cpu(dip->di_size); 486 if (isize & (1ULL << 63)) 487 xchk_ino_set_corrupt(sc, ino); 488 489 /* Devices, fifos, and sockets must have zero size */ 490 if (!S_ISDIR(mode) && !S_ISREG(mode) && !S_ISLNK(mode) && isize != 0) 491 xchk_ino_set_corrupt(sc, ino); 492 493 /* Directories can't be larger than the data section size (32G) */ 494 if (S_ISDIR(mode) && (isize == 0 || isize >= XFS_DIR2_SPACE_SIZE)) 495 xchk_ino_set_corrupt(sc, ino); 496 497 /* Symlinks can't be larger than SYMLINK_MAXLEN */ 498 if (S_ISLNK(mode) && (isize == 0 || isize >= XFS_SYMLINK_MAXLEN)) 499 xchk_ino_set_corrupt(sc, ino); 500 501 /* 502 * Warn if the running kernel can't handle the kinds of offsets 503 * needed to deal with the file size. In other words, if the 504 * pagecache can't cache all the blocks in this file due to 505 * overly large offsets, flag the inode for admin review. 506 */ 507 if (isize > mp->m_super->s_maxbytes) 508 xchk_ino_set_warning(sc, ino); 509 510 /* di_nblocks */ 511 if (flags2 & XFS_DIFLAG2_REFLINK) { 512 ; /* nblocks can exceed dblocks */ 513 } else if (flags & XFS_DIFLAG_REALTIME) { 514 /* 515 * nblocks is the sum of data extents (in the rtdev), 516 * attr extents (in the datadev), and both forks' bmbt 517 * blocks (in the datadev). This clumsy check is the 518 * best we can do without cross-referencing with the 519 * inode forks. 520 */ 521 if (be64_to_cpu(dip->di_nblocks) >= 522 mp->m_sb.sb_dblocks + mp->m_sb.sb_rblocks) 523 xchk_ino_set_corrupt(sc, ino); 524 } else { 525 if (be64_to_cpu(dip->di_nblocks) >= mp->m_sb.sb_dblocks) 526 xchk_ino_set_corrupt(sc, ino); 527 } 528 529 xchk_inode_flags(sc, dip, ino, mode, flags); 530 531 xchk_inode_extsize(sc, dip, ino, mode, flags); 532 533 nextents = xfs_dfork_data_extents(dip); 534 naextents = xfs_dfork_attr_extents(dip); 535 536 /* di_nextents */ 537 fork_recs = XFS_DFORK_DSIZE(dip, mp) / sizeof(struct xfs_bmbt_rec); 538 switch (dip->di_format) { 539 case XFS_DINODE_FMT_EXTENTS: 540 if (nextents > fork_recs) 541 xchk_ino_set_corrupt(sc, ino); 542 break; 543 case XFS_DINODE_FMT_BTREE: 544 if (nextents <= fork_recs) 545 xchk_ino_set_corrupt(sc, ino); 546 break; 547 default: 548 if (nextents != 0) 549 xchk_ino_set_corrupt(sc, ino); 550 break; 551 } 552 553 /* di_forkoff */ 554 if (XFS_DFORK_APTR(dip) >= (char *)dip + mp->m_sb.sb_inodesize) 555 xchk_ino_set_corrupt(sc, ino); 556 if (naextents != 0 && dip->di_forkoff == 0) 557 xchk_ino_set_corrupt(sc, ino); 558 if (dip->di_forkoff == 0 && dip->di_aformat != XFS_DINODE_FMT_EXTENTS) 559 xchk_ino_set_corrupt(sc, ino); 560 561 /* di_aformat */ 562 if (dip->di_aformat != XFS_DINODE_FMT_LOCAL && 563 dip->di_aformat != XFS_DINODE_FMT_EXTENTS && 564 dip->di_aformat != XFS_DINODE_FMT_BTREE) 565 xchk_ino_set_corrupt(sc, ino); 566 567 /* di_anextents */ 568 fork_recs = XFS_DFORK_ASIZE(dip, mp) / sizeof(struct xfs_bmbt_rec); 569 switch (dip->di_aformat) { 570 case XFS_DINODE_FMT_EXTENTS: 571 if (naextents > fork_recs) 572 xchk_ino_set_corrupt(sc, ino); 573 break; 574 case XFS_DINODE_FMT_BTREE: 575 if (naextents <= fork_recs) 576 xchk_ino_set_corrupt(sc, ino); 577 break; 578 default: 579 if (naextents != 0) 580 xchk_ino_set_corrupt(sc, ino); 581 } 582 583 if (dip->di_version >= 3) { 584 xchk_dinode_nsec(sc, ino, dip, dip->di_crtime); 585 xchk_inode_flags2(sc, dip, ino, mode, flags, flags2); 586 xchk_inode_cowextsize(sc, dip, ino, mode, flags, 587 flags2); 588 } 589 } 590 591 /* 592 * Make sure the finobt doesn't think this inode is free. 593 * We don't have to check the inobt ourselves because we got the inode via 594 * IGET_UNTRUSTED, which checks the inobt for us. 595 */ 596 static void 597 xchk_inode_xref_finobt( 598 struct xfs_scrub *sc, 599 xfs_ino_t ino) 600 { 601 struct xfs_inobt_rec_incore rec; 602 xfs_agino_t agino; 603 int has_record; 604 int error; 605 606 if (!sc->sa.fino_cur || xchk_skip_xref(sc->sm)) 607 return; 608 609 agino = XFS_INO_TO_AGINO(sc->mp, ino); 610 611 /* 612 * Try to get the finobt record. If we can't get it, then we're 613 * in good shape. 614 */ 615 error = xfs_inobt_lookup(sc->sa.fino_cur, agino, XFS_LOOKUP_LE, 616 &has_record); 617 if (!xchk_should_check_xref(sc, &error, &sc->sa.fino_cur) || 618 !has_record) 619 return; 620 621 error = xfs_inobt_get_rec(sc->sa.fino_cur, &rec, &has_record); 622 if (!xchk_should_check_xref(sc, &error, &sc->sa.fino_cur) || 623 !has_record) 624 return; 625 626 /* 627 * Otherwise, make sure this record either doesn't cover this inode, 628 * or that it does but it's marked present. 629 */ 630 if (rec.ir_startino > agino || 631 rec.ir_startino + XFS_INODES_PER_CHUNK <= agino) 632 return; 633 634 if (rec.ir_free & XFS_INOBT_MASK(agino - rec.ir_startino)) 635 xchk_btree_xref_set_corrupt(sc, sc->sa.fino_cur, 0); 636 } 637 638 /* Cross reference the inode fields with the forks. */ 639 STATIC void 640 xchk_inode_xref_bmap( 641 struct xfs_scrub *sc, 642 struct xfs_dinode *dip) 643 { 644 xfs_extnum_t nextents; 645 xfs_filblks_t count; 646 xfs_filblks_t acount; 647 int error; 648 649 if (xchk_skip_xref(sc->sm)) 650 return; 651 652 /* Walk all the extents to check nextents/naextents/nblocks. */ 653 error = xfs_bmap_count_blocks(sc->tp, sc->ip, XFS_DATA_FORK, 654 &nextents, &count); 655 if (!xchk_should_check_xref(sc, &error, NULL)) 656 return; 657 if (nextents < xfs_dfork_data_extents(dip)) 658 xchk_ino_xref_set_corrupt(sc, sc->ip->i_ino); 659 660 error = xfs_bmap_count_blocks(sc->tp, sc->ip, XFS_ATTR_FORK, 661 &nextents, &acount); 662 if (!xchk_should_check_xref(sc, &error, NULL)) 663 return; 664 if (nextents != xfs_dfork_attr_extents(dip)) 665 xchk_ino_xref_set_corrupt(sc, sc->ip->i_ino); 666 667 /* Check nblocks against the inode. */ 668 if (count + acount != be64_to_cpu(dip->di_nblocks)) 669 xchk_ino_xref_set_corrupt(sc, sc->ip->i_ino); 670 } 671 672 /* Cross-reference with the other btrees. */ 673 STATIC void 674 xchk_inode_xref( 675 struct xfs_scrub *sc, 676 xfs_ino_t ino, 677 struct xfs_dinode *dip) 678 { 679 xfs_agnumber_t agno; 680 xfs_agblock_t agbno; 681 int error; 682 683 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 684 return; 685 686 agno = XFS_INO_TO_AGNO(sc->mp, ino); 687 agbno = XFS_INO_TO_AGBNO(sc->mp, ino); 688 689 error = xchk_ag_init_existing(sc, agno, &sc->sa); 690 if (!xchk_xref_process_error(sc, agno, agbno, &error)) 691 goto out_free; 692 693 xchk_xref_is_used_space(sc, agbno, 1); 694 xchk_inode_xref_finobt(sc, ino); 695 xchk_xref_is_only_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_INODES); 696 xchk_xref_is_not_shared(sc, agbno, 1); 697 xchk_xref_is_not_cow_staging(sc, agbno, 1); 698 xchk_inode_xref_bmap(sc, dip); 699 700 out_free: 701 xchk_ag_free(sc, &sc->sa); 702 } 703 704 /* 705 * If the reflink iflag disagrees with a scan for shared data fork extents, 706 * either flag an error (shared extents w/ no flag) or a preen (flag set w/o 707 * any shared extents). We already checked for reflink iflag set on a non 708 * reflink filesystem. 709 */ 710 static void 711 xchk_inode_check_reflink_iflag( 712 struct xfs_scrub *sc, 713 xfs_ino_t ino) 714 { 715 struct xfs_mount *mp = sc->mp; 716 bool has_shared; 717 int error; 718 719 if (!xfs_has_reflink(mp)) 720 return; 721 722 error = xfs_reflink_inode_has_shared_extents(sc->tp, sc->ip, 723 &has_shared); 724 if (!xchk_xref_process_error(sc, XFS_INO_TO_AGNO(mp, ino), 725 XFS_INO_TO_AGBNO(mp, ino), &error)) 726 return; 727 if (xfs_is_reflink_inode(sc->ip) && !has_shared) 728 xchk_ino_set_preen(sc, ino); 729 else if (!xfs_is_reflink_inode(sc->ip) && has_shared) 730 xchk_ino_set_corrupt(sc, ino); 731 } 732 733 /* Scrub an inode. */ 734 int 735 xchk_inode( 736 struct xfs_scrub *sc) 737 { 738 struct xfs_dinode di; 739 int error = 0; 740 741 /* 742 * If sc->ip is NULL, that means that the setup function called 743 * xfs_iget to look up the inode. xfs_iget returned a EFSCORRUPTED 744 * and a NULL inode, so flag the corruption error and return. 745 */ 746 if (!sc->ip) { 747 xchk_ino_set_corrupt(sc, sc->sm->sm_ino); 748 return 0; 749 } 750 751 /* Scrub the inode core. */ 752 xfs_inode_to_disk(sc->ip, &di, 0); 753 xchk_dinode(sc, &di, sc->ip->i_ino); 754 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 755 goto out; 756 757 /* 758 * Look for discrepancies between file's data blocks and the reflink 759 * iflag. We already checked the iflag against the file mode when 760 * we scrubbed the dinode. 761 */ 762 if (S_ISREG(VFS_I(sc->ip)->i_mode)) 763 xchk_inode_check_reflink_iflag(sc, sc->ip->i_ino); 764 765 xchk_inode_xref(sc, sc->ip->i_ino, &di); 766 out: 767 return error; 768 } 769