1 /* 2 * Copyright (C) 2017 Oracle. All Rights Reserved. 3 * 4 * Author: Darrick J. Wong <darrick.wong@oracle.com> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 2 9 * of the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it would be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 19 */ 20 #include "xfs.h" 21 #include "xfs_fs.h" 22 #include "xfs_shared.h" 23 #include "xfs_format.h" 24 #include "xfs_trans_resv.h" 25 #include "xfs_mount.h" 26 #include "xfs_defer.h" 27 #include "xfs_btree.h" 28 #include "xfs_bit.h" 29 #include "xfs_log_format.h" 30 #include "xfs_trans.h" 31 #include "xfs_sb.h" 32 #include "xfs_inode.h" 33 #include "xfs_alloc.h" 34 #include "xfs_ialloc.h" 35 #include "xfs_ialloc_btree.h" 36 #include "xfs_icache.h" 37 #include "xfs_rmap.h" 38 #include "xfs_log.h" 39 #include "xfs_trans_priv.h" 40 #include "scrub/xfs_scrub.h" 41 #include "scrub/scrub.h" 42 #include "scrub/common.h" 43 #include "scrub/btree.h" 44 #include "scrub/trace.h" 45 46 /* 47 * Set us up to scrub inode btrees. 48 * If we detect a discrepancy between the inobt and the inode, 49 * try again after forcing logged inode cores out to disk. 50 */ 51 int 52 xfs_scrub_setup_ag_iallocbt( 53 struct xfs_scrub_context *sc, 54 struct xfs_inode *ip) 55 { 56 return xfs_scrub_setup_ag_btree(sc, ip, sc->try_harder); 57 } 58 59 /* Inode btree scrubber. */ 60 61 /* 62 * If we're checking the finobt, cross-reference with the inobt. 63 * Otherwise we're checking the inobt; if there is an finobt, make sure 64 * we have a record or not depending on freecount. 65 */ 66 static inline void 67 xfs_scrub_iallocbt_chunk_xref_other( 68 struct xfs_scrub_context *sc, 69 struct xfs_inobt_rec_incore *irec, 70 xfs_agino_t agino) 71 { 72 struct xfs_btree_cur **pcur; 73 bool has_irec; 74 int error; 75 76 if (sc->sm->sm_type == XFS_SCRUB_TYPE_FINOBT) 77 pcur = &sc->sa.ino_cur; 78 else 79 pcur = &sc->sa.fino_cur; 80 if (!(*pcur)) 81 return; 82 error = xfs_ialloc_has_inode_record(*pcur, agino, agino, &has_irec); 83 if (!xfs_scrub_should_check_xref(sc, &error, pcur)) 84 return; 85 if (((irec->ir_freecount > 0 && !has_irec) || 86 (irec->ir_freecount == 0 && has_irec))) 87 xfs_scrub_btree_xref_set_corrupt(sc, *pcur, 0); 88 } 89 90 /* Cross-reference with the other btrees. */ 91 STATIC void 92 xfs_scrub_iallocbt_chunk_xref( 93 struct xfs_scrub_context *sc, 94 struct xfs_inobt_rec_incore *irec, 95 xfs_agino_t agino, 96 xfs_agblock_t agbno, 97 xfs_extlen_t len) 98 { 99 struct xfs_owner_info oinfo; 100 101 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 102 return; 103 104 xfs_scrub_xref_is_used_space(sc, agbno, len); 105 xfs_scrub_iallocbt_chunk_xref_other(sc, irec, agino); 106 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INODES); 107 xfs_scrub_xref_is_owned_by(sc, agbno, len, &oinfo); 108 xfs_scrub_xref_is_not_shared(sc, agbno, len); 109 } 110 111 /* Is this chunk worth checking? */ 112 STATIC bool 113 xfs_scrub_iallocbt_chunk( 114 struct xfs_scrub_btree *bs, 115 struct xfs_inobt_rec_incore *irec, 116 xfs_agino_t agino, 117 xfs_extlen_t len) 118 { 119 struct xfs_mount *mp = bs->cur->bc_mp; 120 xfs_agnumber_t agno = bs->cur->bc_private.a.agno; 121 xfs_agblock_t bno; 122 123 bno = XFS_AGINO_TO_AGBNO(mp, agino); 124 if (bno + len <= bno || 125 !xfs_verify_agbno(mp, agno, bno) || 126 !xfs_verify_agbno(mp, agno, bno + len - 1)) 127 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 128 129 xfs_scrub_iallocbt_chunk_xref(bs->sc, irec, agino, bno, len); 130 131 return true; 132 } 133 134 /* Count the number of free inodes. */ 135 static unsigned int 136 xfs_scrub_iallocbt_freecount( 137 xfs_inofree_t freemask) 138 { 139 BUILD_BUG_ON(sizeof(freemask) != sizeof(__u64)); 140 return hweight64(freemask); 141 } 142 143 /* Check a particular inode with ir_free. */ 144 STATIC int 145 xfs_scrub_iallocbt_check_cluster_freemask( 146 struct xfs_scrub_btree *bs, 147 xfs_ino_t fsino, 148 xfs_agino_t chunkino, 149 xfs_agino_t clusterino, 150 struct xfs_inobt_rec_incore *irec, 151 struct xfs_buf *bp) 152 { 153 struct xfs_dinode *dip; 154 struct xfs_mount *mp = bs->cur->bc_mp; 155 bool inode_is_free = false; 156 bool freemask_ok; 157 bool inuse; 158 int error = 0; 159 160 if (xfs_scrub_should_terminate(bs->sc, &error)) 161 return error; 162 163 dip = xfs_buf_offset(bp, clusterino * mp->m_sb.sb_inodesize); 164 if (be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC || 165 (dip->di_version >= 3 && 166 be64_to_cpu(dip->di_ino) != fsino + clusterino)) { 167 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 168 goto out; 169 } 170 171 if (irec->ir_free & XFS_INOBT_MASK(chunkino + clusterino)) 172 inode_is_free = true; 173 error = xfs_icache_inode_is_allocated(mp, bs->cur->bc_tp, 174 fsino + clusterino, &inuse); 175 if (error == -ENODATA) { 176 /* Not cached, just read the disk buffer */ 177 freemask_ok = inode_is_free ^ !!(dip->di_mode); 178 if (!bs->sc->try_harder && !freemask_ok) 179 return -EDEADLOCK; 180 } else if (error < 0) { 181 /* 182 * Inode is only half assembled, or there was an IO error, 183 * or the verifier failed, so don't bother trying to check. 184 * The inode scrubber can deal with this. 185 */ 186 goto out; 187 } else { 188 /* Inode is all there. */ 189 freemask_ok = inode_is_free ^ inuse; 190 } 191 if (!freemask_ok) 192 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 193 out: 194 return 0; 195 } 196 197 /* Make sure the free mask is consistent with what the inodes think. */ 198 STATIC int 199 xfs_scrub_iallocbt_check_freemask( 200 struct xfs_scrub_btree *bs, 201 struct xfs_inobt_rec_incore *irec) 202 { 203 struct xfs_owner_info oinfo; 204 struct xfs_imap imap; 205 struct xfs_mount *mp = bs->cur->bc_mp; 206 struct xfs_dinode *dip; 207 struct xfs_buf *bp; 208 xfs_ino_t fsino; 209 xfs_agino_t nr_inodes; 210 xfs_agino_t agino; 211 xfs_agino_t chunkino; 212 xfs_agino_t clusterino; 213 xfs_agblock_t agbno; 214 int blks_per_cluster; 215 uint16_t holemask; 216 uint16_t ir_holemask; 217 int error = 0; 218 219 /* Make sure the freemask matches the inode records. */ 220 blks_per_cluster = xfs_icluster_size_fsb(mp); 221 nr_inodes = XFS_OFFBNO_TO_AGINO(mp, blks_per_cluster, 0); 222 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INODES); 223 224 for (agino = irec->ir_startino; 225 agino < irec->ir_startino + XFS_INODES_PER_CHUNK; 226 agino += blks_per_cluster * mp->m_sb.sb_inopblock) { 227 fsino = XFS_AGINO_TO_INO(mp, bs->cur->bc_private.a.agno, agino); 228 chunkino = agino - irec->ir_startino; 229 agbno = XFS_AGINO_TO_AGBNO(mp, agino); 230 231 /* Compute the holemask mask for this cluster. */ 232 for (clusterino = 0, holemask = 0; clusterino < nr_inodes; 233 clusterino += XFS_INODES_PER_HOLEMASK_BIT) 234 holemask |= XFS_INOBT_MASK((chunkino + clusterino) / 235 XFS_INODES_PER_HOLEMASK_BIT); 236 237 /* The whole cluster must be a hole or not a hole. */ 238 ir_holemask = (irec->ir_holemask & holemask); 239 if (ir_holemask != holemask && ir_holemask != 0) { 240 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 241 continue; 242 } 243 244 /* If any part of this is a hole, skip it. */ 245 if (ir_holemask) { 246 xfs_scrub_xref_is_not_owned_by(bs->sc, agbno, 247 blks_per_cluster, &oinfo); 248 continue; 249 } 250 251 xfs_scrub_xref_is_owned_by(bs->sc, agbno, blks_per_cluster, 252 &oinfo); 253 254 /* Grab the inode cluster buffer. */ 255 imap.im_blkno = XFS_AGB_TO_DADDR(mp, bs->cur->bc_private.a.agno, 256 agbno); 257 imap.im_len = XFS_FSB_TO_BB(mp, blks_per_cluster); 258 imap.im_boffset = 0; 259 260 error = xfs_imap_to_bp(mp, bs->cur->bc_tp, &imap, 261 &dip, &bp, 0, 0); 262 if (!xfs_scrub_btree_xref_process_error(bs->sc, bs->cur, 0, 263 &error)) 264 continue; 265 266 /* Which inodes are free? */ 267 for (clusterino = 0; clusterino < nr_inodes; clusterino++) { 268 error = xfs_scrub_iallocbt_check_cluster_freemask(bs, 269 fsino, chunkino, clusterino, irec, bp); 270 if (error) { 271 xfs_trans_brelse(bs->cur->bc_tp, bp); 272 return error; 273 } 274 } 275 276 xfs_trans_brelse(bs->cur->bc_tp, bp); 277 } 278 279 return error; 280 } 281 282 /* Scrub an inobt/finobt record. */ 283 STATIC int 284 xfs_scrub_iallocbt_rec( 285 struct xfs_scrub_btree *bs, 286 union xfs_btree_rec *rec) 287 { 288 struct xfs_mount *mp = bs->cur->bc_mp; 289 xfs_filblks_t *inode_blocks = bs->private; 290 struct xfs_inobt_rec_incore irec; 291 uint64_t holes; 292 xfs_agnumber_t agno = bs->cur->bc_private.a.agno; 293 xfs_agino_t agino; 294 xfs_agblock_t agbno; 295 xfs_extlen_t len; 296 int holecount; 297 int i; 298 int error = 0; 299 unsigned int real_freecount; 300 uint16_t holemask; 301 302 xfs_inobt_btrec_to_irec(mp, rec, &irec); 303 304 if (irec.ir_count > XFS_INODES_PER_CHUNK || 305 irec.ir_freecount > XFS_INODES_PER_CHUNK) 306 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 307 308 real_freecount = irec.ir_freecount + 309 (XFS_INODES_PER_CHUNK - irec.ir_count); 310 if (real_freecount != xfs_scrub_iallocbt_freecount(irec.ir_free)) 311 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 312 313 agino = irec.ir_startino; 314 /* Record has to be properly aligned within the AG. */ 315 if (!xfs_verify_agino(mp, agno, agino) || 316 !xfs_verify_agino(mp, agno, agino + XFS_INODES_PER_CHUNK - 1)) { 317 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 318 goto out; 319 } 320 321 /* Make sure this record is aligned to cluster and inoalignmnt size. */ 322 agbno = XFS_AGINO_TO_AGBNO(mp, irec.ir_startino); 323 if ((agbno & (xfs_ialloc_cluster_alignment(mp) - 1)) || 324 (agbno & (xfs_icluster_size_fsb(mp) - 1))) 325 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 326 327 *inode_blocks += XFS_B_TO_FSB(mp, 328 irec.ir_count * mp->m_sb.sb_inodesize); 329 330 /* Handle non-sparse inodes */ 331 if (!xfs_inobt_issparse(irec.ir_holemask)) { 332 len = XFS_B_TO_FSB(mp, 333 XFS_INODES_PER_CHUNK * mp->m_sb.sb_inodesize); 334 if (irec.ir_count != XFS_INODES_PER_CHUNK) 335 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 336 337 if (!xfs_scrub_iallocbt_chunk(bs, &irec, agino, len)) 338 goto out; 339 goto check_freemask; 340 } 341 342 /* Check each chunk of a sparse inode cluster. */ 343 holemask = irec.ir_holemask; 344 holecount = 0; 345 len = XFS_B_TO_FSB(mp, 346 XFS_INODES_PER_HOLEMASK_BIT * mp->m_sb.sb_inodesize); 347 holes = ~xfs_inobt_irec_to_allocmask(&irec); 348 if ((holes & irec.ir_free) != holes || 349 irec.ir_freecount > irec.ir_count) 350 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 351 352 for (i = 0; i < XFS_INOBT_HOLEMASK_BITS; i++) { 353 if (holemask & 1) 354 holecount += XFS_INODES_PER_HOLEMASK_BIT; 355 else if (!xfs_scrub_iallocbt_chunk(bs, &irec, agino, len)) 356 break; 357 holemask >>= 1; 358 agino += XFS_INODES_PER_HOLEMASK_BIT; 359 } 360 361 if (holecount > XFS_INODES_PER_CHUNK || 362 holecount + irec.ir_count != XFS_INODES_PER_CHUNK) 363 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 364 365 check_freemask: 366 error = xfs_scrub_iallocbt_check_freemask(bs, &irec); 367 if (error) 368 goto out; 369 370 out: 371 return error; 372 } 373 374 /* 375 * Make sure the inode btrees are as large as the rmap thinks they are. 376 * Don't bother if we're missing btree cursors, as we're already corrupt. 377 */ 378 STATIC void 379 xfs_scrub_iallocbt_xref_rmap_btreeblks( 380 struct xfs_scrub_context *sc, 381 int which) 382 { 383 struct xfs_owner_info oinfo; 384 xfs_filblks_t blocks; 385 xfs_extlen_t inobt_blocks = 0; 386 xfs_extlen_t finobt_blocks = 0; 387 int error; 388 389 if (!sc->sa.ino_cur || !sc->sa.rmap_cur || 390 (xfs_sb_version_hasfinobt(&sc->mp->m_sb) && !sc->sa.fino_cur)) 391 return; 392 393 /* Check that we saw as many inobt blocks as the rmap says. */ 394 error = xfs_btree_count_blocks(sc->sa.ino_cur, &inobt_blocks); 395 if (!xfs_scrub_process_error(sc, 0, 0, &error)) 396 return; 397 398 if (sc->sa.fino_cur) { 399 error = xfs_btree_count_blocks(sc->sa.fino_cur, &finobt_blocks); 400 if (!xfs_scrub_process_error(sc, 0, 0, &error)) 401 return; 402 } 403 404 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INOBT); 405 error = xfs_scrub_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur, &oinfo, 406 &blocks); 407 if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.rmap_cur)) 408 return; 409 if (blocks != inobt_blocks + finobt_blocks) 410 xfs_scrub_btree_set_corrupt(sc, sc->sa.ino_cur, 0); 411 } 412 413 /* 414 * Make sure that the inobt records point to the same number of blocks as 415 * the rmap says are owned by inodes. 416 */ 417 STATIC void 418 xfs_scrub_iallocbt_xref_rmap_inodes( 419 struct xfs_scrub_context *sc, 420 int which, 421 xfs_filblks_t inode_blocks) 422 { 423 struct xfs_owner_info oinfo; 424 xfs_filblks_t blocks; 425 int error; 426 427 if (!sc->sa.rmap_cur) 428 return; 429 430 /* Check that we saw as many inode blocks as the rmap knows about. */ 431 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INODES); 432 error = xfs_scrub_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur, &oinfo, 433 &blocks); 434 if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.rmap_cur)) 435 return; 436 if (blocks != inode_blocks) 437 xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0); 438 } 439 440 /* Scrub the inode btrees for some AG. */ 441 STATIC int 442 xfs_scrub_iallocbt( 443 struct xfs_scrub_context *sc, 444 xfs_btnum_t which) 445 { 446 struct xfs_btree_cur *cur; 447 struct xfs_owner_info oinfo; 448 xfs_filblks_t inode_blocks = 0; 449 int error; 450 451 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INOBT); 452 cur = which == XFS_BTNUM_INO ? sc->sa.ino_cur : sc->sa.fino_cur; 453 error = xfs_scrub_btree(sc, cur, xfs_scrub_iallocbt_rec, &oinfo, 454 &inode_blocks); 455 if (error) 456 return error; 457 458 xfs_scrub_iallocbt_xref_rmap_btreeblks(sc, which); 459 460 /* 461 * If we're scrubbing the inode btree, inode_blocks is the number of 462 * blocks pointed to by all the inode chunk records. Therefore, we 463 * should compare to the number of inode chunk blocks that the rmap 464 * knows about. We can't do this for the finobt since it only points 465 * to inode chunks with free inodes. 466 */ 467 if (which == XFS_BTNUM_INO) 468 xfs_scrub_iallocbt_xref_rmap_inodes(sc, which, inode_blocks); 469 470 return error; 471 } 472 473 int 474 xfs_scrub_inobt( 475 struct xfs_scrub_context *sc) 476 { 477 return xfs_scrub_iallocbt(sc, XFS_BTNUM_INO); 478 } 479 480 int 481 xfs_scrub_finobt( 482 struct xfs_scrub_context *sc) 483 { 484 return xfs_scrub_iallocbt(sc, XFS_BTNUM_FINO); 485 } 486 487 /* See if an inode btree has (or doesn't have) an inode chunk record. */ 488 static inline void 489 xfs_scrub_xref_inode_check( 490 struct xfs_scrub_context *sc, 491 xfs_agblock_t agbno, 492 xfs_extlen_t len, 493 struct xfs_btree_cur **icur, 494 bool should_have_inodes) 495 { 496 bool has_inodes; 497 int error; 498 499 if (!(*icur)) 500 return; 501 502 error = xfs_ialloc_has_inodes_at_extent(*icur, agbno, len, &has_inodes); 503 if (!xfs_scrub_should_check_xref(sc, &error, icur)) 504 return; 505 if (has_inodes != should_have_inodes) 506 xfs_scrub_btree_xref_set_corrupt(sc, *icur, 0); 507 } 508 509 /* xref check that the extent is not covered by inodes */ 510 void 511 xfs_scrub_xref_is_not_inode_chunk( 512 struct xfs_scrub_context *sc, 513 xfs_agblock_t agbno, 514 xfs_extlen_t len) 515 { 516 xfs_scrub_xref_inode_check(sc, agbno, len, &sc->sa.ino_cur, false); 517 xfs_scrub_xref_inode_check(sc, agbno, len, &sc->sa.fino_cur, false); 518 } 519 520 /* xref check that the extent is covered by inodes */ 521 void 522 xfs_scrub_xref_is_inode_chunk( 523 struct xfs_scrub_context *sc, 524 xfs_agblock_t agbno, 525 xfs_extlen_t len) 526 { 527 xfs_scrub_xref_inode_check(sc, agbno, len, &sc->sa.ino_cur, true); 528 } 529