Lines Matching +full:re +full:- +full:attached
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2022-2023 Oracle. All Rights Reserved.
84 * the btree we're trying to rebuild and the block is indeed owned by another
92 * state while we're not looking. We must also invalidate any buffers
122 /* Number of deferred reaps attached to the current transaction. */
144 * Since we're "freeing" a lost block onto the AGFL, we have to in xreap_put_freelist()
148 error = xfs_rmap_alloc(sc->tp, sc->sa.agf_bp, sc->sa.pag, agbno, 1, in xreap_put_freelist()
154 error = xfs_alloc_read_agfl(sc->sa.pag, sc->tp, &agfl_bp); in xreap_put_freelist()
158 error = xfs_alloc_put_freelist(sc->sa.pag, sc->tp, sc->sa.agf_bp, in xreap_put_freelist()
162 xfs_extent_busy_insert(sc->tp, pag_group(sc->sa.pag), agbno, 1, in xreap_put_freelist()
171 return rs->nr_binval > 0 || rs->nr_deferred > 0; in xreap_is_dirty()
180 return rs->nr_binval >= rs->max_binval; in xreap_want_binval_roll()
186 rs->nr_binval = 0; in xreap_binval_reset()
195 rs->nr_binval++; in xreap_inc_binval()
196 return rs->nr_binval < rs->max_binval; in xreap_inc_binval()
200 * Decide if we want to finish the deferred ops that are attached to the scrub
208 return rs->nr_deferred >= rs->max_deferred; in xreap_want_defer_finish()
217 rs->nr_deferred = 0; in xreap_defer_finish_reset()
218 rs->nr_binval = 0; in xreap_defer_finish_reset()
226 rs->nr_deferred++; in xreap_inc_defer()
232 rs->nr_deferred = rs->max_deferred; in xreap_force_defer_finish()
266 scan->__sector_count += scan->daddr_step; in xrep_bufscan_advance()
267 while (scan->__sector_count <= scan->max_sectors) { in xrep_bufscan_advance()
271 error = xfs_buf_incore(mp->m_ddev_targp, scan->daddr, in xrep_bufscan_advance()
272 scan->__sector_count, XBF_LIVESCAN, &bp); in xrep_bufscan_advance()
276 scan->__sector_count += scan->daddr_step; in xrep_bufscan_advance()
282 /* Try to invalidate the incore buffers for an extent that we're freeing. */
289 struct xfs_scrub *sc = rs->sc; in xreap_agextent_binval()
290 struct xfs_perag *pag = sc->sa.pag; in xreap_agextent_binval()
291 struct xfs_mount *mp = sc->mp; in xreap_agextent_binval()
296 * Avoid invalidating AG headers and post-EOFS blocks because we never in xreap_agextent_binval()
300 !xfs_verify_agbno(pag, agbno_next - 1)) in xreap_agextent_binval()
314 agbno_next - bno), in xreap_agextent_binval()
320 xfs_trans_bjoin(sc->tp, bp); in xreap_agextent_binval()
321 xfs_trans_binval(sc->tp, bp); in xreap_agextent_binval()
329 *aglenp -= agbno_next - bno; in xreap_agextent_binval()
338 trace_xreap_agextent_binval(pag_group(sc->sa.pag), agbno, *aglenp); in xreap_agextent_binval()
343 * call. Cross-linked blocks should have their reverse mappings removed, but
344 * single-owner extents can be freed. AGFL blocks can only be put back one at
355 struct xfs_scrub *sc = rs->sc; in xreap_agextent_select()
365 cur = xfs_rmapbt_init_cursor(sc->mp, sc->tp, sc->sa.agf_bp, in xreap_agextent_select()
366 sc->sa.pag); in xreap_agextent_select()
367 error = xfs_rmap_has_other_keys(cur, agbno, 1, rs->oinfo, in xreap_agextent_select()
373 if (rs->resv == XFS_AG_RESV_AGFL) in xreap_agextent_select()
383 error = xfs_rmap_has_other_keys(cur, bno, 1, rs->oinfo, in xreap_agextent_select()
397 trace_xreap_agextent_select(pag_group(sc->sa.pag), agbno, len, in xreap_agextent_select()
415 struct xfs_scrub *sc = rs->sc; in xreap_agextent_iter()
419 ASSERT(rs->resv != XFS_AG_RESV_METAFILE); in xreap_agextent_iter()
421 fsbno = xfs_agbno_to_fsb(sc->sa.pag, agbno); in xreap_agextent_iter()
430 * metadata structure is crosslinked with a multi-block structure in xreap_agextent_iter()
437 trace_xreap_dispose_unmap_extent(pag_group(sc->sa.pag), agbno, in xreap_agextent_iter()
440 if (rs->oinfo == &XFS_RMAP_OINFO_COW) { in xreap_agextent_iter()
446 xfs_refcount_free_cow_extent(sc->tp, false, fsbno, in xreap_agextent_iter()
453 xfs_rmap_free_extent(sc->tp, false, fsbno, *aglenp, in xreap_agextent_iter()
454 rs->oinfo->oi_owner); in xreap_agextent_iter()
459 trace_xreap_dispose_free_extent(pag_group(sc->sa.pag), agbno, *aglenp); in xreap_agextent_iter()
476 * and free the extent. We're not worried about the system going down in xreap_agextent_iter()
480 if (rs->oinfo == &XFS_RMAP_OINFO_COW) { in xreap_agextent_iter()
481 ASSERT(rs->resv == XFS_AG_RESV_NONE); in xreap_agextent_iter()
483 xfs_refcount_free_cow_extent(sc->tp, false, fsbno, *aglenp); in xreap_agextent_iter()
484 error = xfs_free_extent_later(sc->tp, fsbno, *aglenp, NULL, in xreap_agextent_iter()
485 rs->resv, XFS_FREE_EXTENT_SKIP_DISCARD); in xreap_agextent_iter()
494 if (rs->resv == XFS_AG_RESV_AGFL) { in xreap_agextent_iter()
510 error = xfs_free_extent_later(sc->tp, fsbno, *aglenp, rs->oinfo, in xreap_agextent_iter()
511 rs->resv, XFS_FREE_EXTENT_SKIP_DISCARD); in xreap_agextent_iter()
516 if (rs->nr_deferred % 2 == 0) in xreap_agextent_iter()
517 xfs_defer_add_barrier(sc->tp); in xreap_agextent_iter()
530 struct xfs_scrub *sc = rs->sc; in xreap_configure_limits()
531 unsigned int res = sc->tp->t_log_res - fixed_overhead; in xreap_configure_limits()
534 if (sc->tp->t_log_res < (fixed_overhead + variable_overhead)) { in xreap_configure_limits()
535 ASSERT(sc->tp->t_log_res >= in xreap_configure_limits()
537 xfs_force_shutdown(sc->mp, SHUTDOWN_CORRUPT_INCORE); in xreap_configure_limits()
541 rs->max_deferred = per_intent ? res / variable_overhead : 0; in xreap_configure_limits()
542 res -= rs->max_deferred * per_intent; in xreap_configure_limits()
543 rs->max_binval = per_binval ? res / per_binval : 0; in xreap_configure_limits()
549 * needed to reap a single per-AG space extent. This is not for freeing CoW
556 struct xfs_scrub *sc = rs->sc; in xreap_configure_agextent_limits()
557 struct xfs_mount *mp = sc->mp; in xreap_configure_agextent_limits()
561 * item and a done item to be attached to a transaction for each extent in xreap_configure_agextent_limits()
570 * Various things can happen when reaping non-CoW metadata blocks: in xreap_configure_agextent_limits()
581 * For simplicity, we'll use the worst-case intents size to determine in xreap_configure_agextent_limits()
583 * whole chain. If we're trying to reap a btree larger than this size, in xreap_configure_agextent_limits()
621 trace_xreap_agextent_limits(sc->tp, per_binval, rs->max_binval, in xreap_configure_agextent_limits()
622 step_size, per_intent, rs->max_deferred); in xreap_configure_agextent_limits()
635 struct xfs_scrub *sc = rs->sc; in xreap_configure_agcow_limits()
636 struct xfs_mount *mp = sc->mp; in xreap_configure_agcow_limits()
640 * item and a done item to be attached to a transaction for each extent in xreap_configure_agcow_limits()
651 * Various things can happen when reaping non-CoW metadata blocks: in xreap_configure_agcow_limits()
659 * For simplicity, we'll use the worst-case intents size to determine in xreap_configure_agcow_limits()
661 * whole chain. If we're trying to reap a btree larger than this size, in xreap_configure_agcow_limits()
699 trace_xreap_agcow_limits(sc->tp, per_binval, rs->max_binval, step_size, in xreap_configure_agcow_limits()
700 per_intent, rs->max_deferred); in xreap_configure_agcow_limits()
704 * Break an AG metadata extent into sub-extents by fate (crosslinked, not
705 * crosslinked), and dispose of each sub-extent separately.
714 struct xfs_scrub *sc = rs->sc; in xreap_agmeta_extent()
719 ASSERT(sc->ip == NULL); in xreap_agmeta_extent()
767 ASSERT(xfs_has_rmapbt(sc->mp)); in xrep_reap_agblocks()
768 ASSERT(sc->ip == NULL); in xrep_reap_agblocks()
782 * Break a file metadata extent into sub-extents by fate (crosslinked, not
783 * crosslinked), and dispose of each sub-extent separately. The extent must
793 struct xfs_scrub *sc = rs->sc; in xreap_fsmeta_extent()
794 xfs_agnumber_t agno = XFS_FSB_TO_AGNO(sc->mp, fsbno); in xreap_fsmeta_extent()
795 xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(sc->mp, fsbno); in xreap_fsmeta_extent()
800 ASSERT(sc->ip != NULL); in xreap_fsmeta_extent()
801 ASSERT(!sc->sa.pag); in xreap_fsmeta_extent()
804 * We're reaping blocks after repairing file metadata, which means that in xreap_fsmeta_extent()
807 sc->sa.pag = xfs_perag_get(sc->mp, agno); in xreap_fsmeta_extent()
808 if (!sc->sa.pag) in xreap_fsmeta_extent()
809 return -EFSCORRUPTED; in xreap_fsmeta_extent()
811 error = xfs_alloc_read_agf(sc->sa.pag, sc->tp, 0, &sc->sa.agf_bp); in xreap_fsmeta_extent()
843 xfs_trans_bhold(sc->tp, sc->sa.agf_bp); in xreap_fsmeta_extent()
844 error = xfs_trans_roll_inode(&sc->tp, sc->ip); in xreap_fsmeta_extent()
845 xfs_trans_bjoin(sc->tp, sc->sa.agf_bp); in xreap_fsmeta_extent()
855 xfs_trans_brelse(sc->tp, sc->sa.agf_bp); in xreap_fsmeta_extent()
856 sc->sa.agf_bp = NULL; in xreap_fsmeta_extent()
858 xfs_perag_put(sc->sa.pag); in xreap_fsmeta_extent()
859 sc->sa.pag = NULL; in xreap_fsmeta_extent()
880 ASSERT(xfs_has_rmapbt(sc->mp)); in xrep_reap_fsblocks()
881 ASSERT(sc->ip != NULL); in xrep_reap_fsblocks()
900 * call. Cross-linked blocks should have their reverse mappings removed, but
901 * single-owner extents can be freed. Units are rt blocks, not rt extents.
911 struct xfs_scrub *sc = rs->sc; in xreap_rgextent_select()
921 cur = xfs_rtrmapbt_init_cursor(sc->tp, sc->sr.rtg); in xreap_rgextent_select()
922 error = xfs_rmap_has_other_keys(cur, rgbno, 1, rs->oinfo, in xreap_rgextent_select()
934 error = xfs_rmap_has_other_keys(cur, bno, 1, rs->oinfo, in xreap_rgextent_select()
947 trace_xreap_agextent_select(rtg_group(sc->sr.rtg), rgbno, len, in xreap_rgextent_select()
965 struct xfs_scrub *sc = rs->sc; in xreap_rgextent_iter()
974 if (rs->oinfo != &XFS_RMAP_OINFO_COW) { in xreap_rgextent_iter()
975 ASSERT(rs->oinfo == &XFS_RMAP_OINFO_COW); in xreap_rgextent_iter()
976 return -EFSCORRUPTED; in xreap_rgextent_iter()
978 ASSERT(rs->resv == XFS_AG_RESV_NONE); in xreap_rgextent_iter()
980 rtbno = xfs_rgbno_to_rtb(sc->sr.rtg, rgbno); in xreap_rgextent_iter()
987 trace_xreap_dispose_unmap_extent(rtg_group(sc->sr.rtg), rgbno, in xreap_rgextent_iter()
990 xfs_refcount_free_cow_extent(sc->tp, true, rtbno, *rglenp); in xreap_rgextent_iter()
995 trace_xreap_dispose_free_extent(rtg_group(sc->sr.rtg), rgbno, *rglenp); in xreap_rgextent_iter()
1000 * and free the extent. We're not worried about the system going down in xreap_rgextent_iter()
1004 xfs_refcount_free_cow_extent(sc->tp, true, rtbno, *rglenp); in xreap_rgextent_iter()
1005 error = xfs_free_extent_later(sc->tp, rtbno, *rglenp, NULL, in xreap_rgextent_iter()
1006 rs->resv, in xreap_rgextent_iter()
1026 struct xfs_scrub *sc = rs->sc; in xreap_configure_rgcow_limits()
1027 struct xfs_mount *mp = sc->mp; in xreap_configure_rgcow_limits()
1031 * item and a done item to be attached to a transaction for each extent in xreap_configure_rgcow_limits()
1042 * Various things can happen when reaping non-CoW metadata blocks: in xreap_configure_rgcow_limits()
1050 * For simplicity, we'll use the worst-case intents size to determine in xreap_configure_rgcow_limits()
1052 * whole chain. If we're trying to reap a btree larger than this size, in xreap_configure_rgcow_limits()
1075 trace_xreap_rgcow_limits(sc->tp, 0, 0, step_size, per_intent, in xreap_configure_rgcow_limits()
1076 rs->max_deferred); in xreap_configure_rgcow_limits()
1084 * Break a rt file metadata extent into sub-extents by fate (crosslinked, not
1085 * crosslinked), and dispose of each sub-extent separately. The extent must
1095 struct xfs_scrub *sc = rs->sc; in xreap_rtmeta_extent()
1096 xfs_rgblock_t rgbno = xfs_rtb_to_rgbno(sc->mp, rtbno); in xreap_rtmeta_extent()
1100 ASSERT(sc->ip != NULL); in xreap_rtmeta_extent()
1101 ASSERT(!sc->sr.rtg); in xreap_rtmeta_extent()
1104 * We're reaping blocks after repairing file metadata, which means that in xreap_rtmeta_extent()
1107 sc->sr.rtg = xfs_rtgroup_get(sc->mp, xfs_rtb_to_rgno(sc->mp, rtbno)); in xreap_rtmeta_extent()
1108 if (!sc->sr.rtg) in xreap_rtmeta_extent()
1109 return -EFSCORRUPTED; in xreap_rtmeta_extent()
1111 xfs_rtgroup_lock(sc->sr.rtg, XREAP_RTGLOCK_ALL); in xreap_rtmeta_extent()
1127 error = xfs_defer_finish(&sc->tp); in xreap_rtmeta_extent()
1132 error = xfs_trans_roll_inode(&sc->tp, sc->ip); in xreap_rtmeta_extent()
1142 xfs_rtgroup_unlock(sc->sr.rtg, XREAP_RTGLOCK_ALL); in xreap_rtmeta_extent()
1143 xfs_rtgroup_put(sc->sr.rtg); in xreap_rtmeta_extent()
1144 sc->sr.rtg = NULL; in xreap_rtmeta_extent()
1165 ASSERT(xfs_has_rmapbt(sc->mp)); in xrep_reap_rtblocks()
1166 ASSERT(sc->ip != NULL); in xrep_reap_rtblocks()
1203 ASSERT(xfs_has_rmapbt(sc->mp)); in xrep_reap_metadir_fsblocks()
1204 ASSERT(sc->ip != NULL); in xrep_reap_metadir_fsblocks()
1205 ASSERT(xfs_is_metadir_inode(sc->ip)); in xrep_reap_metadir_fsblocks()
1208 xfs_rmap_ino_bmbt_owner(&oinfo, sc->ip->i_ino, XFS_DATA_FORK); in xrep_reap_metadir_fsblocks()
1227 * This first step determines the longest subset of the passed-in imap
1238 struct xfs_scrub *sc = rs->sc; in xreap_bmapi_select()
1246 agbno = XFS_FSB_TO_AGBNO(sc->mp, imap->br_startblock); in xreap_bmapi_select()
1247 agbno_next = agbno + imap->br_blockcount; in xreap_bmapi_select()
1249 cur = xfs_rmapbt_init_cursor(sc->mp, sc->tp, sc->sa.agf_bp, in xreap_bmapi_select()
1250 sc->sa.pag); in xreap_bmapi_select()
1252 xfs_rmap_ino_owner(&oinfo, rs->ip->i_ino, rs->whichfork, in xreap_bmapi_select()
1253 imap->br_startoff); in xreap_bmapi_select()
1275 imap->br_blockcount = len; in xreap_bmapi_select()
1276 trace_xreap_bmapi_select(pag_group(sc->sa.pag), agbno, len, in xreap_bmapi_select()
1296 for (i = 0; i < bp->b_map_count; i++) { in xreap_buf_loggable()
1300 chunks = DIV_ROUND_UP(BBTOB(bp->b_maps[i].bm_len), in xreap_buf_loggable()
1319 struct xfs_scrub *sc = rs->sc; in xreap_bmapi_binval()
1320 struct xfs_mount *mp = sc->mp; in xreap_bmapi_binval()
1321 struct xfs_perag *pag = sc->sa.pag; in xreap_bmapi_binval()
1322 int bmap_flags = xfs_bmapi_aflag(rs->whichfork); in xreap_bmapi_binval()
1332 * Avoid invalidating AG headers and post-EOFS blocks because we never in xreap_bmapi_binval()
1335 agbno = bno = XFS_FSB_TO_AGBNO(sc->mp, imap->br_startblock); in xreap_bmapi_binval()
1336 agbno_next = agbno + imap->br_blockcount; in xreap_bmapi_binval()
1338 !xfs_verify_agbno(pag, agbno_next - 1)) in xreap_bmapi_binval()
1349 off = imap->br_startoff + imap->br_blockcount; in xreap_bmapi_binval()
1355 error = xfs_bmapi_read(rs->ip, off, max_off - off, &hmap, in xreap_bmapi_binval()
1361 return -EFSCORRUPTED; in xreap_bmapi_binval()
1369 scan_blocks = off - imap->br_startoff; in xreap_bmapi_binval()
1390 xfs_trans_bjoin(sc->tp, bp); in xreap_bmapi_binval()
1391 xfs_trans_binval(sc->tp, bp); in xreap_bmapi_binval()
1403 imap->br_blockcount = agbno_next - bno; in xreap_bmapi_binval()
1409 scan_blocks--; in xreap_bmapi_binval()
1413 trace_xreap_bmapi_binval(pag_group(sc->sa.pag), agbno, in xreap_bmapi_binval()
1414 imap->br_blockcount); in xreap_bmapi_binval()
1420 * The number of blocks disposed of is returned in @imap->br_blockcount.
1428 struct xfs_scrub *sc = rs->sc; in xrep_reap_bmapi_iter()
1440 trace_xreap_dispose_unmap_extent(pag_group(sc->sa.pag), in xrep_reap_bmapi_iter()
1441 XFS_FSB_TO_AGBNO(sc->mp, imap->br_startblock), in xrep_reap_bmapi_iter()
1442 imap->br_blockcount); in xrep_reap_bmapi_iter()
1449 xfs_bmap_unmap_extent(sc->tp, rs->ip, rs->whichfork, imap); in xrep_reap_bmapi_iter()
1450 xfs_trans_mod_dquot_byino(sc->tp, rs->ip, XFS_TRANS_DQ_BCOUNT, in xrep_reap_bmapi_iter()
1451 -(int64_t)imap->br_blockcount); in xrep_reap_bmapi_iter()
1452 xfs_rmap_unmap_extent(sc->tp, rs->ip, rs->whichfork, imap); in xrep_reap_bmapi_iter()
1463 trace_xreap_dispose_free_extent(pag_group(sc->sa.pag), in xrep_reap_bmapi_iter()
1464 XFS_FSB_TO_AGBNO(sc->mp, imap->br_startblock), in xrep_reap_bmapi_iter()
1465 imap->br_blockcount); in xrep_reap_bmapi_iter()
1474 if (error || imap->br_blockcount == 0) in xrep_reap_bmapi_iter()
1482 xfs_bmap_unmap_extent(sc->tp, rs->ip, rs->whichfork, imap); in xrep_reap_bmapi_iter()
1483 xfs_trans_mod_dquot_byino(sc->tp, rs->ip, XFS_TRANS_DQ_BCOUNT, in xrep_reap_bmapi_iter()
1484 -(int64_t)imap->br_blockcount); in xrep_reap_bmapi_iter()
1485 return xfs_free_extent_later(sc->tp, imap->br_startblock, in xrep_reap_bmapi_iter()
1486 imap->br_blockcount, NULL, XFS_AG_RESV_NONE, in xrep_reap_bmapi_iter()
1496 if (sc->sm->sm_type == XFS_SCRUB_TYPE_DIR) in xreap_bmapi_binval_mapcount()
1497 return sc->mp->m_dir_geo->fsbcount; in xreap_bmapi_binval_mapcount()
1508 switch (sc->sm->sm_type) { in xreap_bmapi_binval_blocksize()
1510 return sc->mp->m_dir_geo->blksize; in xreap_bmapi_binval_blocksize()
1521 return sc->mp->m_sb.sb_blocksize; in xreap_bmapi_binval_blocksize()
1532 struct xfs_scrub *sc = rs->sc; in xreap_configure_bmapi_limits()
1533 struct xfs_mount *mp = sc->mp; in xreap_configure_bmapi_limits()
1542 * item and a done item to be attached to a transaction for each extent in xreap_configure_bmapi_limits()
1585 trace_xreap_bmapi_limits(sc->tp, per_binval, rs->max_binval, in xreap_configure_bmapi_limits()
1598 struct xfs_scrub *sc = rs->sc; in xreap_ifork_extent()
1603 ASSERT(sc->sa.pag == NULL); in xreap_ifork_extent()
1605 trace_xreap_ifork_extent(sc, rs->ip, rs->whichfork, imap); in xreap_ifork_extent()
1607 agno = XFS_FSB_TO_AGNO(sc->mp, imap->br_startblock); in xreap_ifork_extent()
1608 sc->sa.pag = xfs_perag_get(sc->mp, agno); in xreap_ifork_extent()
1609 if (!sc->sa.pag) in xreap_ifork_extent()
1610 return -EFSCORRUPTED; in xreap_ifork_extent()
1612 error = xfs_alloc_read_agf(sc->sa.pag, sc->tp, 0, &sc->sa.agf_bp); in xreap_ifork_extent()
1629 xfs_trans_brelse(sc->tp, sc->sa.agf_bp); in xreap_ifork_extent()
1630 sc->sa.agf_bp = NULL; in xreap_ifork_extent()
1632 xfs_perag_put(sc->sa.pag); in xreap_ifork_extent()
1633 sc->sa.pag = NULL; in xreap_ifork_extent()
1639 * must hold ILOCK_EXCL, and ip can only be sc->ip or sc->tempip. The fork
1657 ASSERT(xfs_has_rmapbt(sc->mp)); in xrep_reap_ifork()
1658 ASSERT(ip == sc->ip || ip == sc->tempip); in xrep_reap_ifork()
1667 error = xfs_bmapi_read(ip, off, XFS_MAX_FILEOFF - off, &imap, in xrep_reap_ifork()
1673 return -EFSCORRUPTED; in xrep_reap_ifork()
1685 error = xfs_defer_finish(&sc->tp); in xrep_reap_ifork()