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