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 /* Is this chunk worth checking? */ 62 STATIC bool 63 xfs_scrub_iallocbt_chunk( 64 struct xfs_scrub_btree *bs, 65 struct xfs_inobt_rec_incore *irec, 66 xfs_agino_t agino, 67 xfs_extlen_t len) 68 { 69 struct xfs_mount *mp = bs->cur->bc_mp; 70 xfs_agnumber_t agno = bs->cur->bc_private.a.agno; 71 xfs_agblock_t bno; 72 73 bno = XFS_AGINO_TO_AGBNO(mp, agino); 74 if (bno + len <= bno || 75 !xfs_verify_agbno(mp, agno, bno) || 76 !xfs_verify_agbno(mp, agno, bno + len - 1)) 77 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 78 79 return true; 80 } 81 82 /* Count the number of free inodes. */ 83 static unsigned int 84 xfs_scrub_iallocbt_freecount( 85 xfs_inofree_t freemask) 86 { 87 BUILD_BUG_ON(sizeof(freemask) != sizeof(__u64)); 88 return hweight64(freemask); 89 } 90 91 /* Check a particular inode with ir_free. */ 92 STATIC int 93 xfs_scrub_iallocbt_check_cluster_freemask( 94 struct xfs_scrub_btree *bs, 95 xfs_ino_t fsino, 96 xfs_agino_t chunkino, 97 xfs_agino_t clusterino, 98 struct xfs_inobt_rec_incore *irec, 99 struct xfs_buf *bp) 100 { 101 struct xfs_dinode *dip; 102 struct xfs_mount *mp = bs->cur->bc_mp; 103 bool inode_is_free = false; 104 bool freemask_ok; 105 bool inuse; 106 int error = 0; 107 108 if (xfs_scrub_should_terminate(bs->sc, &error)) 109 return error; 110 111 dip = xfs_buf_offset(bp, clusterino * mp->m_sb.sb_inodesize); 112 if (be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC || 113 (dip->di_version >= 3 && 114 be64_to_cpu(dip->di_ino) != fsino + clusterino)) { 115 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 116 goto out; 117 } 118 119 if (irec->ir_free & XFS_INOBT_MASK(chunkino + clusterino)) 120 inode_is_free = true; 121 error = xfs_icache_inode_is_allocated(mp, bs->cur->bc_tp, 122 fsino + clusterino, &inuse); 123 if (error == -ENODATA) { 124 /* Not cached, just read the disk buffer */ 125 freemask_ok = inode_is_free ^ !!(dip->di_mode); 126 if (!bs->sc->try_harder && !freemask_ok) 127 return -EDEADLOCK; 128 } else if (error < 0) { 129 /* 130 * Inode is only half assembled, or there was an IO error, 131 * or the verifier failed, so don't bother trying to check. 132 * The inode scrubber can deal with this. 133 */ 134 goto out; 135 } else { 136 /* Inode is all there. */ 137 freemask_ok = inode_is_free ^ inuse; 138 } 139 if (!freemask_ok) 140 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 141 out: 142 return 0; 143 } 144 145 /* Make sure the free mask is consistent with what the inodes think. */ 146 STATIC int 147 xfs_scrub_iallocbt_check_freemask( 148 struct xfs_scrub_btree *bs, 149 struct xfs_inobt_rec_incore *irec) 150 { 151 struct xfs_owner_info oinfo; 152 struct xfs_imap imap; 153 struct xfs_mount *mp = bs->cur->bc_mp; 154 struct xfs_dinode *dip; 155 struct xfs_buf *bp; 156 xfs_ino_t fsino; 157 xfs_agino_t nr_inodes; 158 xfs_agino_t agino; 159 xfs_agino_t chunkino; 160 xfs_agino_t clusterino; 161 xfs_agblock_t agbno; 162 int blks_per_cluster; 163 uint16_t holemask; 164 uint16_t ir_holemask; 165 int error = 0; 166 167 /* Make sure the freemask matches the inode records. */ 168 blks_per_cluster = xfs_icluster_size_fsb(mp); 169 nr_inodes = XFS_OFFBNO_TO_AGINO(mp, blks_per_cluster, 0); 170 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INODES); 171 172 for (agino = irec->ir_startino; 173 agino < irec->ir_startino + XFS_INODES_PER_CHUNK; 174 agino += blks_per_cluster * mp->m_sb.sb_inopblock) { 175 fsino = XFS_AGINO_TO_INO(mp, bs->cur->bc_private.a.agno, agino); 176 chunkino = agino - irec->ir_startino; 177 agbno = XFS_AGINO_TO_AGBNO(mp, agino); 178 179 /* Compute the holemask mask for this cluster. */ 180 for (clusterino = 0, holemask = 0; clusterino < nr_inodes; 181 clusterino += XFS_INODES_PER_HOLEMASK_BIT) 182 holemask |= XFS_INOBT_MASK((chunkino + clusterino) / 183 XFS_INODES_PER_HOLEMASK_BIT); 184 185 /* The whole cluster must be a hole or not a hole. */ 186 ir_holemask = (irec->ir_holemask & holemask); 187 if (ir_holemask != holemask && ir_holemask != 0) { 188 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 189 continue; 190 } 191 192 /* If any part of this is a hole, skip it. */ 193 if (ir_holemask) 194 continue; 195 196 /* Grab the inode cluster buffer. */ 197 imap.im_blkno = XFS_AGB_TO_DADDR(mp, bs->cur->bc_private.a.agno, 198 agbno); 199 imap.im_len = XFS_FSB_TO_BB(mp, blks_per_cluster); 200 imap.im_boffset = 0; 201 202 error = xfs_imap_to_bp(mp, bs->cur->bc_tp, &imap, 203 &dip, &bp, 0, 0); 204 if (!xfs_scrub_btree_process_error(bs->sc, bs->cur, 0, &error)) 205 continue; 206 207 /* Which inodes are free? */ 208 for (clusterino = 0; clusterino < nr_inodes; clusterino++) { 209 error = xfs_scrub_iallocbt_check_cluster_freemask(bs, 210 fsino, chunkino, clusterino, irec, bp); 211 if (error) { 212 xfs_trans_brelse(bs->cur->bc_tp, bp); 213 return error; 214 } 215 } 216 217 xfs_trans_brelse(bs->cur->bc_tp, bp); 218 } 219 220 return error; 221 } 222 223 /* Scrub an inobt/finobt record. */ 224 STATIC int 225 xfs_scrub_iallocbt_rec( 226 struct xfs_scrub_btree *bs, 227 union xfs_btree_rec *rec) 228 { 229 struct xfs_mount *mp = bs->cur->bc_mp; 230 struct xfs_inobt_rec_incore irec; 231 uint64_t holes; 232 xfs_agnumber_t agno = bs->cur->bc_private.a.agno; 233 xfs_agino_t agino; 234 xfs_agblock_t agbno; 235 xfs_extlen_t len; 236 int holecount; 237 int i; 238 int error = 0; 239 unsigned int real_freecount; 240 uint16_t holemask; 241 242 xfs_inobt_btrec_to_irec(mp, rec, &irec); 243 244 if (irec.ir_count > XFS_INODES_PER_CHUNK || 245 irec.ir_freecount > XFS_INODES_PER_CHUNK) 246 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 247 248 real_freecount = irec.ir_freecount + 249 (XFS_INODES_PER_CHUNK - irec.ir_count); 250 if (real_freecount != xfs_scrub_iallocbt_freecount(irec.ir_free)) 251 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 252 253 agino = irec.ir_startino; 254 /* Record has to be properly aligned within the AG. */ 255 if (!xfs_verify_agino(mp, agno, agino) || 256 !xfs_verify_agino(mp, agno, agino + XFS_INODES_PER_CHUNK - 1)) { 257 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 258 goto out; 259 } 260 261 /* Make sure this record is aligned to cluster and inoalignmnt size. */ 262 agbno = XFS_AGINO_TO_AGBNO(mp, irec.ir_startino); 263 if ((agbno & (xfs_ialloc_cluster_alignment(mp) - 1)) || 264 (agbno & (xfs_icluster_size_fsb(mp) - 1))) 265 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 266 267 /* Handle non-sparse inodes */ 268 if (!xfs_inobt_issparse(irec.ir_holemask)) { 269 len = XFS_B_TO_FSB(mp, 270 XFS_INODES_PER_CHUNK * mp->m_sb.sb_inodesize); 271 if (irec.ir_count != XFS_INODES_PER_CHUNK) 272 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 273 274 if (!xfs_scrub_iallocbt_chunk(bs, &irec, agino, len)) 275 goto out; 276 goto check_freemask; 277 } 278 279 /* Check each chunk of a sparse inode cluster. */ 280 holemask = irec.ir_holemask; 281 holecount = 0; 282 len = XFS_B_TO_FSB(mp, 283 XFS_INODES_PER_HOLEMASK_BIT * mp->m_sb.sb_inodesize); 284 holes = ~xfs_inobt_irec_to_allocmask(&irec); 285 if ((holes & irec.ir_free) != holes || 286 irec.ir_freecount > irec.ir_count) 287 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 288 289 for (i = 0; i < XFS_INOBT_HOLEMASK_BITS; i++) { 290 if (holemask & 1) 291 holecount += XFS_INODES_PER_HOLEMASK_BIT; 292 else if (!xfs_scrub_iallocbt_chunk(bs, &irec, agino, len)) 293 break; 294 holemask >>= 1; 295 agino += XFS_INODES_PER_HOLEMASK_BIT; 296 } 297 298 if (holecount > XFS_INODES_PER_CHUNK || 299 holecount + irec.ir_count != XFS_INODES_PER_CHUNK) 300 xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); 301 302 check_freemask: 303 error = xfs_scrub_iallocbt_check_freemask(bs, &irec); 304 if (error) 305 goto out; 306 307 out: 308 return error; 309 } 310 311 /* Scrub the inode btrees for some AG. */ 312 STATIC int 313 xfs_scrub_iallocbt( 314 struct xfs_scrub_context *sc, 315 xfs_btnum_t which) 316 { 317 struct xfs_btree_cur *cur; 318 struct xfs_owner_info oinfo; 319 320 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INOBT); 321 cur = which == XFS_BTNUM_INO ? sc->sa.ino_cur : sc->sa.fino_cur; 322 return xfs_scrub_btree(sc, cur, xfs_scrub_iallocbt_rec, &oinfo, NULL); 323 } 324 325 int 326 xfs_scrub_inobt( 327 struct xfs_scrub_context *sc) 328 { 329 return xfs_scrub_iallocbt(sc, XFS_BTNUM_INO); 330 } 331 332 int 333 xfs_scrub_finobt( 334 struct xfs_scrub_context *sc) 335 { 336 return xfs_scrub_iallocbt(sc, XFS_BTNUM_FINO); 337 } 338