fs/xfs/libxfs/xfs_refcount.c
Source file repositories/reference/linux-study-clean/fs/xfs/libxfs/xfs_refcount.c
File Facts
- System
- Linux kernel
- Corpus path
fs/xfs/libxfs/xfs_refcount.c- Extension
.c- Size
- 59931 bytes
- Lines
- 2245
- Domain
- Core OS
- Bucket
- VFS And Filesystem Core
- Inferred role
- Core OS: implementation source
- Status
- source implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
xfs_platform.hxfs_fs.hxfs_shared.hxfs_format.hxfs_log_format.hxfs_trans_resv.hxfs_mount.hxfs_defer.hxfs_btree.hxfs_bmap.hxfs_refcount_btree.hxfs_alloc.hxfs_errortag.hxfs_error.hxfs_trace.hxfs_trans.hxfs_bit.hxfs_refcount.hxfs_rmap.hxfs_ag.hxfs_health.hxfs_refcount_item.hxfs_rtgroup.hxfs_rtalloc.hxfs_rtrefcount_btree.h
Detected Declarations
struct xfs_refcount_recoverystruct xfs_refcount_query_range_infoenum xfs_refc_adjust_opfunction xfs_refcount_lookup_lefunction xfs_refcount_lookup_gefunction xfs_refcount_lookup_eqfunction xfs_refcount_btrec_to_irecfunction xfs_refcount_check_irecfunction xfs_rtrefcount_check_irecfunction xfs_refcount_check_btrecfunction xfs_refcount_complain_bad_recfunction xfs_refcount_get_recfunction worksfunction worksfunction worksfunction xfs_refc_nextfunction xfs_refcount_split_extentfunction xfs_refcount_merge_center_extentsfunction xfs_refcount_merge_left_extentfunction xfs_refcount_merge_right_extentfunction itfunction itfunction xfs_refc_validfunction xfs_refc_merge_refcountfunction xfs_refc_want_merge_centerfunction xfs_refc_want_merge_leftfunction xfs_refc_want_merge_rightfunction xfs_refcount_merge_extentsfunction xfs_refcount_still_have_spacefunction xrefc_free_extentfunction xfs_refcount_adjust_extentsfunction xfs_refcount_adjustfunction xfs_refcount_continue_opfunction xfs_refcount_finish_onefunction xfs_rtrefcount_continue_opfunction xfs_rtrefcount_finish_onefunction __xfs_refcount_addfunction xfs_refcount_increase_extentfunction xfs_refcount_decrease_extentfunction xfs_refcount_find_sharedfunction remappingfunction xfs_refcount_adjust_cowfunction __xfs_refcount_cow_allocfunction __xfs_refcount_cow_freefunction xfs_refcount_alloc_cow_extentfunction xfs_refcount_free_cow_extentfunction xfs_refcount_recover_extentfunction xfs_refcount_recover_cow_leftovers
Annotated Snippet
struct xfs_refcount_recovery {
struct list_head rr_list;
struct xfs_refcount_irec rr_rrec;
};
/* Stuff an extent on the recovery list. */
STATIC int
xfs_refcount_recover_extent(
struct xfs_btree_cur *cur,
const union xfs_btree_rec *rec,
void *priv)
{
struct list_head *debris = priv;
struct xfs_refcount_recovery *rr;
if (XFS_IS_CORRUPT(cur->bc_mp,
be32_to_cpu(rec->refc.rc_refcount) != 1)) {
xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
}
rr = kmalloc_obj(struct xfs_refcount_recovery,
GFP_KERNEL | __GFP_NOFAIL);
INIT_LIST_HEAD(&rr->rr_list);
xfs_refcount_btrec_to_irec(rec, &rr->rr_rrec);
if (xfs_refcount_check_btrec(cur, &rr->rr_rrec) != NULL ||
XFS_IS_CORRUPT(cur->bc_mp,
rr->rr_rrec.rc_domain != XFS_REFC_DOMAIN_COW)) {
xfs_btree_mark_sick(cur);
kfree(rr);
return -EFSCORRUPTED;
}
list_add_tail(&rr->rr_list, debris);
return 0;
}
/* Find and remove leftover CoW reservations. */
int
xfs_refcount_recover_cow_leftovers(
struct xfs_group *xg)
{
struct xfs_mount *mp = xg->xg_mount;
bool isrt = xg->xg_type == XG_TYPE_RTG;
struct xfs_trans *tp;
struct xfs_btree_cur *cur;
struct xfs_buf *agbp = NULL;
struct xfs_refcount_recovery *rr, *n;
struct list_head debris;
union xfs_btree_irec low = {
.rc.rc_domain = XFS_REFC_DOMAIN_COW,
};
union xfs_btree_irec high = {
.rc.rc_domain = XFS_REFC_DOMAIN_COW,
.rc.rc_startblock = -1U,
};
xfs_fsblock_t fsb;
int error;
/* reflink filesystems must not have groups larger than 2^31-1 blocks */
BUILD_BUG_ON(XFS_MAX_RGBLOCKS >= XFS_REFC_COWFLAG);
BUILD_BUG_ON(XFS_MAX_CRC_AG_BLOCKS >= XFS_REFC_COWFLAG);
if (isrt) {
if (!xfs_has_rtgroups(mp))
return 0;
if (xfs_group_max_blocks(xg) >= XFS_MAX_RGBLOCKS)
return -EOPNOTSUPP;
} else {
if (xfs_group_max_blocks(xg) > XFS_MAX_CRC_AG_BLOCKS)
return -EOPNOTSUPP;
}
INIT_LIST_HEAD(&debris);
/*
* In this first part, we use an empty transaction to gather up
* all the leftover CoW extents so that we can subsequently
* delete them. The empty transaction is used to avoid
* a buffer lock deadlock if there happens to be a loop in the
* refcountbt because we're allowed to re-grab a buffer that is
* already attached to our transaction. When we're done
* recording the CoW debris we cancel the (empty) transaction
* and everything goes away cleanly.
*/
tp = xfs_trans_alloc_empty(mp);
if (isrt) {
xfs_rtgroup_lock(to_rtg(xg), XFS_RTGLOCK_REFCOUNT);
Annotation
- Immediate include surface: `xfs_platform.h`, `xfs_fs.h`, `xfs_shared.h`, `xfs_format.h`, `xfs_log_format.h`, `xfs_trans_resv.h`, `xfs_mount.h`, `xfs_defer.h`.
- Detected declarations: `struct xfs_refcount_recovery`, `struct xfs_refcount_query_range_info`, `enum xfs_refc_adjust_op`, `function xfs_refcount_lookup_le`, `function xfs_refcount_lookup_ge`, `function xfs_refcount_lookup_eq`, `function xfs_refcount_btrec_to_irec`, `function xfs_refcount_check_irec`, `function xfs_rtrefcount_check_irec`, `function xfs_refcount_check_btrec`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.