Lines Matching +full:sub +full:- +full:blocks

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2018-2023 Oracle. All Rights Reserved.
58 * told us to fix it. This function returns -EAGAIN to mean "re-run scrub",
69 trace_xrep_attempt(XFS_I(file_inode(sc->file)), sc->sm, error); in xrep_attempt()
71 xchk_ag_btcur_free(&sc->sa); in xrep_attempt()
72 xchk_rtgroup_btcur_free(&sc->sr); in xrep_attempt()
75 ASSERT(sc->ops->repair); in xrep_attempt()
76 run->repair_attempted = true; in xrep_attempt()
78 error = sc->ops->repair(sc); in xrep_attempt()
79 trace_xrep_done(XFS_I(file_inode(sc->file)), sc->sm, error); in xrep_attempt()
80 run->repair_ns += xchk_stats_elapsed_ns(repair_start); in xrep_attempt()
87 sc->sm->sm_flags &= ~XFS_SCRUB_FLAGS_OUT; in xrep_attempt()
88 sc->flags |= XREP_ALREADY_FIXED; in xrep_attempt()
89 run->repair_succeeded = true; in xrep_attempt()
90 return -EAGAIN; in xrep_attempt()
91 case -ECHRNG: in xrep_attempt()
92 sc->flags |= XCHK_NEED_DRAIN; in xrep_attempt()
93 run->retries++; in xrep_attempt()
94 return -EAGAIN; in xrep_attempt()
95 case -EDEADLOCK: in xrep_attempt()
97 if (!(sc->flags & XCHK_TRY_HARDER)) { in xrep_attempt()
98 sc->flags |= XCHK_TRY_HARDER; in xrep_attempt()
99 run->retries++; in xrep_attempt()
100 return -EAGAIN; in xrep_attempt()
110 * EAGAIN tells the caller to re-scrub, so we cannot return in xrep_attempt()
113 ASSERT(error != -EAGAIN); in xrep_attempt()
122 * administrator isn't running xfs_scrub in no-repairs mode.
136 * Repair probe -- userspace uses this to probe if we're willing to repair a
170 if (sc->sa.agi_bp) { in xrep_roll_ag_trans()
171 xfs_ialloc_log_agi(sc->tp, sc->sa.agi_bp, XFS_AGI_MAGICNUM); in xrep_roll_ag_trans()
172 xfs_trans_bhold(sc->tp, sc->sa.agi_bp); in xrep_roll_ag_trans()
175 if (sc->sa.agf_bp) { in xrep_roll_ag_trans()
176 xfs_alloc_log_agf(sc->tp, sc->sa.agf_bp, XFS_AGF_MAGICNUM); in xrep_roll_ag_trans()
177 xfs_trans_bhold(sc->tp, sc->sa.agf_bp); in xrep_roll_ag_trans()
186 error = xfs_trans_roll(&sc->tp); in xrep_roll_ag_trans()
191 if (sc->sa.agi_bp) in xrep_roll_ag_trans()
192 xfs_trans_bjoin(sc->tp, sc->sa.agi_bp); in xrep_roll_ag_trans()
193 if (sc->sa.agf_bp) in xrep_roll_ag_trans()
194 xfs_trans_bjoin(sc->tp, sc->sa.agf_bp); in xrep_roll_ag_trans()
204 if (!sc->ip) in xrep_roll_trans()
206 return xfs_trans_roll_inode(&sc->tp, sc->ip); in xrep_roll_trans()
225 if (sc->sa.agi_bp) { in xrep_defer_finish()
226 xfs_ialloc_log_agi(sc->tp, sc->sa.agi_bp, XFS_AGI_MAGICNUM); in xrep_defer_finish()
227 xfs_trans_bhold(sc->tp, sc->sa.agi_bp); in xrep_defer_finish()
230 if (sc->sa.agf_bp) { in xrep_defer_finish()
231 xfs_alloc_log_agf(sc->tp, sc->sa.agf_bp, XFS_AGF_MAGICNUM); in xrep_defer_finish()
232 xfs_trans_bhold(sc->tp, sc->sa.agf_bp); in xrep_defer_finish()
242 error = xfs_defer_finish(&sc->tp); in xrep_defer_finish()
251 if (sc->sa.agi_bp) in xrep_defer_finish()
252 xfs_trans_bhold_release(sc->tp, sc->sa.agi_bp); in xrep_defer_finish()
253 if (sc->sa.agf_bp) in xrep_defer_finish()
254 xfs_trans_bhold_release(sc->tp, sc->sa.agf_bp); in xrep_defer_finish()
272 pag->pagf_freeblks > xfs_ag_resv_needed(pag, type) + nr_blocks; in xrep_ag_has_space()
276 * Figure out how many blocks to reserve for an AG repair. We calculate the
277 * worst case estimate for the number of blocks we'd need to rebuild one of
278 * any type of per-AG btree.
284 struct xfs_mount *mp = sc->mp; in xrep_calc_ag_resblks()
285 struct xfs_scrub_metadata *sm = sc->sm; in xrep_calc_ag_resblks()
298 if (!(sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR)) in xrep_calc_ag_resblks()
301 pag = xfs_perag_get(mp, sm->sm_agno); in xrep_calc_ag_resblks()
303 /* Use in-core icount if possible. */ in xrep_calc_ag_resblks()
304 icount = pag->pagi_count; in xrep_calc_ag_resblks()
309 icount = pag->pagi_count; in xrep_calc_ag_resblks()
317 aglen = pag_group(pag)->xg_block_count; in xrep_calc_ag_resblks()
321 struct xfs_agf *agf = bp->b_addr; in xrep_calc_ag_resblks()
323 aglen = be32_to_cpu(agf->agf_length); in xrep_calc_ag_resblks()
324 freelen = be32_to_cpu(agf->agf_freeblks); in xrep_calc_ag_resblks()
325 usedlen = aglen - freelen; in xrep_calc_ag_resblks()
329 /* If the icount is impossible, make some worst-case assumptions. */ in xrep_calc_ag_resblks()
332 icount = pag->agino_max - pag->agino_min + 1; in xrep_calc_ag_resblks()
335 /* If the block counts are impossible, make worst-case assumptions. */ in xrep_calc_ag_resblks()
337 aglen != pag_group(pag)->xg_block_count || in xrep_calc_ag_resblks()
339 aglen = pag_group(pag)->xg_block_count; in xrep_calc_ag_resblks()
347 * Figure out how many blocks we'd need worst case to rebuild in xrep_calc_ag_resblks()
366 * Guess how many blocks we need to rebuild the rmapbt. in xrep_calc_ag_resblks()
367 * For non-reflink filesystems we can't have more records than in xrep_calc_ag_resblks()
368 * used blocks. However, with reflink it's possible to have in xrep_calc_ag_resblks()
371 * what we hope is an generous over-estimation. in xrep_calc_ag_resblks()
391 * Figure out how many blocks to reserve for a rtgroup repair. We calculate
392 * the worst case estimate for the number of blocks we'd need to rebuild one of
393 * any type of per-rtgroup btree.
399 struct xfs_mount *mp = sc->mp; in xrep_calc_rtgroup_resblks()
400 struct xfs_scrub_metadata *sm = sc->sm; in xrep_calc_rtgroup_resblks()
404 if (!(sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR)) in xrep_calc_rtgroup_resblks()
408 return -EFSCORRUPTED; in xrep_calc_rtgroup_resblks()
411 usedlen = xfs_rtbxlen_to_blen(mp, xfs_rtgroup_extents(mp, sm->sm_agno)); in xrep_calc_rtgroup_resblks()
417 trace_xrep_calc_rtgroup_resblks_btsize(mp, sm->sm_agno, usedlen, in xrep_calc_rtgroup_resblks()
425 * Reconstructing per-AG Btrees
438 * derive the blocks that were used by the old btree. These blocks can be
446 * result (since the rmapbt lives in the free space) are the blocks from the
458 args.mp = sc->mp; in xrep_fix_freelist()
459 args.tp = sc->tp; in xrep_fix_freelist()
460 args.agno = pag_agno(sc->sa.pag); in xrep_fix_freelist()
462 args.pag = sc->sa.pag; in xrep_fix_freelist()
468 * Finding per-AG Btree Roots for AGF/AGI Reconstruction
510 return (*agbno == bno) ? -ECANCELED : 0; in xrep_findroot_agfl_walk()
522 struct xfs_mount *mp = ri->sc->mp; in xrep_findroot_block()
529 daddr = xfs_agbno_to_daddr(ri->sc->sa.pag, agbno); in xrep_findroot_block()
532 * Blocks in the AGFL have stale contents that might just happen to in xrep_findroot_block()
533 * have a matching magic and uuid. We don't want to pull these blocks in xrep_findroot_block()
538 error = xfs_agfl_walk(mp, ri->agf, ri->agfl_bp, in xrep_findroot_block()
540 if (error == -ECANCELED) in xrep_findroot_block()
564 error = xfs_trans_read_buf(mp, ri->sc->tp, mp->m_ddev_targp, daddr, in xrep_findroot_block()
565 mp->m_bsize, 0, &bp, NULL); in xrep_findroot_block()
571 ASSERT(fab->buf_ops->magic[1] != 0); in xrep_findroot_block()
572 if (btblock->bb_magic != fab->buf_ops->magic[1]) in xrep_findroot_block()
589 if (bp->b_ops) { in xrep_findroot_block()
590 if (bp->b_ops != fab->buf_ops) in xrep_findroot_block()
594 if (!uuid_equal(&btblock->bb_u.s.bb_uuid, in xrep_findroot_block()
595 &mp->m_sb.sb_meta_uuid)) in xrep_findroot_block()
602 bp->b_ops = fab->buf_ops; in xrep_findroot_block()
603 fab->buf_ops->verify_read(bp); in xrep_findroot_block()
604 if (bp->b_error) { in xrep_findroot_block()
605 bp->b_ops = NULL; in xrep_findroot_block()
606 bp->b_error = 0; in xrep_findroot_block()
627 * blocks because there can't be two candidate roots. in xrep_findroot_block()
633 if (block_level + 1 == fab->height) { in xrep_findroot_block()
634 fab->root = NULLAGBLOCK; in xrep_findroot_block()
636 } else if (block_level < fab->height) { in xrep_findroot_block()
645 fab->height = block_level + 1; in xrep_findroot_block()
652 if (btblock->bb_u.s.bb_leftsib == cpu_to_be32(NULLAGBLOCK) && in xrep_findroot_block()
653 btblock->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK)) in xrep_findroot_block()
654 fab->root = agbno; in xrep_findroot_block()
656 fab->root = NULLAGBLOCK; in xrep_findroot_block()
658 trace_xrep_findroot_block(ri->sc->sa.pag, agbno, in xrep_findroot_block()
659 be32_to_cpu(btblock->bb_magic), fab->height - 1); in xrep_findroot_block()
661 xfs_trans_brelse(ri->sc->tp, bp); in xrep_findroot_block()
666 * Do any of the blocks in this rmap record match one of the btrees we're
682 if (!XFS_RMAP_NON_INODE_OWNER(rec->rm_owner)) in xrep_findroot_rmap()
686 for (b = 0; b < rec->rm_blockcount; b++) { in xrep_findroot_rmap()
688 for (fab = ri->btree_info; fab->buf_ops; fab++) { in xrep_findroot_rmap()
689 if (rec->rm_owner != fab->rmap_owner) in xrep_findroot_rmap()
692 rec->rm_owner, rec->rm_startblock + b, in xrep_findroot_rmap()
704 /* Find the roots of the per-AG btrees described in btree_info. */
712 struct xfs_mount *mp = sc->mp; in xrep_find_ag_btree_roots()
723 ri.agf = agf_bp->b_addr; in xrep_find_ag_btree_roots()
725 for (fab = btree_info; fab->buf_ops; fab++) { in xrep_find_ag_btree_roots()
726 ASSERT(agfl_bp || fab->rmap_owner != XFS_RMAP_OWN_AG); in xrep_find_ag_btree_roots()
727 ASSERT(XFS_RMAP_NON_INODE_OWNER(fab->rmap_owner)); in xrep_find_ag_btree_roots()
728 fab->root = NULLAGBLOCK; in xrep_find_ag_btree_roots()
729 fab->height = 0; in xrep_find_ag_btree_roots()
732 cur = xfs_rmapbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.pag); in xrep_find_ag_btree_roots()
747 struct xfs_mount *mp = sc->mp; in xrep_update_qflags()
750 mutex_lock(&mp->m_quotainfo->qi_quotaofflock); in xrep_update_qflags()
751 if ((mp->m_qflags & clear_flags) == 0 && in xrep_update_qflags()
752 (mp->m_qflags & set_flags) == set_flags) in xrep_update_qflags()
755 mp->m_qflags &= ~clear_flags; in xrep_update_qflags()
756 mp->m_qflags |= set_flags; in xrep_update_qflags()
758 spin_lock(&mp->m_sb_lock); in xrep_update_qflags()
759 mp->m_sb.sb_qflags &= ~clear_flags; in xrep_update_qflags()
760 mp->m_sb.sb_qflags |= set_flags; in xrep_update_qflags()
761 spin_unlock(&mp->m_sb_lock); in xrep_update_qflags()
769 bp = xfs_trans_getsb(sc->tp); in xrep_update_qflags()
770 xfs_sb_to_disk(bp->b_addr, &mp->m_sb); in xrep_update_qflags()
771 xfs_trans_buf_set_type(sc->tp, bp, XFS_BLFT_SB_BUF); in xrep_update_qflags()
772 xfs_trans_log_buf(sc->tp, bp, 0, sizeof(struct xfs_dsb) - 1); in xrep_update_qflags()
775 mutex_unlock(&mp->m_quotainfo->qi_quotaofflock); in xrep_update_qflags()
787 if (!(flag & sc->mp->m_qflags)) in xrep_force_quotacheck()
797 * We cannot allow the dquot code to allocate an on-disk dquot block here
798 * because we're already in transaction context. The on-disk dquot should
809 ASSERT(sc->tp != NULL); in xrep_ino_dqattach()
810 ASSERT(sc->ip != NULL); in xrep_ino_dqattach()
812 error = xfs_qm_dqattach(sc->ip); in xrep_ino_dqattach()
814 case -EFSBADCRC: in xrep_ino_dqattach()
815 case -EFSCORRUPTED: in xrep_ino_dqattach()
816 case -ENOENT: in xrep_ino_dqattach()
817 xfs_err_ratelimited(sc->mp, in xrep_ino_dqattach()
819 (unsigned long long)sc->ip->i_ino, error); in xrep_ino_dqattach()
820 if (XFS_IS_UQUOTA_ON(sc->mp) && !sc->ip->i_udquot) in xrep_ino_dqattach()
822 if (XFS_IS_GQUOTA_ON(sc->mp) && !sc->ip->i_gdquot) in xrep_ino_dqattach()
824 if (XFS_IS_PQUOTA_ON(sc->mp) && !sc->ip->i_pdquot) in xrep_ino_dqattach()
827 case -ESRCH: in xrep_ino_dqattach()
852 inode_has_nrext64 = xfs_inode_has_large_extent_counts(sc->ip); in xrep_ino_ensure_extent_count()
857 return -EFSCORRUPTED; in xrep_ino_ensure_extent_count()
858 if (!xfs_has_large_extent_counts(sc->mp)) in xrep_ino_ensure_extent_count()
859 return -EFSCORRUPTED; in xrep_ino_ensure_extent_count()
863 return -EFSCORRUPTED; in xrep_ino_ensure_extent_count()
865 sc->ip->i_diflags2 |= XFS_DIFLAG2_NREXT64; in xrep_ino_ensure_extent_count()
866 xfs_trans_log_inode(sc->tp, sc->ip, XFS_ILOG_CORE); in xrep_ino_ensure_extent_count()
879 struct xfs_mount *mp = sc->mp; in xrep_ag_btcur_init()
881 /* Set up a bnobt cursor for cross-referencing. */ in xrep_ag_btcur_init()
882 if (sc->sm->sm_type != XFS_SCRUB_TYPE_BNOBT && in xrep_ag_btcur_init()
883 sc->sm->sm_type != XFS_SCRUB_TYPE_CNTBT) { in xrep_ag_btcur_init()
884 sa->bno_cur = xfs_bnobt_init_cursor(mp, sc->tp, sa->agf_bp, in xrep_ag_btcur_init()
885 sc->sa.pag); in xrep_ag_btcur_init()
886 sa->cnt_cur = xfs_cntbt_init_cursor(mp, sc->tp, sa->agf_bp, in xrep_ag_btcur_init()
887 sc->sa.pag); in xrep_ag_btcur_init()
890 /* Set up a inobt cursor for cross-referencing. */ in xrep_ag_btcur_init()
891 if (sc->sm->sm_type != XFS_SCRUB_TYPE_INOBT && in xrep_ag_btcur_init()
892 sc->sm->sm_type != XFS_SCRUB_TYPE_FINOBT) { in xrep_ag_btcur_init()
893 sa->ino_cur = xfs_inobt_init_cursor(sc->sa.pag, sc->tp, in xrep_ag_btcur_init()
894 sa->agi_bp); in xrep_ag_btcur_init()
896 sa->fino_cur = xfs_finobt_init_cursor(sc->sa.pag, in xrep_ag_btcur_init()
897 sc->tp, sa->agi_bp); in xrep_ag_btcur_init()
900 /* Set up a rmapbt cursor for cross-referencing. */ in xrep_ag_btcur_init()
901 if (sc->sm->sm_type != XFS_SCRUB_TYPE_RMAPBT && in xrep_ag_btcur_init()
903 sa->rmap_cur = xfs_rmapbt_init_cursor(mp, sc->tp, sa->agf_bp, in xrep_ag_btcur_init()
904 sc->sa.pag); in xrep_ag_btcur_init()
906 /* Set up a refcountbt cursor for cross-referencing. */ in xrep_ag_btcur_init()
907 if (sc->sm->sm_type != XFS_SCRUB_TYPE_REFCNTBT && in xrep_ag_btcur_init()
909 sa->refc_cur = xfs_refcountbt_init_cursor(mp, sc->tp, in xrep_ag_btcur_init()
910 sa->agf_bp, sc->sa.pag); in xrep_ag_btcur_init()
914 * Reinitialize the in-core AG state after a repair by rereading the AGF
922 struct xfs_perag *pag = sc->sa.pag; in xrep_reinit_pagf()
929 clear_bit(XFS_AGSTATE_AGF_INIT, &pag->pag_opstate); in xrep_reinit_pagf()
930 error = xfs_alloc_read_agf(pag, sc->tp, 0, &bp); in xrep_reinit_pagf()
934 if (bp != sc->sa.agf_bp) { in xrep_reinit_pagf()
935 ASSERT(bp == sc->sa.agf_bp); in xrep_reinit_pagf()
936 return -EFSCORRUPTED; in xrep_reinit_pagf()
943 * Reinitialize the in-core AG state after a repair by rereading the AGI
951 struct xfs_perag *pag = sc->sa.pag; in xrep_reinit_pagi()
958 clear_bit(XFS_AGSTATE_AGI_INIT, &pag->pag_opstate); in xrep_reinit_pagi()
959 error = xfs_ialloc_read_agi(pag, sc->tp, 0, &bp); in xrep_reinit_pagi()
963 if (bp != sc->sa.agi_bp) { in xrep_reinit_pagi()
964 ASSERT(bp == sc->sa.agi_bp); in xrep_reinit_pagi()
965 return -EFSCORRUPTED; in xrep_reinit_pagi()
973 * This should only be called to scan an AG while repairing file-based metadata.
983 ASSERT(!sa->pag); in xrep_ag_init()
985 error = xfs_ialloc_read_agi(pag, sc->tp, 0, &sa->agi_bp); in xrep_ag_init()
989 error = xfs_alloc_read_agf(pag, sc->tp, 0, &sa->agf_bp); in xrep_ag_init()
994 sa->pag = xfs_perag_hold(pag); in xrep_ag_init()
1006 struct xfs_mount *mp = sc->mp; in xrep_rtgroup_btcur_init()
1008 ASSERT(sr->rtg != NULL); in xrep_rtgroup_btcur_init()
1010 if (sc->sm->sm_type != XFS_SCRUB_TYPE_RTRMAPBT && in xrep_rtgroup_btcur_init()
1011 (sr->rtlock_flags & XFS_RTGLOCK_RMAP) && in xrep_rtgroup_btcur_init()
1013 sr->rmap_cur = xfs_rtrmapbt_init_cursor(sc->tp, sr->rtg); in xrep_rtgroup_btcur_init()
1015 if (sc->sm->sm_type != XFS_SCRUB_TYPE_RTREFCBT && in xrep_rtgroup_btcur_init()
1016 (sr->rtlock_flags & XFS_RTGLOCK_REFCOUNT) && in xrep_rtgroup_btcur_init()
1018 sr->refc_cur = xfs_rtrefcountbt_init_cursor(sc->tp, sr->rtg); in xrep_rtgroup_btcur_init()
1032 ASSERT(sr->rtg == NULL); in xrep_rtgroup_init()
1035 sr->rtlock_flags = rtglock_flags; in xrep_rtgroup_init()
1038 sr->rtg = xfs_rtgroup_hold(rtg); in xrep_rtgroup_init()
1043 /* Ensure that all rt blocks in the given range are not marked free. */
1050 struct xfs_mount *mp = sc->mp; in xrep_require_rtext_inuse()
1057 if (!xfs_zone_rgbno_is_valid(sc->sr.rtg, rgbno + len - 1)) in xrep_require_rtext_inuse()
1058 return -EFSCORRUPTED; in xrep_require_rtext_inuse()
1063 endrtx = xfs_rgbno_to_rtx(mp, rgbno + len - 1); in xrep_require_rtext_inuse()
1065 error = xfs_rtalloc_extent_is_free(sc->sr.rtg, sc->tp, startrtx, in xrep_require_rtext_inuse()
1066 endrtx - startrtx + 1, &is_free); in xrep_require_rtext_inuse()
1070 return -EFSCORRUPTED; in xrep_require_rtext_inuse()
1076 /* Reinitialize the per-AG block reservation for the AG we just fixed. */
1083 if (!(sc->flags & XREP_RESET_PERAG_RESV)) in xrep_reset_perag_resv()
1086 ASSERT(sc->sa.pag != NULL); in xrep_reset_perag_resv()
1087 ASSERT(sc->ops->type == ST_PERAG); in xrep_reset_perag_resv()
1088 ASSERT(sc->tp); in xrep_reset_perag_resv()
1090 sc->flags &= ~XREP_RESET_PERAG_RESV; in xrep_reset_perag_resv()
1091 xfs_ag_resv_free(sc->sa.pag); in xrep_reset_perag_resv()
1092 error = xfs_ag_resv_init(sc->sa.pag, sc->tp); in xrep_reset_perag_resv()
1093 if (error == -ENOSPC) { in xrep_reset_perag_resv()
1094 xfs_err(sc->mp, in xrep_reset_perag_resv()
1095 "Insufficient free space to reset per-AG reservation for AG %u after repair.", in xrep_reset_perag_resv()
1096 pag_agno(sc->sa.pag)); in xrep_reset_perag_resv()
1109 if (sc->sm->sm_flags & XFS_SCRUB_IFLAG_FORCE_REBUILD) in xrep_will_attempt()
1113 if (XFS_TEST_ERROR(false, sc->mp, XFS_ERRTAG_FORCE_SCRUB_REPAIR)) in xrep_will_attempt()
1116 /* Metadata is corrupt or failed cross-referencing. */ in xrep_will_attempt()
1117 if (xchk_needs_repair(sc->sm)) in xrep_will_attempt()
1129 struct xfs_scrub_subord *sub; in xrep_metadata_inode_subtype() local
1138 sub = xchk_scrub_create_subord(sc, scrub_type); in xrep_metadata_inode_subtype()
1139 error = sub->sc.ops->scrub(&sub->sc); in xrep_metadata_inode_subtype()
1142 if (!xrep_will_attempt(&sub->sc)) in xrep_metadata_inode_subtype()
1149 error = sub->sc.ops->repair(&sub->sc); in xrep_metadata_inode_subtype()
1158 error = xfs_defer_finish(&sub->sc.tp); in xrep_metadata_inode_subtype()
1161 error = xfs_trans_roll(&sub->sc.tp); in xrep_metadata_inode_subtype()
1166 * Clear the corruption flags and re-check the metadata that we just in xrep_metadata_inode_subtype()
1169 sub->sc.sm->sm_flags &= ~XFS_SCRUB_FLAGS_OUT; in xrep_metadata_inode_subtype()
1170 error = sub->sc.ops->scrub(&sub->sc); in xrep_metadata_inode_subtype()
1175 if (xchk_needs_repair(sub->sc.sm)) { in xrep_metadata_inode_subtype()
1176 error = -EFSCORRUPTED; in xrep_metadata_inode_subtype()
1180 xchk_scrub_free_subord(sub); in xrep_metadata_inode_subtype()
1186 * sc->ip points to the metadata inode and the ILOCK is held on that inode.
1209 * For a non-metadir filesystem, make sure the attr fork looks ok in xrep_metadata_inode_forks()
1212 if (xfs_inode_hasattr(sc->ip)) { in xrep_metadata_inode_forks()
1219 if (xfs_is_reflink_inode(sc->ip)) { in xrep_metadata_inode_forks()
1221 xfs_trans_ijoin(sc->tp, sc->ip, 0); in xrep_metadata_inode_forks()
1222 error = xfs_reflink_clear_inode_flag(sc->ip, &sc->tp); in xrep_metadata_inode_forks()
1228 * Metadata files on non-metadir filesystems cannot have attr forks, in xrep_metadata_inode_forks()
1231 if (xfs_inode_hasattr(sc->ip) && !xfs_has_metadir(sc->mp)) { in xrep_metadata_inode_forks()
1234 xfs_trans_ijoin(sc->tp, sc->ip, 0); in xrep_metadata_inode_forks()
1246 error = xfs_trans_roll(&sc->tp); in xrep_metadata_inode_forks()
1256 * Set up an in-memory buffer cache so that we can use the xfbtree. Allocating
1266 ASSERT(sc->tp == NULL); in xrep_setup_xfbtree()
1268 return xmbuf_alloc(sc->mp, descr, &sc->xmbtp); in xrep_setup_xfbtree()
1284 *cookiep = current->journal_info; in xrep_trans_alloc_hook_dummy()
1285 current->journal_info = NULL; in xrep_trans_alloc_hook_dummy()
1291 current->journal_info = *cookiep; in xrep_trans_alloc_hook_dummy()
1303 current->journal_info = *cookiep; in xrep_trans_cancel_hook_dummy()
1308 * See if this buffer can pass the given ->verify_struct() function.
1320 const struct xfs_buf_ops *old_ops = bp->b_ops; in xrep_buf_verify_struct()
1329 old_error = bp->b_error; in xrep_buf_verify_struct()
1330 bp->b_ops = ops; in xrep_buf_verify_struct()
1331 fa = bp->b_ops->verify_struct(bp); in xrep_buf_verify_struct()
1332 bp->b_ops = old_ops; in xrep_buf_verify_struct()
1333 bp->b_error = old_error; in xrep_buf_verify_struct()
1348 * Metadata btree inodes never have extended attributes, and all blocks in xrep_check_ino_btree_mapping()
1351 if ((rec->rm_flags & XFS_RMAP_ATTR_FORK) || in xrep_check_ino_btree_mapping()
1352 !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK)) in xrep_check_ino_btree_mapping()
1353 return -EFSCORRUPTED; in xrep_check_ino_btree_mapping()
1356 if (!xfs_verify_agbext(sc->sa.pag, rec->rm_startblock, in xrep_check_ino_btree_mapping()
1357 rec->rm_blockcount)) in xrep_check_ino_btree_mapping()
1358 return -EFSCORRUPTED; in xrep_check_ino_btree_mapping()
1361 error = xfs_alloc_has_records(sc->sa.bno_cur, rec->rm_startblock, in xrep_check_ino_btree_mapping()
1362 rec->rm_blockcount, &outcome); in xrep_check_ino_btree_mapping()
1366 return -EFSCORRUPTED; in xrep_check_ino_btree_mapping()
1381 new_blocks - sc->ip->i_nblocks; in xrep_inode_set_nblocks()
1383 sc->ip->i_nblocks = new_blocks; in xrep_inode_set_nblocks()
1385 xfs_trans_log_inode(sc->tp, sc->ip, XFS_ILOG_CORE); in xrep_inode_set_nblocks()
1387 xfs_trans_mod_dquot_byino(sc->tp, sc->ip, XFS_TRANS_DQ_BCOUNT, in xrep_inode_set_nblocks()
1396 struct xfs_mount *mp = sc->mp; in xrep_reset_metafile_resv()
1400 delta = mp->m_metafile_resv_used + mp->m_metafile_resv_avail - in xrep_reset_metafile_resv()
1401 mp->m_metafile_resv_target; in xrep_reset_metafile_resv()
1406 * Too many blocks have been reserved, transfer some from the incore in xrep_reset_metafile_resv()
1412 give_back = min_t(uint64_t, delta, mp->m_metafile_resv_avail); in xrep_reset_metafile_resv()
1414 xfs_mod_sb_delalloc(mp, -give_back); in xrep_reset_metafile_resv()
1416 mp->m_metafile_resv_avail -= give_back; in xrep_reset_metafile_resv()
1423 * Not enough reservation; try to take some blocks from the filesystem in xrep_reset_metafile_resv()
1426 delta = -delta; /* delta is negative here, so invert the sign. */ in xrep_reset_metafile_resv()
1428 while (error == -ENOSPC) { in xrep_reset_metafile_resv()
1429 delta--; in xrep_reset_metafile_resv()
1431 xfs_warn(sc->mp, in xrep_reset_metafile_resv()
1441 mp->m_metafile_resv_avail += delta; in xrep_reset_metafile_resv()