// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2022-2023 Oracle. All Rights Reserved. * Author: Darrick J. Wong <[email protected]> */ #include "xfs.h" #include "xfs_fs.h" #include "xfs_shared.h" #include "xfs_format.h" #include "xfs_trans_resv.h" #include "xfs_mount.h" #include "xfs_btree.h" #include "xfs_btree_staging.h" #include "xfs_log_format.h" #include "xfs_trans.h" #include "xfs_sb.h" #include "xfs_inode.h" #include "xfs_alloc.h" #include "xfs_rmap.h" #include "xfs_ag.h" #include "xfs_defer.h" #include "scrub/scrub.h" #include "scrub/common.h" #include "scrub/trace.h" #include "scrub/repair.h" #include "scrub/newbt.h" /* * Estimate proper slack values for a btree that's being reloaded. * * Under most circumstances, we'll take whatever default loading value the * btree bulk loading code calculates for us. However, there are some * exceptions to this rule: * * (0) If someone turned one of the debug knobs. * (1) If this is a per-AG btree and the AG has less than 10% space free. * (2) If this is an inode btree and the FS has less than 10% space free. * In either case, format the new btree blocks almost completely full to * minimize space usage. */ static void xrep_newbt_estimate_slack( struct xrep_newbt *xnr) { … } /* Initialize accounting resources for staging a new AG btree. */ void xrep_newbt_init_ag( struct xrep_newbt *xnr, struct xfs_scrub *sc, const struct xfs_owner_info *oinfo, xfs_fsblock_t alloc_hint, enum xfs_ag_resv_type resv) { … } /* Initialize accounting resources for staging a new inode fork btree. */ int xrep_newbt_init_inode( struct xrep_newbt *xnr, struct xfs_scrub *sc, int whichfork, const struct xfs_owner_info *oinfo) { … } /* * Initialize accounting resources for staging a new btree. Callers are * expected to add their own reservations (and clean them up) manually. */ void xrep_newbt_init_bare( struct xrep_newbt *xnr, struct xfs_scrub *sc) { … } /* * Designate specific blocks to be used to build our new btree. @pag must be * a passive reference. */ STATIC int xrep_newbt_add_blocks( struct xrep_newbt *xnr, struct xfs_perag *pag, const struct xfs_alloc_arg *args) { … } /* * Add an extent to the new btree reservation pool. Callers are required to * reap this reservation manually if the repair is cancelled. @pag must be a * passive reference. */ int xrep_newbt_add_extent( struct xrep_newbt *xnr, struct xfs_perag *pag, xfs_agblock_t agbno, xfs_extlen_t len) { … } /* Don't let our allocation hint take us beyond this AG */ static inline void xrep_newbt_validate_ag_alloc_hint( struct xrep_newbt *xnr) { … } /* Allocate disk space for a new per-AG btree. */ STATIC int xrep_newbt_alloc_ag_blocks( struct xrep_newbt *xnr, uint64_t nr_blocks) { … } /* Don't let our allocation hint take us beyond EOFS */ static inline void xrep_newbt_validate_file_alloc_hint( struct xrep_newbt *xnr) { … } /* Allocate disk space for our new file-based btree. */ STATIC int xrep_newbt_alloc_file_blocks( struct xrep_newbt *xnr, uint64_t nr_blocks) { … } /* Allocate disk space for our new btree. */ int xrep_newbt_alloc_blocks( struct xrep_newbt *xnr, uint64_t nr_blocks) { … } /* * Free the unused part of a space extent that was reserved for a new ondisk * structure. Returns the number of EFIs logged or a negative errno. */ STATIC int xrep_newbt_free_extent( struct xrep_newbt *xnr, struct xrep_newbt_resv *resv, bool btree_committed) { … } /* Free all the accounting info and disk space we reserved for a new btree. */ STATIC int xrep_newbt_free( struct xrep_newbt *xnr, bool btree_committed) { … } /* * Free all the accounting info and unused disk space allocations after * committing a new btree. */ int xrep_newbt_commit( struct xrep_newbt *xnr) { … } /* * Free all the accounting info and all of the disk space we reserved for a new * btree that we're not going to commit. We want to try to roll things back * cleanly for things like ENOSPC midway through allocation. */ void xrep_newbt_cancel( struct xrep_newbt *xnr) { … } /* Feed one of the reserved btree blocks to the bulk loader. */ int xrep_newbt_claim_block( struct xfs_btree_cur *cur, struct xrep_newbt *xnr, union xfs_btree_ptr *ptr) { … } /* How many reserved blocks are unused? */ unsigned int xrep_newbt_unused_blocks( struct xrep_newbt *xnr) { … }