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_inode.h" 14 #include "xfs_log_format.h" 15 #include "xfs_trans.h" 16 #include "xfs_rtbitmap.h" 17 #include "xfs_bit.h" 18 #include "xfs_bmap.h" 19 #include "xfs_sb.h" 20 #include "xfs_exchmaps.h" 21 #include "scrub/scrub.h" 22 #include "scrub/common.h" 23 #include "scrub/trace.h" 24 #include "scrub/xfile.h" 25 #include "scrub/repair.h" 26 #include "scrub/tempexch.h" 27 #include "scrub/rtsummary.h" 28 29 /* 30 * Realtime Summary 31 * ================ 32 * 33 * We check the realtime summary by scanning the realtime bitmap file to create 34 * a new summary file incore, and then we compare the computed version against 35 * the ondisk version. We use the 'xfile' functionality to store this 36 * (potentially large) amount of data in pageable memory. 37 */ 38 39 /* Set us up to check the rtsummary file. */ 40 int 41 xchk_setup_rtsummary( 42 struct xfs_scrub *sc) 43 { 44 struct xfs_mount *mp = sc->mp; 45 char *descr; 46 struct xchk_rtsummary *rts; 47 int error; 48 49 rts = kvzalloc(struct_size(rts, words, mp->m_blockwsize), 50 XCHK_GFP_FLAGS); 51 if (!rts) 52 return -ENOMEM; 53 sc->buf = rts; 54 55 if (xchk_could_repair(sc)) { 56 error = xrep_setup_rtsummary(sc, rts); 57 if (error) 58 return error; 59 } 60 61 /* 62 * Create an xfile to construct a new rtsummary file. The xfile allows 63 * us to avoid pinning kernel memory for this purpose. 64 */ 65 descr = xchk_xfile_descr(sc, "realtime summary file"); 66 error = xfile_create(descr, mp->m_rsumsize, &sc->xfile); 67 kfree(descr); 68 if (error) 69 return error; 70 71 error = xchk_trans_alloc(sc, rts->resblks); 72 if (error) 73 return error; 74 75 error = xchk_install_live_inode(sc, mp->m_rsumip); 76 if (error) 77 return error; 78 79 error = xchk_ino_dqattach(sc); 80 if (error) 81 return error; 82 83 /* 84 * Locking order requires us to take the rtbitmap first. We must be 85 * careful to unlock it ourselves when we are done with the rtbitmap 86 * file since the scrub infrastructure won't do that for us. Only 87 * then we can lock the rtsummary inode. 88 */ 89 xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); 90 xchk_ilock(sc, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM); 91 92 /* 93 * Now that we've locked the rtbitmap and rtsummary, we can't race with 94 * growfsrt trying to expand the summary or change the size of the rt 95 * volume. Hence it is safe to compute and check the geometry values. 96 */ 97 if (mp->m_sb.sb_rblocks) { 98 xfs_filblks_t rsumblocks; 99 int rextslog; 100 101 rts->rextents = xfs_rtb_to_rtx(mp, mp->m_sb.sb_rblocks); 102 rextslog = xfs_compute_rextslog(rts->rextents); 103 rts->rsumlevels = rextslog + 1; 104 rts->rbmblocks = xfs_rtbitmap_blockcount(mp, rts->rextents); 105 rsumblocks = xfs_rtsummary_blockcount(mp, rts->rsumlevels, 106 rts->rbmblocks); 107 rts->rsumsize = XFS_FSB_TO_B(mp, rsumblocks); 108 } 109 return 0; 110 } 111 112 /* Helper functions to record suminfo words in an xfile. */ 113 114 static inline int 115 xfsum_load( 116 struct xfs_scrub *sc, 117 xfs_rtsumoff_t sumoff, 118 union xfs_suminfo_raw *rawinfo) 119 { 120 return xfile_load(sc->xfile, rawinfo, 121 sizeof(union xfs_suminfo_raw), 122 sumoff << XFS_WORDLOG); 123 } 124 125 static inline int 126 xfsum_store( 127 struct xfs_scrub *sc, 128 xfs_rtsumoff_t sumoff, 129 const union xfs_suminfo_raw rawinfo) 130 { 131 return xfile_store(sc->xfile, &rawinfo, 132 sizeof(union xfs_suminfo_raw), 133 sumoff << XFS_WORDLOG); 134 } 135 136 inline int 137 xfsum_copyout( 138 struct xfs_scrub *sc, 139 xfs_rtsumoff_t sumoff, 140 union xfs_suminfo_raw *rawinfo, 141 unsigned int nr_words) 142 { 143 return xfile_load(sc->xfile, rawinfo, nr_words << XFS_WORDLOG, 144 sumoff << XFS_WORDLOG); 145 } 146 147 static inline xfs_suminfo_t 148 xchk_rtsum_inc( 149 struct xfs_mount *mp, 150 union xfs_suminfo_raw *v) 151 { 152 v->old += 1; 153 return v->old; 154 } 155 156 /* Update the summary file to reflect the free extent that we've accumulated. */ 157 STATIC int 158 xchk_rtsum_record_free( 159 struct xfs_mount *mp, 160 struct xfs_trans *tp, 161 const struct xfs_rtalloc_rec *rec, 162 void *priv) 163 { 164 struct xfs_scrub *sc = priv; 165 xfs_fileoff_t rbmoff; 166 xfs_rtblock_t rtbno; 167 xfs_filblks_t rtlen; 168 xfs_rtsumoff_t offs; 169 unsigned int lenlog; 170 union xfs_suminfo_raw v; 171 xfs_suminfo_t value; 172 int error = 0; 173 174 if (xchk_should_terminate(sc, &error)) 175 return error; 176 177 /* Compute the relevant location in the rtsum file. */ 178 rbmoff = xfs_rtx_to_rbmblock(mp, rec->ar_startext); 179 lenlog = xfs_highbit64(rec->ar_extcount); 180 offs = xfs_rtsumoffs(mp, lenlog, rbmoff); 181 182 rtbno = xfs_rtx_to_rtb(mp, rec->ar_startext); 183 rtlen = xfs_rtx_to_rtb(mp, rec->ar_extcount); 184 185 if (!xfs_verify_rtbext(mp, rtbno, rtlen)) { 186 xchk_ino_xref_set_corrupt(sc, mp->m_rbmip->i_ino); 187 return -EFSCORRUPTED; 188 } 189 190 /* Bump the summary count. */ 191 error = xfsum_load(sc, offs, &v); 192 if (error) 193 return error; 194 195 value = xchk_rtsum_inc(sc->mp, &v); 196 trace_xchk_rtsum_record_free(mp, rec->ar_startext, rec->ar_extcount, 197 lenlog, offs, value); 198 199 return xfsum_store(sc, offs, v); 200 } 201 202 /* Compute the realtime summary from the realtime bitmap. */ 203 STATIC int 204 xchk_rtsum_compute( 205 struct xfs_scrub *sc) 206 { 207 struct xfs_mount *mp = sc->mp; 208 unsigned long long rtbmp_blocks; 209 210 /* If the bitmap size doesn't match the computed size, bail. */ 211 rtbmp_blocks = xfs_rtbitmap_blockcount(mp, mp->m_sb.sb_rextents); 212 if (XFS_FSB_TO_B(mp, rtbmp_blocks) != mp->m_rbmip->i_disk_size) 213 return -EFSCORRUPTED; 214 215 return xfs_rtalloc_query_all(sc->mp, sc->tp, xchk_rtsum_record_free, 216 sc); 217 } 218 219 /* Compare the rtsummary file against the one we computed. */ 220 STATIC int 221 xchk_rtsum_compare( 222 struct xfs_scrub *sc) 223 { 224 struct xfs_bmbt_irec map; 225 struct xfs_iext_cursor icur; 226 227 struct xfs_mount *mp = sc->mp; 228 struct xfs_inode *ip = sc->ip; 229 struct xchk_rtsummary *rts = sc->buf; 230 xfs_fileoff_t off = 0; 231 xfs_fileoff_t endoff; 232 xfs_rtsumoff_t sumoff = 0; 233 int error = 0; 234 235 rts->args.mp = sc->mp; 236 rts->args.tp = sc->tp; 237 238 /* Mappings may not cross or lie beyond EOF. */ 239 endoff = XFS_B_TO_FSB(mp, ip->i_disk_size); 240 if (xfs_iext_lookup_extent(ip, &ip->i_df, endoff, &icur, &map)) { 241 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, endoff); 242 return 0; 243 } 244 245 while (off < endoff) { 246 int nmap = 1; 247 248 if (xchk_should_terminate(sc, &error)) 249 return error; 250 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 251 return 0; 252 253 /* Make sure we have a written extent. */ 254 error = xfs_bmapi_read(ip, off, endoff - off, &map, &nmap, 255 XFS_DATA_FORK); 256 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, off, &error)) 257 return error; 258 259 if (nmap != 1 || !xfs_bmap_is_written_extent(&map)) { 260 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, off); 261 return 0; 262 } 263 264 off += map.br_blockcount; 265 } 266 267 for (off = 0; off < endoff; off++) { 268 union xfs_suminfo_raw *ondisk_info; 269 270 /* Read a block's worth of ondisk rtsummary file. */ 271 error = xfs_rtsummary_read_buf(&rts->args, off); 272 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, off, &error)) 273 return error; 274 275 /* Read a block's worth of computed rtsummary file. */ 276 error = xfsum_copyout(sc, sumoff, rts->words, mp->m_blockwsize); 277 if (error) { 278 xfs_rtbuf_cache_relse(&rts->args); 279 return error; 280 } 281 282 ondisk_info = xfs_rsumblock_infoptr(&rts->args, 0); 283 if (memcmp(ondisk_info, rts->words, 284 mp->m_blockwsize << XFS_WORDLOG) != 0) { 285 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, off); 286 xfs_rtbuf_cache_relse(&rts->args); 287 return error; 288 } 289 290 xfs_rtbuf_cache_relse(&rts->args); 291 sumoff += mp->m_blockwsize; 292 } 293 294 return 0; 295 } 296 297 /* Scrub the realtime summary. */ 298 int 299 xchk_rtsummary( 300 struct xfs_scrub *sc) 301 { 302 struct xfs_mount *mp = sc->mp; 303 struct xchk_rtsummary *rts = sc->buf; 304 int error = 0; 305 306 /* Is sb_rextents correct? */ 307 if (mp->m_sb.sb_rextents != rts->rextents) { 308 xchk_ino_set_corrupt(sc, mp->m_rbmip->i_ino); 309 goto out_rbm; 310 } 311 312 /* Is m_rsumlevels correct? */ 313 if (mp->m_rsumlevels != rts->rsumlevels) { 314 xchk_ino_set_corrupt(sc, mp->m_rsumip->i_ino); 315 goto out_rbm; 316 } 317 318 /* Is m_rsumsize correct? */ 319 if (mp->m_rsumsize != rts->rsumsize) { 320 xchk_ino_set_corrupt(sc, mp->m_rsumip->i_ino); 321 goto out_rbm; 322 } 323 324 /* The summary file length must be aligned to an fsblock. */ 325 if (mp->m_rsumip->i_disk_size & mp->m_blockmask) { 326 xchk_ino_set_corrupt(sc, mp->m_rsumip->i_ino); 327 goto out_rbm; 328 } 329 330 /* 331 * Is the summary file itself large enough to handle the rt volume? 332 * growfsrt expands the summary file before updating sb_rextents, so 333 * the file can be larger than rsumsize. 334 */ 335 if (mp->m_rsumip->i_disk_size < rts->rsumsize) { 336 xchk_ino_set_corrupt(sc, mp->m_rsumip->i_ino); 337 goto out_rbm; 338 } 339 340 /* Invoke the fork scrubber. */ 341 error = xchk_metadata_inode_forks(sc); 342 if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) 343 goto out_rbm; 344 345 /* Construct the new summary file from the rtbitmap. */ 346 error = xchk_rtsum_compute(sc); 347 if (error == -EFSCORRUPTED) { 348 /* 349 * EFSCORRUPTED means the rtbitmap is corrupt, which is an xref 350 * error since we're checking the summary file. 351 */ 352 xchk_ino_xref_set_corrupt(sc, mp->m_rbmip->i_ino); 353 error = 0; 354 goto out_rbm; 355 } 356 if (error) 357 goto out_rbm; 358 359 /* Does the computed summary file match the actual rtsummary file? */ 360 error = xchk_rtsum_compare(sc); 361 362 out_rbm: 363 /* 364 * Unlock the rtbitmap since we're done with it. All other writers of 365 * the rt free space metadata grab the bitmap and summary ILOCKs in 366 * that order, so we're still protected against allocation activities 367 * even if we continue on to the repair function. 368 */ 369 xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); 370 return error; 371 } 372