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.
57 RLS_IRRELEVANT = -1, /* not applicable to this file */
63 /* Old bmbt blocks */
74 /* How many blocks did we find allocated to this file? */
77 /* How many bmbt blocks did we find for this fork? */
83 /* How many real (non-hole, non-delalloc) mappings do we have? */
103 struct xfs_scrub *sc = rb->sc; in xrep_bmap_discover_shared()
110 if (XFS_IS_REALTIME_INODE(sc->ip)) { in xrep_bmap_discover_shared()
111 agbno = xfs_rtb_to_rgbno(sc->mp, startblock); in xrep_bmap_discover_shared()
112 cur = sc->sr.refc_cur; in xrep_bmap_discover_shared()
114 agbno = XFS_FSB_TO_AGBNO(sc->mp, startblock); in xrep_bmap_discover_shared()
115 cur = sc->sa.refc_cur; in xrep_bmap_discover_shared()
123 rb->reflink_scan = RLS_SET_IFLAG; in xrep_bmap_discover_shared()
128 /* Remember this reverse-mapping as a series of bmap records. */
143 struct xfs_scrub *sc = rb->sc; in xrep_bmap_from_rmap()
147 * If we're repairing the data fork of a non-reflinked regular file on in xrep_bmap_from_rmap()
151 if (rb->reflink_scan == RLS_UNKNOWN && !unwritten) { in xrep_bmap_from_rmap()
163 fa = xfs_bmap_validate_extent(sc->ip, rb->whichfork, &irec); in xrep_bmap_from_rmap()
165 return -EFSCORRUPTED; in xrep_bmap_from_rmap()
169 trace_xrep_bmap_found(sc->ip, rb->whichfork, &irec); in xrep_bmap_from_rmap()
174 error = xfarray_append(rb->bmap_records, &rbe); in xrep_bmap_from_rmap()
178 rb->real_mappings++; in xrep_bmap_from_rmap()
182 blockcount -= irec.br_blockcount; in xrep_bmap_from_rmap()
195 struct xfs_scrub *sc = rb->sc; in xrep_bmap_check_fork_rmap()
201 * everything else (xattrs, bmbt blocks) can be. in xrep_bmap_check_fork_rmap()
203 if (XFS_IS_REALTIME_INODE(sc->ip) && in xrep_bmap_check_fork_rmap()
204 !(rec->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))) in xrep_bmap_check_fork_rmap()
205 return -EFSCORRUPTED; in xrep_bmap_check_fork_rmap()
208 if (!xfs_verify_agbext(to_perag(cur->bc_group), rec->rm_startblock, in xrep_bmap_check_fork_rmap()
209 rec->rm_blockcount)) in xrep_bmap_check_fork_rmap()
210 return -EFSCORRUPTED; in xrep_bmap_check_fork_rmap()
213 if (!(rec->rm_flags & XFS_RMAP_BMBT_BLOCK) && in xrep_bmap_check_fork_rmap()
214 !xfs_verify_fileext(sc->mp, rec->rm_offset, rec->rm_blockcount)) in xrep_bmap_check_fork_rmap()
215 return -EFSCORRUPTED; in xrep_bmap_check_fork_rmap()
218 if ((rec->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK)) && in xrep_bmap_check_fork_rmap()
219 (rec->rm_flags & XFS_RMAP_UNWRITTEN)) in xrep_bmap_check_fork_rmap()
220 return -EFSCORRUPTED; in xrep_bmap_check_fork_rmap()
223 error = xfs_alloc_has_records(sc->sa.bno_cur, rec->rm_startblock, in xrep_bmap_check_fork_rmap()
224 rec->rm_blockcount, &outcome); in xrep_bmap_check_fork_rmap()
228 return -EFSCORRUPTED; in xrep_bmap_check_fork_rmap()
231 error = xfs_ialloc_has_inodes_at_extent(sc->sa.ino_cur, in xrep_bmap_check_fork_rmap()
232 rec->rm_startblock, rec->rm_blockcount, &outcome); in xrep_bmap_check_fork_rmap()
236 return -EFSCORRUPTED; in xrep_bmap_check_fork_rmap()
252 if (xchk_should_terminate(rb->sc, &error)) in xrep_bmap_walk_rmap()
255 if (rec->rm_owner != rb->sc->ip->i_ino) in xrep_bmap_walk_rmap()
263 * Record all blocks allocated to this file even if the extent isn't in xrep_bmap_walk_rmap()
266 rb->nblocks += rec->rm_blockcount; in xrep_bmap_walk_rmap()
269 if (rb->whichfork == XFS_DATA_FORK && in xrep_bmap_walk_rmap()
270 (rec->rm_flags & XFS_RMAP_ATTR_FORK)) in xrep_bmap_walk_rmap()
272 if (rb->whichfork == XFS_ATTR_FORK && in xrep_bmap_walk_rmap()
273 !(rec->rm_flags & XFS_RMAP_ATTR_FORK)) in xrep_bmap_walk_rmap()
277 if ((rec->rm_flags & XFS_RMAP_UNWRITTEN) && !rb->allow_unwritten) in xrep_bmap_walk_rmap()
278 return -EFSCORRUPTED; in xrep_bmap_walk_rmap()
280 fsbno = xfs_agbno_to_fsb(to_perag(cur->bc_group), rec->rm_startblock); in xrep_bmap_walk_rmap()
282 if (rec->rm_flags & XFS_RMAP_BMBT_BLOCK) { in xrep_bmap_walk_rmap()
283 rb->old_bmbt_block_count += rec->rm_blockcount; in xrep_bmap_walk_rmap()
284 return xfsb_bitmap_set(&rb->old_bmbt_blocks, fsbno, in xrep_bmap_walk_rmap()
285 rec->rm_blockcount); in xrep_bmap_walk_rmap()
288 return xrep_bmap_from_rmap(rb, rec->rm_offset, fsbno, in xrep_bmap_walk_rmap()
289 rec->rm_blockcount, in xrep_bmap_walk_rmap()
290 rec->rm_flags & XFS_RMAP_UNWRITTEN); in xrep_bmap_walk_rmap()
310 return -1; in xrep_bmap_extent_cmp()
327 error = xfarray_sort(rb->bmap_records, xrep_bmap_extent_cmp, in xrep_bmap_sort_records()
332 foreach_xfarray_idx(rb->bmap_records, array_cur) { in xrep_bmap_sort_records()
335 if (xchk_should_terminate(rb->sc, &error)) in xrep_bmap_sort_records()
338 error = xfarray_load(rb->bmap_records, array_cur, &rec); in xrep_bmap_sort_records()
345 return -EFSCORRUPTED; in xrep_bmap_sort_records()
359 struct xfs_scrub *sc = rb->sc; in xrep_bmap_scan_ag()
362 error = xrep_ag_init(sc, pag, &sc->sa); in xrep_bmap_scan_ag()
366 error = xfs_rmap_query_all(sc->sa.rmap_cur, xrep_bmap_walk_rmap, rb); in xrep_bmap_scan_ag()
367 xchk_ag_free(sc, &sc->sa); in xrep_bmap_scan_ag()
380 if (rec->rm_flags & XFS_RMAP_ATTR_FORK) in xrep_bmap_check_rtfork_rmap()
381 return -EFSCORRUPTED; in xrep_bmap_check_rtfork_rmap()
383 /* bmbt blocks are never stored on realtime devices */ in xrep_bmap_check_rtfork_rmap()
384 if (rec->rm_flags & XFS_RMAP_BMBT_BLOCK) in xrep_bmap_check_rtfork_rmap()
385 return -EFSCORRUPTED; in xrep_bmap_check_rtfork_rmap()
387 /* Data extents for non-rt files are never stored on the rt device. */ in xrep_bmap_check_rtfork_rmap()
388 if (!XFS_IS_REALTIME_INODE(sc->ip)) in xrep_bmap_check_rtfork_rmap()
389 return -EFSCORRUPTED; in xrep_bmap_check_rtfork_rmap()
392 if (!xfs_verify_fileext(sc->mp, rec->rm_offset, rec->rm_blockcount)) in xrep_bmap_check_rtfork_rmap()
393 return -EFSCORRUPTED; in xrep_bmap_check_rtfork_rmap()
396 if (!xfs_verify_rgbext(to_rtg(cur->bc_group), rec->rm_startblock, in xrep_bmap_check_rtfork_rmap()
397 rec->rm_blockcount)) in xrep_bmap_check_rtfork_rmap()
398 return -EFSCORRUPTED; in xrep_bmap_check_rtfork_rmap()
401 return xrep_require_rtext_inuse(sc, rec->rm_startblock, in xrep_bmap_check_rtfork_rmap()
402 rec->rm_blockcount); in xrep_bmap_check_rtfork_rmap()
415 if (xchk_should_terminate(rb->sc, &error)) in xrep_bmap_walk_rtrmap()
419 if (rec->rm_owner != rb->sc->ip->i_ino) in xrep_bmap_walk_rtrmap()
422 error = xrep_bmap_check_rtfork_rmap(rb->sc, cur, rec); in xrep_bmap_walk_rtrmap()
427 * Record all blocks allocated to this file even if the extent isn't in xrep_bmap_walk_rtrmap()
430 rb->nblocks += rec->rm_blockcount; in xrep_bmap_walk_rtrmap()
433 if (rb->whichfork == XFS_DATA_FORK && in xrep_bmap_walk_rtrmap()
434 (rec->rm_flags & XFS_RMAP_ATTR_FORK)) in xrep_bmap_walk_rtrmap()
436 if (rb->whichfork == XFS_ATTR_FORK && in xrep_bmap_walk_rtrmap()
437 !(rec->rm_flags & XFS_RMAP_ATTR_FORK)) in xrep_bmap_walk_rtrmap()
440 return xrep_bmap_from_rmap(rb, rec->rm_offset, in xrep_bmap_walk_rtrmap()
441 xfs_rgbno_to_rtb(to_rtg(cur->bc_group), in xrep_bmap_walk_rtrmap()
442 rec->rm_startblock), in xrep_bmap_walk_rtrmap()
443 rec->rm_blockcount, in xrep_bmap_walk_rtrmap()
444 rec->rm_flags & XFS_RMAP_UNWRITTEN); in xrep_bmap_walk_rtrmap()
453 struct xfs_scrub *sc = rb->sc; in xrep_bmap_scan_rtgroup()
456 if (!xfs_has_rtrmapbt(sc->mp)) in xrep_bmap_scan_rtgroup()
459 error = xrep_rtgroup_init(sc, rtg, &sc->sr, in xrep_bmap_scan_rtgroup()
466 error = xfs_rmap_query_all(sc->sr.rmap_cur, xrep_bmap_walk_rtrmap, rb); in xrep_bmap_scan_rtgroup()
467 xchk_rtgroup_btcur_free(&sc->sr); in xrep_bmap_scan_rtgroup()
468 xchk_rtgroup_free(sc, &sc->sr); in xrep_bmap_scan_rtgroup()
475 return -EFSCORRUPTED; in xrep_bmap_scan_rtgroup()
487 struct xfs_inode *ip = rb->sc->ip; in xrep_bmap_find_delalloc() local
488 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, rb->whichfork); in xrep_bmap_find_delalloc()
495 if (rb->whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0) in xrep_bmap_find_delalloc()
504 trace_xrep_bmap_found(ip, rb->whichfork, &irec); in xrep_bmap_find_delalloc()
506 if (xchk_should_terminate(rb->sc, &error)) in xrep_bmap_find_delalloc()
509 error = xfarray_append(rb->bmap_records, &rbe); in xrep_bmap_find_delalloc()
526 struct xfs_scrub *sc = rb->sc; in xrep_bmap_find_mappings()
534 if (!xfs_is_metadir_inode(sc->ip)) { in xrep_bmap_find_mappings()
537 while ((rtg = xfs_rtgroup_next(sc->mp, rtg))) { in xrep_bmap_find_mappings()
547 while ((pag = xfs_perag_next(sc->mp, pag))) { in xrep_bmap_find_mappings()
568 struct xfs_bmbt_irec *irec = &cur->bc_rec.b; in xrep_bmap_get_records()
576 error = xfarray_load(rb->bmap_records, rb->array_cur++, in xrep_bmap_get_records()
582 } while (isnullstartblock(irec->br_startblock)); in xrep_bmap_get_records()
585 cur->bc_ops->init_rec_from_cur(cur, block_rec); in xrep_bmap_get_records()
591 /* Feed one of the new btree blocks to the bulk loader. */
600 return xrep_newbt_claim_block(cur, &rb->new_bmapbt, ptr); in xrep_bmap_claim_block()
613 return xfs_bmap_broot_space_calc(cur->bc_mp, nr_this_level); in xrep_bmap_iroot_size()
621 struct xfs_scrub *sc = rb->sc; in xrep_bmap_reset_counters()
622 struct xbtree_ifakeroot *ifake = &rb->new_bmapbt.ifake; in xrep_bmap_reset_counters()
625 if (rb->reflink_scan == RLS_SET_IFLAG) in xrep_bmap_reset_counters()
626 sc->ip->i_diflags2 |= XFS_DIFLAG2_REFLINK; in xrep_bmap_reset_counters()
632 delta = ifake->if_blocks - rb->old_bmbt_block_count; in xrep_bmap_reset_counters()
633 sc->ip->i_nblocks = rb->nblocks + delta; in xrep_bmap_reset_counters()
634 xfs_trans_log_inode(sc->tp, sc->ip, XFS_ILOG_CORE); in xrep_bmap_reset_counters()
640 xfs_trans_mod_dquot_byino(sc->tp, sc->ip, XFS_TRANS_DQ_BCOUNT, delta); in xrep_bmap_reset_counters()
655 struct xfs_ifork *ifp = rb->new_bmapbt.ifake.if_fork; in xrep_bmap_extents_load()
659 ASSERT(ifp->if_bytes == 0); in xrep_bmap_extents_load()
663 foreach_xfarray_idx(rb->bmap_records, array_cur) { in xrep_bmap_extents_load()
666 error = xfarray_load(rb->bmap_records, array_cur, &rec); in xrep_bmap_extents_load()
674 ifp->if_nextents++; in xrep_bmap_extents_load()
679 return xrep_ino_ensure_extent_count(rb->sc, rb->whichfork, in xrep_bmap_extents_load()
680 ifp->if_nextents); in xrep_bmap_extents_load()
684 * Reserve new btree blocks, bulk load the bmap records into the ondisk btree,
692 struct xfs_scrub *sc = rb->sc; in xrep_bmap_btree_load()
695 /* Compute how many blocks we'll need. */ in xrep_bmap_btree_load()
697 &rb->new_bmapbt.bload, rb->real_mappings); in xrep_bmap_btree_load()
706 * Guess how many blocks we're going to need to rebuild an entire bmap in xrep_bmap_btree_load()
711 error = xfs_trans_reserve_more_inode(sc->tp, sc->ip, in xrep_bmap_btree_load()
712 rb->new_bmapbt.bload.nr_blocks, 0, true); in xrep_bmap_btree_load()
717 error = xrep_newbt_alloc_blocks(&rb->new_bmapbt, in xrep_bmap_btree_load()
718 rb->new_bmapbt.bload.nr_blocks); in xrep_bmap_btree_load()
723 rb->array_cur = XFARRAY_CURSOR_INIT; in xrep_bmap_btree_load()
724 error = xfs_btree_bload(bmap_cur, &rb->new_bmapbt.bload, rb); in xrep_bmap_btree_load()
750 struct xfs_scrub *sc = rb->sc; in xrep_bmap_build_new_fork()
752 struct xbtree_ifakeroot *ifake = &rb->new_bmapbt.ifake; in xrep_bmap_build_new_fork()
763 xfs_rmap_ino_bmbt_owner(&oinfo, sc->ip->i_ino, rb->whichfork); in xrep_bmap_build_new_fork()
764 error = xrep_newbt_init_inode(&rb->new_bmapbt, sc, rb->whichfork, in xrep_bmap_build_new_fork()
769 rb->new_bmapbt.bload.get_records = xrep_bmap_get_records; in xrep_bmap_build_new_fork()
770 rb->new_bmapbt.bload.claim_block = xrep_bmap_claim_block; in xrep_bmap_build_new_fork()
771 rb->new_bmapbt.bload.iroot_size = xrep_bmap_iroot_size; in xrep_bmap_build_new_fork()
777 bmap_cur = xfs_bmbt_init_cursor(sc->mp, NULL, sc->ip, XFS_STAGING_FORK); in xrep_bmap_build_new_fork()
785 if (rb->real_mappings <= XFS_IFORK_MAXEXT(sc->ip, rb->whichfork)) { in xrep_bmap_build_new_fork()
786 ifake->if_fork->if_format = XFS_DINODE_FMT_EXTENTS; in xrep_bmap_build_new_fork()
789 ifake->if_fork->if_format = XFS_DINODE_FMT_BTREE; in xrep_bmap_build_new_fork()
801 xfs_bmbt_commit_staged_btree(bmap_cur, sc->tp, rb->whichfork); in xrep_bmap_build_new_fork()
809 /* Dispose of any unused blocks and the accounting information. */ in xrep_bmap_build_new_fork()
810 error = xrep_newbt_commit(&rb->new_bmapbt); in xrep_bmap_build_new_fork()
820 xrep_newbt_cancel(&rb->new_bmapbt); in xrep_bmap_build_new_fork()
825 * Now that we've logged the new inode btree, invalidate all of the old blocks
832 struct xfs_scrub *sc = rb->sc; in xrep_bmap_remove_old_tree()
835 /* Free the old bmbt blocks if they're not in use. */ in xrep_bmap_remove_old_tree()
836 xfs_rmap_ino_bmbt_owner(&oinfo, sc->ip->i_ino, rb->whichfork); in xrep_bmap_remove_old_tree()
837 return xrep_reap_fsblocks(sc, &rb->old_bmbt_blocks, &oinfo); in xrep_bmap_remove_old_tree()
840 /* Check for garbage inputs. Returns -ECANCELED if there's nothing to do. */
846 struct xfs_ifork *ifp = xfs_ifork_ptr(sc->ip, whichfork); in xrep_bmap_check_inputs()
850 if (!xfs_has_rmapbt(sc->mp)) in xrep_bmap_check_inputs()
851 return -EOPNOTSUPP; in xrep_bmap_check_inputs()
855 return -ECANCELED; in xrep_bmap_check_inputs()
863 switch (ifp->if_format) { in xrep_bmap_check_inputs()
868 return -ECANCELED; in xrep_bmap_check_inputs()
873 return -EFSCORRUPTED; in xrep_bmap_check_inputs()
880 switch (VFS_I(sc->ip)->i_mode & S_IFMT) { in xrep_bmap_check_inputs()
887 return -EINVAL; in xrep_bmap_check_inputs()
899 /* cannot share on non-reflink filesystem */ in xrep_bmap_init_reflink_scan()
900 if (!xfs_has_reflink(sc->mp)) in xrep_bmap_init_reflink_scan()
904 if (xfs_is_reflink_inode(sc->ip)) in xrep_bmap_init_reflink_scan()
908 if (!S_ISREG(VFS_I(sc->ip)->i_mode)) in xrep_bmap_init_reflink_scan()
932 if (error == -ECANCELED) in xrep_bmap()
939 return -ENOMEM; in xrep_bmap()
940 rb->sc = sc; in xrep_bmap()
941 rb->whichfork = whichfork; in xrep_bmap()
942 rb->reflink_scan = xrep_bmap_init_reflink_scan(sc, whichfork); in xrep_bmap()
943 rb->allow_unwritten = allow_unwritten; in xrep_bmap()
946 large_extcount = xfs_has_large_extent_counts(sc->mp); in xrep_bmap()
951 sizeof(struct xfs_bmbt_rec), &rb->bmap_records); in xrep_bmap()
957 xfsb_bitmap_init(&rb->old_bmbt_blocks); in xrep_bmap()
962 xfs_trans_ijoin(sc->tp, sc->ip, 0); in xrep_bmap()
975 xfsb_bitmap_destroy(&rb->old_bmbt_blocks); in xrep_bmap()
976 xfarray_destroy(rb->bmap_records); in xrep_bmap()