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 regular untrusted iget. */ 98 error = xchk_iget(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 return; 341 bad: 342 xchk_ino_set_corrupt(sc, ino); 343 } 344 345 static inline void 346 xchk_dinode_nsec( 347 struct xfs_scrub *sc, 348 xfs_ino_t ino, 349 struct xfs_dinode *dip, 350 const xfs_timestamp_t ts) 351 { 352 struct timespec64 tv; 353 354 tv = xfs_inode_from_disk_ts(dip, ts); 355 if (tv.tv_nsec < 0 || tv.tv_nsec >= NSEC_PER_SEC) 356 xchk_ino_set_corrupt(sc, ino); 357 } 358 359 /* Scrub all the ondisk inode fields. */ 360 STATIC void 361 xchk_dinode( 362 struct xfs_scrub *sc, 363 struct xfs_dinode *dip, 364 xfs_ino_t ino) 365 { 366 struct xfs_mount *mp = sc->mp; 367 size_t fork_recs; 368 unsigned long long isize; 369 uint64_t flags2; 370 xfs_extnum_t nextents; 371 xfs_extnum_t naextents; 372 prid_t prid; 373 uint16_t flags; 374 uint16_t mode; 375 376 flags = be16_to_cpu(dip->di_flags); 377 if (dip->di_version >= 3) 378 flags2 = be64_to_cpu(dip->di_flags2); 379 else 380 flags2 = 0; 381 382 /* di_mode */ 383 mode = be16_to_cpu(dip->di_mode); 384 switch (mode & S_IFMT) { 385 case S_IFLNK: 386 case S_IFREG: 387 case S_IFDIR: 388 case S_IFCHR: 389 case S_IFBLK: 390 case S_IFIFO: 391 case S_IFSOCK: 392 /* mode is recognized */ 393 break; 394 default: 395 xchk_ino_set_corrupt(sc, ino); 396 break; 397 } 398 399 /* v1/v2 fields */ 400 switch (dip->di_version) { 401 case 1: 402 /* 403 * We autoconvert v1 inodes into v2 inodes on writeout, 404 * so just mark this inode for preening. 405 */ 406 xchk_ino_set_preen(sc, ino); 407 prid = 0; 408 break; 409 case 2: 410 case 3: 411 if (dip->di_onlink != 0) 412 xchk_ino_set_corrupt(sc, ino); 413 414 if (dip->di_mode == 0 && sc->ip) 415 xchk_ino_set_corrupt(sc, ino); 416 417 if (dip->di_projid_hi != 0 && 418 !xfs_has_projid32(mp)) 419 xchk_ino_set_corrupt(sc, ino); 420 421 prid = be16_to_cpu(dip->di_projid_lo); 422 break; 423 default: 424 xchk_ino_set_corrupt(sc, ino); 425 return; 426 } 427 428 if (xfs_has_projid32(mp)) 429 prid |= (prid_t)be16_to_cpu(dip->di_projid_hi) << 16; 430 431 /* 432 * di_uid/di_gid -- -1 isn't invalid, but there's no way that 433 * userspace could have created that. 434 */ 435 if (dip->di_uid == cpu_to_be32(-1U) || 436 dip->di_gid == cpu_to_be32(-1U)) 437 xchk_ino_set_warning(sc, ino); 438 439 /* 440 * project id of -1 isn't supposed to be valid, but the kernel didn't 441 * always validate that. 442 */ 443 if (prid == -1U) 444 xchk_ino_set_warning(sc, ino); 445 446 /* di_format */ 447 switch (dip->di_format) { 448 case XFS_DINODE_FMT_DEV: 449 if (!S_ISCHR(mode) && !S_ISBLK(mode) && 450 !S_ISFIFO(mode) && !S_ISSOCK(mode)) 451 xchk_ino_set_corrupt(sc, ino); 452 break; 453 case XFS_DINODE_FMT_LOCAL: 454 if (!S_ISDIR(mode) && !S_ISLNK(mode)) 455 xchk_ino_set_corrupt(sc, ino); 456 break; 457 case XFS_DINODE_FMT_EXTENTS: 458 if (!S_ISREG(mode) && !S_ISDIR(mode) && !S_ISLNK(mode)) 459 xchk_ino_set_corrupt(sc, ino); 460 break; 461 case XFS_DINODE_FMT_BTREE: 462 if (!S_ISREG(mode) && !S_ISDIR(mode)) 463 xchk_ino_set_corrupt(sc, ino); 464 break; 465 case XFS_DINODE_FMT_UUID: 466 default: 467 xchk_ino_set_corrupt(sc, ino); 468 break; 469 } 470 471 /* di_[amc]time.nsec */ 472 xchk_dinode_nsec(sc, ino, dip, dip->di_atime); 473 xchk_dinode_nsec(sc, ino, dip, dip->di_mtime); 474 xchk_dinode_nsec(sc, ino, dip, dip->di_ctime); 475 476 /* 477 * di_size. xfs_dinode_verify checks for things that screw up 478 * the VFS such as the upper bit being set and zero-length 479 * symlinks/directories, but we can do more here. 480 */ 481 isize = be64_to_cpu(dip->di_size); 482 if (isize & (1ULL << 63)) 483 xchk_ino_set_corrupt(sc, ino); 484 485 /* Devices, fifos, and sockets must have zero size */ 486 if (!S_ISDIR(mode) && !S_ISREG(mode) && !S_ISLNK(mode) && isize != 0) 487 xchk_ino_set_corrupt(sc, ino); 488 489 /* Directories can't be larger than the data section size (32G) */ 490 if (S_ISDIR(mode) && (isize == 0 || isize >= XFS_DIR2_SPACE_SIZE)) 491 xchk_ino_set_corrupt(sc, ino); 492 493 /* Symlinks can't be larger than SYMLINK_MAXLEN */ 494 if (S_ISLNK(mode) && (isize == 0 || isize >= XFS_SYMLINK_MAXLEN)) 495 xchk_ino_set_corrupt(sc, ino); 496 497 /* 498 * Warn if the running kernel can't handle the kinds of offsets 499 * needed to deal with the file size. In other words, if the 500 * pagecache can't cache all the blocks in this file due to 501 * overly large offsets, flag the inode for admin review. 502 */ 503 if (isize > mp->m_super->s_maxbytes) 504 xchk_ino_set_warning(sc, ino); 505 506 /* di_nblocks */ 507 if (flags2 & XFS_DIFLAG2_REFLINK) { 508 ; /* nblocks can exceed dblocks */ 509 } else if (flags & XFS_DIFLAG_REALTIME) { 510 /* 511 * nblocks is the sum of data extents (in the rtdev), 512 * attr extents (in the datadev), and both forks' bmbt 513 * blocks (in the datadev). This clumsy check is the 514 * best we can do without cross-referencing with the 515 * inode forks. 516 */ 517 if (be64_to_cpu(dip->di_nblocks) >= 518 mp->m_sb.sb_dblocks + mp->m_sb.sb_rblocks) 519 xchk_ino_set_corrupt(sc, ino); 520 } else { 521 if (be64_to_cpu(dip->di_nblocks) >= mp->m_sb.sb_dblocks) 522 xchk_ino_set_corrupt(sc, ino); 523 } 524 525 xchk_inode_flags(sc, dip, ino, mode, flags); 526 527 xchk_inode_extsize(sc, dip, ino, mode, flags); 528 529 nextents = xfs_dfork_data_extents(dip); 530 naextents = xfs_dfork_attr_extents(dip); 531 532 /* di_nextents */ 533 fork_recs = XFS_DFORK_DSIZE(dip, mp) / sizeof(struct xfs_bmbt_rec); 534 switch (dip->di_format) { 535 case XFS_DINODE_FMT_EXTENTS: 536 if (nextents > fork_recs) 537 xchk_ino_set_corrupt(sc, ino); 538 break; 539 case XFS_DINODE_FMT_BTREE: 540 if (nextents <= fork_recs) 541 xchk_ino_set_corrupt(sc, ino); 542 break; 543 default: 544 if (nextents != 0) 545 xchk_ino_set_corrupt(sc, ino); 546 break; 547 } 548 549 /* di_forkoff */ 550 if (XFS_DFORK_APTR(dip) >= (char *)dip + mp->m_sb.sb_inodesize) 551 xchk_ino_set_corrupt(sc, ino); 552 if (naextents != 0 && dip->di_forkoff == 0) 553 xchk_ino_set_corrupt(sc, ino); 554 if (dip->di_forkoff == 0 && dip->di_aformat != XFS_DINODE_FMT_EXTENTS) 555 xchk_ino_set_corrupt(sc, ino); 556 557 /* di_aformat */ 558 if (dip->di_aformat != XFS_DINODE_FMT_LOCAL && 559 dip->di_aformat != XFS_DINODE_FMT_EXTENTS && 560 dip->di_aformat != XFS_DINODE_FMT_BTREE) 561 xchk_ino_set_corrupt(sc, ino); 562 563 /* di_anextents */ 564 fork_recs = XFS_DFORK_ASIZE(dip, mp) / sizeof(struct xfs_bmbt_rec); 565 switch (dip->di_aformat) { 566 case XFS_DINODE_FMT_EXTENTS: 567 if (naextents > fork_recs) 568 xchk_ino_set_corrupt(sc, ino); 569 break; 570 case XFS_DINODE_FMT_BTREE: 571 if (naextents <= fork_recs) 572 xchk_ino_set_corrupt(sc, ino); 573 break; 574 default: 575 if (naextents != 0) 576 xchk_ino_set_corrupt(sc, ino); 577 } 578 579 if (dip->di_version >= 3) { 580 xchk_dinode_nsec(sc, ino, dip, dip->di_crtime); 581 xchk_inode_flags2(sc, dip, ino, mode, flags, flags2); 582 xchk_inode_cowextsize(sc, dip, ino, mode, flags, 583 flags2); 584 } 585 } 586 587 /* 588 * Make sure the finobt doesn't think this inode is free. 589 * We don't have to check the inobt ourselves because we got the inode via 590 * IGET_UNTRUSTED, which checks the inobt for us. 591 */ 592 static void 593 xchk_inode_xref_finobt( 594 struct xfs_scrub *sc, 595 xfs_ino_t ino) 596 { 597 struct xfs_inobt_rec_incore rec; 598 xfs_agino_t agino; 599 int has_record; 600 int error; 601 602 if (!sc->sa.fino_cur || xchk_skip_xref(sc->sm)) 603 return; 604 605 agino = XFS_INO_TO_AGINO(sc->mp, ino); 606 607 /* 608 * Try to get the finobt record. If we can't get it, then we're 609 * in good shape. 610 */ 611 error = xfs_inobt_lookup(sc->sa.fino_cur, agino, XFS_LOOKUP_LE, 612 &has_record); 613 if (!xchk_should_check_xref(sc, &error, &sc->sa.fino_cur) || 614 !has_record) 615 return; 616 617 error = xfs_inobt_get_rec(sc->sa.fino_cur, &rec, &has_record); 618 if (!xchk_should_check_xref(sc, &error, &sc->sa.fino_cur) || 619 !has_record) 620 return; 621 622 /* 623 * Otherwise, make sure this record either doesn't cover this inode, 624 * or that it does but it's marked present. 625 */ 626 if (rec.ir_startino > agino || 627 rec.ir_startino + XFS_INODES_PER_CHUNK <= agino) 628 return; 629 630 if (rec.ir_free & XFS_INOBT_MASK(agino - rec.ir_startino)) 631 xchk_btree_xref_set_corrupt(sc, sc->sa.fino_cur, 0); 632 } 633 634 /* Cross reference the inode fields with the forks. */ 635 STATIC void 636 xchk_inode_xref_bmap( 637 struct xfs_scrub *sc, 638 struct xfs_dinode *dip) 639 { 640 xfs_extnum_t nextents; 641 xfs_filblks_t count; 642 xfs_filblks_t acount; 643 int error; 644 645 if (xchk_skip_xref(sc->sm)) 646 return; 647 648 /* Walk all the extents to check nextents/naextents/nblocks. */ 649 error = xfs_bmap_count_blocks(sc->tp, sc->ip, XFS_DATA_FORK, 650 &nextents, &count); 651 if (!xchk_should_check_xref(sc, &error, NULL)) 652 return; 653 if (nextents < xfs_dfork_data_extents(dip)) 654 xchk_ino_xref_set_corrupt(sc, sc->ip->i_ino); 655 656 error = xfs_bmap_count_blocks(sc->tp, sc->ip, XFS_ATTR_FORK, 657 &nextents, &acount); 658 if (!xchk_should_check_xref(sc, &error, NULL)) 659 return; 660 if (nextents != xfs_dfork_attr_extents(dip)) 661 xchk_ino_xref_set_corrupt(sc, sc->ip->i_ino); 662 663 /* Check nblocks against the inode. */ 664 if (count + acount != be64_to_cpu(dip->di_nblocks)) 665 xchk_ino_xref_set_corrupt(sc, sc->ip->i_ino); 666 } 667 668 /* Cross-reference with the other btrees. */ 669 STATIC void 670 xchk_inode_xref( 671 struct xfs_scrub *sc, 672 xfs_ino_t ino, 673 struct xfs_dinode *dip) 674 { 675 xfs_agnumber_t agno; 676 xfs_agblock_t agbno; 677 int error; 678 679 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 680 return; 681 682 agno = XFS_INO_TO_AGNO(sc->mp, ino); 683 agbno = XFS_INO_TO_AGBNO(sc->mp, ino); 684 685 error = xchk_ag_init_existing(sc, agno, &sc->sa); 686 if (!xchk_xref_process_error(sc, agno, agbno, &error)) 687 goto out_free; 688 689 xchk_xref_is_used_space(sc, agbno, 1); 690 xchk_inode_xref_finobt(sc, ino); 691 xchk_xref_is_only_owned_by(sc, agbno, 1, &XFS_RMAP_OINFO_INODES); 692 xchk_xref_is_not_shared(sc, agbno, 1); 693 xchk_xref_is_not_cow_staging(sc, agbno, 1); 694 xchk_inode_xref_bmap(sc, dip); 695 696 out_free: 697 xchk_ag_free(sc, &sc->sa); 698 } 699 700 /* 701 * If the reflink iflag disagrees with a scan for shared data fork extents, 702 * either flag an error (shared extents w/ no flag) or a preen (flag set w/o 703 * any shared extents). We already checked for reflink iflag set on a non 704 * reflink filesystem. 705 */ 706 static void 707 xchk_inode_check_reflink_iflag( 708 struct xfs_scrub *sc, 709 xfs_ino_t ino) 710 { 711 struct xfs_mount *mp = sc->mp; 712 bool has_shared; 713 int error; 714 715 if (!xfs_has_reflink(mp)) 716 return; 717 718 error = xfs_reflink_inode_has_shared_extents(sc->tp, sc->ip, 719 &has_shared); 720 if (!xchk_xref_process_error(sc, XFS_INO_TO_AGNO(mp, ino), 721 XFS_INO_TO_AGBNO(mp, ino), &error)) 722 return; 723 if (xfs_is_reflink_inode(sc->ip) && !has_shared) 724 xchk_ino_set_preen(sc, ino); 725 else if (!xfs_is_reflink_inode(sc->ip) && has_shared) 726 xchk_ino_set_corrupt(sc, ino); 727 } 728 729 /* Scrub an inode. */ 730 int 731 xchk_inode( 732 struct xfs_scrub *sc) 733 { 734 struct xfs_dinode di; 735 int error = 0; 736 737 /* 738 * If sc->ip is NULL, that means that the setup function called 739 * xfs_iget to look up the inode. xfs_iget returned a EFSCORRUPTED 740 * and a NULL inode, so flag the corruption error and return. 741 */ 742 if (!sc->ip) { 743 xchk_ino_set_corrupt(sc, sc->sm->sm_ino); 744 return 0; 745 } 746 747 /* Scrub the inode core. */ 748 xfs_inode_to_disk(sc->ip, &di, 0); 749 xchk_dinode(sc, &di, sc->ip->i_ino); 750 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 751 goto out; 752 753 /* 754 * Look for discrepancies between file's data blocks and the reflink 755 * iflag. We already checked the iflag against the file mode when 756 * we scrubbed the dinode. 757 */ 758 if (S_ISREG(VFS_I(sc->ip)->i_mode)) 759 xchk_inode_check_reflink_iflag(sc, sc->ip->i_ino); 760 761 xchk_inode_xref(sc, sc->ip->i_ino, &di); 762 out: 763 return error; 764 } 765