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