Lines Matching +full:ip +full:- +full:blocks
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2018-2023 Oracle. All Rights Reserved.
55 RLS_IRRELEVANT = -1, /* not applicable to this file */
61 /* Old bmbt blocks */
72 /* How many blocks did we find allocated to this file? */
75 /* How many bmbt blocks did we find for this fork? */
81 /* How many real (non-hole, non-delalloc) mappings do we have? */
101 struct xfs_scrub *sc = rb->sc; in xrep_bmap_discover_shared()
107 agbno = XFS_FSB_TO_AGBNO(sc->mp, startblock); in xrep_bmap_discover_shared()
108 error = xfs_refcount_find_shared(sc->sa.refc_cur, agbno, blockcount, in xrep_bmap_discover_shared()
114 rb->reflink_scan = RLS_SET_IFLAG; in xrep_bmap_discover_shared()
119 /* Remember this reverse-mapping as a series of bmap records. */
134 struct xfs_scrub *sc = rb->sc; in xrep_bmap_from_rmap()
138 * If we're repairing the data fork of a non-reflinked regular file on in xrep_bmap_from_rmap()
142 if (rb->reflink_scan == RLS_UNKNOWN && !unwritten) { in xrep_bmap_from_rmap()
154 fa = xfs_bmap_validate_extent(sc->ip, rb->whichfork, &irec); in xrep_bmap_from_rmap()
156 return -EFSCORRUPTED; in xrep_bmap_from_rmap()
160 trace_xrep_bmap_found(sc->ip, rb->whichfork, &irec); in xrep_bmap_from_rmap()
165 error = xfarray_append(rb->bmap_records, &rbe); in xrep_bmap_from_rmap()
169 rb->real_mappings++; in xrep_bmap_from_rmap()
173 blockcount -= irec.br_blockcount; in xrep_bmap_from_rmap()
186 struct xfs_scrub *sc = rb->sc; in xrep_bmap_check_fork_rmap()
192 * everything else (xattrs, bmbt blocks) can be. in xrep_bmap_check_fork_rmap()
194 if (XFS_IS_REALTIME_INODE(sc->ip) && in xrep_bmap_check_fork_rmap()
195 !(rec->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))) in xrep_bmap_check_fork_rmap()
196 return -EFSCORRUPTED; in xrep_bmap_check_fork_rmap()
199 if (!xfs_verify_agbext(cur->bc_ag.pag, rec->rm_startblock, in xrep_bmap_check_fork_rmap()
200 rec->rm_blockcount)) in xrep_bmap_check_fork_rmap()
201 return -EFSCORRUPTED; in xrep_bmap_check_fork_rmap()
204 if (!(rec->rm_flags & XFS_RMAP_BMBT_BLOCK) && in xrep_bmap_check_fork_rmap()
205 !xfs_verify_fileext(sc->mp, rec->rm_offset, rec->rm_blockcount)) in xrep_bmap_check_fork_rmap()
206 return -EFSCORRUPTED; in xrep_bmap_check_fork_rmap()
209 if ((rec->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK)) && in xrep_bmap_check_fork_rmap()
210 (rec->rm_flags & XFS_RMAP_UNWRITTEN)) in xrep_bmap_check_fork_rmap()
211 return -EFSCORRUPTED; in xrep_bmap_check_fork_rmap()
214 error = xfs_alloc_has_records(sc->sa.bno_cur, rec->rm_startblock, in xrep_bmap_check_fork_rmap()
215 rec->rm_blockcount, &outcome); in xrep_bmap_check_fork_rmap()
219 return -EFSCORRUPTED; in xrep_bmap_check_fork_rmap()
222 error = xfs_ialloc_has_inodes_at_extent(sc->sa.ino_cur, in xrep_bmap_check_fork_rmap()
223 rec->rm_startblock, rec->rm_blockcount, &outcome); in xrep_bmap_check_fork_rmap()
227 return -EFSCORRUPTED; in xrep_bmap_check_fork_rmap()
240 struct xfs_mount *mp = cur->bc_mp; in xrep_bmap_walk_rmap()
244 if (xchk_should_terminate(rb->sc, &error)) in xrep_bmap_walk_rmap()
247 if (rec->rm_owner != rb->sc->ip->i_ino) in xrep_bmap_walk_rmap()
255 * Record all blocks allocated to this file even if the extent isn't in xrep_bmap_walk_rmap()
258 rb->nblocks += rec->rm_blockcount; in xrep_bmap_walk_rmap()
261 if (rb->whichfork == XFS_DATA_FORK && in xrep_bmap_walk_rmap()
262 (rec->rm_flags & XFS_RMAP_ATTR_FORK)) in xrep_bmap_walk_rmap()
264 if (rb->whichfork == XFS_ATTR_FORK && in xrep_bmap_walk_rmap()
265 !(rec->rm_flags & XFS_RMAP_ATTR_FORK)) in xrep_bmap_walk_rmap()
269 if ((rec->rm_flags & XFS_RMAP_UNWRITTEN) && !rb->allow_unwritten) in xrep_bmap_walk_rmap()
270 return -EFSCORRUPTED; in xrep_bmap_walk_rmap()
272 fsbno = XFS_AGB_TO_FSB(mp, cur->bc_ag.pag->pag_agno, in xrep_bmap_walk_rmap()
273 rec->rm_startblock); in xrep_bmap_walk_rmap()
275 if (rec->rm_flags & XFS_RMAP_BMBT_BLOCK) { in xrep_bmap_walk_rmap()
276 rb->old_bmbt_block_count += rec->rm_blockcount; in xrep_bmap_walk_rmap()
277 return xfsb_bitmap_set(&rb->old_bmbt_blocks, fsbno, in xrep_bmap_walk_rmap()
278 rec->rm_blockcount); in xrep_bmap_walk_rmap()
281 return xrep_bmap_from_rmap(rb, rec->rm_offset, fsbno, in xrep_bmap_walk_rmap()
282 rec->rm_blockcount, in xrep_bmap_walk_rmap()
283 rec->rm_flags & XFS_RMAP_UNWRITTEN); in xrep_bmap_walk_rmap()
303 return -1; in xrep_bmap_extent_cmp()
320 error = xfarray_sort(rb->bmap_records, xrep_bmap_extent_cmp, in xrep_bmap_sort_records()
325 foreach_xfarray_idx(rb->bmap_records, array_cur) { in xrep_bmap_sort_records()
328 if (xchk_should_terminate(rb->sc, &error)) in xrep_bmap_sort_records()
331 error = xfarray_load(rb->bmap_records, array_cur, &rec); in xrep_bmap_sort_records()
338 return -EFSCORRUPTED; in xrep_bmap_sort_records()
352 struct xfs_scrub *sc = rb->sc; in xrep_bmap_scan_ag()
355 error = xrep_ag_init(sc, pag, &sc->sa); in xrep_bmap_scan_ag()
359 error = xfs_rmap_query_all(sc->sa.rmap_cur, xrep_bmap_walk_rmap, rb); in xrep_bmap_scan_ag()
360 xchk_ag_free(sc, &sc->sa); in xrep_bmap_scan_ag()
372 struct xfs_inode *ip = rb->sc->ip; in xrep_bmap_find_delalloc() local
373 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, rb->whichfork); in xrep_bmap_find_delalloc()
380 if (rb->whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0) in xrep_bmap_find_delalloc()
389 trace_xrep_bmap_found(ip, rb->whichfork, &irec); in xrep_bmap_find_delalloc()
391 if (xchk_should_terminate(rb->sc, &error)) in xrep_bmap_find_delalloc()
394 error = xfarray_append(rb->bmap_records, &rbe); in xrep_bmap_find_delalloc()
411 struct xfs_scrub *sc = rb->sc; in xrep_bmap_find_mappings()
417 for_each_perag(sc->mp, agno, pag) { in xrep_bmap_find_mappings()
438 struct xfs_bmbt_irec *irec = &cur->bc_rec.b; in xrep_bmap_get_records()
446 error = xfarray_load(rb->bmap_records, rb->array_cur++, in xrep_bmap_get_records()
452 } while (isnullstartblock(irec->br_startblock)); in xrep_bmap_get_records()
455 cur->bc_ops->init_rec_from_cur(cur, block_rec); in xrep_bmap_get_records()
461 /* Feed one of the new btree blocks to the bulk loader. */
470 return xrep_newbt_claim_block(cur, &rb->new_bmapbt, ptr); in xrep_bmap_claim_block()
483 return xfs_bmap_broot_space_calc(cur->bc_mp, nr_this_level); in xrep_bmap_iroot_size()
491 struct xfs_scrub *sc = rb->sc; in xrep_bmap_reset_counters()
492 struct xbtree_ifakeroot *ifake = &rb->new_bmapbt.ifake; in xrep_bmap_reset_counters()
495 if (rb->reflink_scan == RLS_SET_IFLAG) in xrep_bmap_reset_counters()
496 sc->ip->i_diflags2 |= XFS_DIFLAG2_REFLINK; in xrep_bmap_reset_counters()
502 delta = ifake->if_blocks - rb->old_bmbt_block_count; in xrep_bmap_reset_counters()
503 sc->ip->i_nblocks = rb->nblocks + delta; in xrep_bmap_reset_counters()
504 xfs_trans_log_inode(sc->tp, sc->ip, XFS_ILOG_CORE); in xrep_bmap_reset_counters()
510 xfs_trans_mod_dquot_byino(sc->tp, sc->ip, XFS_TRANS_DQ_BCOUNT, delta); in xrep_bmap_reset_counters()
525 struct xfs_ifork *ifp = rb->new_bmapbt.ifake.if_fork; in xrep_bmap_extents_load()
529 ASSERT(ifp->if_bytes == 0); in xrep_bmap_extents_load()
533 foreach_xfarray_idx(rb->bmap_records, array_cur) { in xrep_bmap_extents_load()
536 error = xfarray_load(rb->bmap_records, array_cur, &rec); in xrep_bmap_extents_load()
544 ifp->if_nextents++; in xrep_bmap_extents_load()
549 return xrep_ino_ensure_extent_count(rb->sc, rb->whichfork, in xrep_bmap_extents_load()
550 ifp->if_nextents); in xrep_bmap_extents_load()
554 * Reserve new btree blocks, bulk load the bmap records into the ondisk btree,
562 struct xfs_scrub *sc = rb->sc; in xrep_bmap_btree_load()
565 /* Compute how many blocks we'll need. */ in xrep_bmap_btree_load()
567 &rb->new_bmapbt.bload, rb->real_mappings); in xrep_bmap_btree_load()
576 * Guess how many blocks we're going to need to rebuild an entire bmap in xrep_bmap_btree_load()
581 error = xfs_trans_reserve_more_inode(sc->tp, sc->ip, in xrep_bmap_btree_load()
582 rb->new_bmapbt.bload.nr_blocks, 0, true); in xrep_bmap_btree_load()
587 error = xrep_newbt_alloc_blocks(&rb->new_bmapbt, in xrep_bmap_btree_load()
588 rb->new_bmapbt.bload.nr_blocks); in xrep_bmap_btree_load()
593 rb->array_cur = XFARRAY_CURSOR_INIT; in xrep_bmap_btree_load()
594 error = xfs_btree_bload(bmap_cur, &rb->new_bmapbt.bload, rb); in xrep_bmap_btree_load()
620 struct xfs_scrub *sc = rb->sc; in xrep_bmap_build_new_fork()
622 struct xbtree_ifakeroot *ifake = &rb->new_bmapbt.ifake; in xrep_bmap_build_new_fork()
633 xfs_rmap_ino_bmbt_owner(&oinfo, sc->ip->i_ino, rb->whichfork); in xrep_bmap_build_new_fork()
634 error = xrep_newbt_init_inode(&rb->new_bmapbt, sc, rb->whichfork, in xrep_bmap_build_new_fork()
639 rb->new_bmapbt.bload.get_records = xrep_bmap_get_records; in xrep_bmap_build_new_fork()
640 rb->new_bmapbt.bload.claim_block = xrep_bmap_claim_block; in xrep_bmap_build_new_fork()
641 rb->new_bmapbt.bload.iroot_size = xrep_bmap_iroot_size; in xrep_bmap_build_new_fork()
647 bmap_cur = xfs_bmbt_init_cursor(sc->mp, NULL, sc->ip, XFS_STAGING_FORK); in xrep_bmap_build_new_fork()
655 if (rb->real_mappings <= XFS_IFORK_MAXEXT(sc->ip, rb->whichfork)) { in xrep_bmap_build_new_fork()
656 ifake->if_fork->if_format = XFS_DINODE_FMT_EXTENTS; in xrep_bmap_build_new_fork()
659 ifake->if_fork->if_format = XFS_DINODE_FMT_BTREE; in xrep_bmap_build_new_fork()
671 xfs_bmbt_commit_staged_btree(bmap_cur, sc->tp, rb->whichfork); in xrep_bmap_build_new_fork()
679 /* Dispose of any unused blocks and the accounting information. */ in xrep_bmap_build_new_fork()
680 error = xrep_newbt_commit(&rb->new_bmapbt); in xrep_bmap_build_new_fork()
690 xrep_newbt_cancel(&rb->new_bmapbt); in xrep_bmap_build_new_fork()
695 * Now that we've logged the new inode btree, invalidate all of the old blocks
702 struct xfs_scrub *sc = rb->sc; in xrep_bmap_remove_old_tree()
705 /* Free the old bmbt blocks if they're not in use. */ in xrep_bmap_remove_old_tree()
706 xfs_rmap_ino_bmbt_owner(&oinfo, sc->ip->i_ino, rb->whichfork); in xrep_bmap_remove_old_tree()
707 return xrep_reap_fsblocks(sc, &rb->old_bmbt_blocks, &oinfo); in xrep_bmap_remove_old_tree()
710 /* Check for garbage inputs. Returns -ECANCELED if there's nothing to do. */
716 struct xfs_ifork *ifp = xfs_ifork_ptr(sc->ip, whichfork); in xrep_bmap_check_inputs()
720 if (!xfs_has_rmapbt(sc->mp)) in xrep_bmap_check_inputs()
721 return -EOPNOTSUPP; in xrep_bmap_check_inputs()
725 return -ECANCELED; in xrep_bmap_check_inputs()
733 switch (ifp->if_format) { in xrep_bmap_check_inputs()
737 return -ECANCELED; in xrep_bmap_check_inputs()
742 return -EFSCORRUPTED; in xrep_bmap_check_inputs()
749 switch (VFS_I(sc->ip)->i_mode & S_IFMT) { in xrep_bmap_check_inputs()
756 return -EINVAL; in xrep_bmap_check_inputs()
760 if (XFS_IS_REALTIME_INODE(sc->ip)) in xrep_bmap_check_inputs()
761 return -EOPNOTSUPP; in xrep_bmap_check_inputs()
772 /* cannot share on non-reflink filesystem */ in xrep_bmap_init_reflink_scan()
773 if (!xfs_has_reflink(sc->mp)) in xrep_bmap_init_reflink_scan()
777 if (xfs_is_reflink_inode(sc->ip)) in xrep_bmap_init_reflink_scan()
781 if (!S_ISREG(VFS_I(sc->ip)->i_mode)) in xrep_bmap_init_reflink_scan()
789 if (XFS_IS_REALTIME_INODE(sc->ip)) in xrep_bmap_init_reflink_scan()
809 if (error == -ECANCELED) in xrep_bmap()
816 return -ENOMEM; in xrep_bmap()
817 rb->sc = sc; in xrep_bmap()
818 rb->whichfork = whichfork; in xrep_bmap()
819 rb->reflink_scan = xrep_bmap_init_reflink_scan(sc, whichfork); in xrep_bmap()
820 rb->allow_unwritten = allow_unwritten; in xrep_bmap()
823 large_extcount = xfs_has_large_extent_counts(sc->mp); in xrep_bmap()
828 sizeof(struct xfs_bmbt_rec), &rb->bmap_records); in xrep_bmap()
834 xfsb_bitmap_init(&rb->old_bmbt_blocks); in xrep_bmap()
839 xfs_trans_ijoin(sc->tp, sc->ip, 0); in xrep_bmap()
852 xfsb_bitmap_destroy(&rb->old_bmbt_blocks); in xrep_bmap()
853 xfarray_destroy(rb->bmap_records); in xrep_bmap()