fs/btrfs/discard.c
Source file repositories/reference/linux-study-clean/fs/btrfs/discard.c
File Facts
- System
- Linux kernel
- Corpus path
fs/btrfs/discard.c- Extension
.c- Size
- 25726 bytes
- Lines
- 829
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/jiffies.hlinux/kernel.hlinux/ktime.hlinux/list.hlinux/math64.hlinux/sizes.hlinux/workqueue.hctree.hblock-group.hdiscard.hfree-space-cache.hfs.h
Detected Declarations
function btrfs_run_discard_workfunction __add_to_discard_listfunction add_to_discard_listfunction add_to_discard_unused_listfunction remove_from_discard_listfunction block_group_is_emptyfunction find_next_block_groupfunction btrfs_discard_check_filterfunction btrfs_update_discard_indexfunction btrfs_discard_cancel_workfunction btrfs_discard_queue_workfunction __btrfs_discard_schedule_workfunction btrfs_discard_schedule_workfunction btrfs_finish_discard_passfunction btrfs_discard_workfnfunction upper_limitfunction btrfs_discard_update_discardablefunction btrfs_discard_punt_unused_bgs_listfunction btrfs_discard_purge_listfunction list_for_each_entry_safefunction btrfs_discard_resumefunction btrfs_discard_stopfunction btrfs_discard_initfunction btrfs_discard_cleanup
Annotated Snippet
if (!list_empty(discard_list)) {
block_group = list_first_entry(discard_list,
struct btrfs_block_group,
discard_list);
if (!ret_block_group)
ret_block_group = block_group;
if (ret_block_group->discard_eligible_time < now)
break;
if (ret_block_group->discard_eligible_time >
block_group->discard_eligible_time)
ret_block_group = block_group;
}
}
return ret_block_group;
}
/*
* Check whether a block group is empty.
*
* "Empty" here means that there are no extents physically located within the
* device extents corresponding to this block group.
*
* For a remapped block group, this means that all of its identity remaps have
* been removed. For a non-remapped block group, this means that no extents
* have an address within its range, and that nothing has been remapped to be
* within it.
*/
static bool block_group_is_empty(const struct btrfs_block_group *bg)
{
if (bg->flags & BTRFS_BLOCK_GROUP_REMAPPED)
return bg->identity_remap_count == 0;
return bg->used == 0 && bg->remap_bytes == 0;
}
/*
* Look up next block group and set it for use.
*
* @discard_ctl: discard control
* @discard_state: the discard_state of the block_group after state management
* @discard_index: the discard_index of the block_group after state management
* @now: time when discard was invoked, in ns
*
* Wrap find_next_block_group() and set the block_group to be in use.
* @discard_state's control flow is managed here. Variables related to
* @discard_state are reset here as needed (eg. @discard_cursor). @discard_state
* and @discard_index are remembered as it may change while we're discarding,
* but we want the discard to execute in the context determined here.
*/
static struct btrfs_block_group *peek_discard_list(
struct btrfs_discard_ctl *discard_ctl,
enum btrfs_discard_state *discard_state,
int *discard_index, u64 now)
{
struct btrfs_block_group *block_group;
spin_lock(&discard_ctl->lock);
again:
block_group = find_next_block_group(discard_ctl, now);
if (block_group && now >= block_group->discard_eligible_time) {
const bool empty = block_group_is_empty(block_group);
if (block_group->discard_index == BTRFS_DISCARD_INDEX_UNUSED &&
!empty) {
if (btrfs_is_block_group_data_only(block_group)) {
__add_to_discard_list(discard_ctl, block_group);
/*
* The block group must have been moved to other
* discard list even if discard was disabled in
* the meantime or a transaction abort happened,
* otherwise we can end up in an infinite loop,
* always jumping into the 'again' label and
* keep getting this block group over and over
* in case there are no other block groups in
* the discard lists.
*/
ASSERT(block_group->discard_index !=
BTRFS_DISCARD_INDEX_UNUSED,
"discard_index=%d",
block_group->discard_index);
} else {
list_del_init(&block_group->discard_list);
btrfs_put_block_group(block_group);
}
goto again;
Annotation
- Immediate include surface: `linux/jiffies.h`, `linux/kernel.h`, `linux/ktime.h`, `linux/list.h`, `linux/math64.h`, `linux/sizes.h`, `linux/workqueue.h`, `ctree.h`.
- Detected declarations: `function btrfs_run_discard_work`, `function __add_to_discard_list`, `function add_to_discard_list`, `function add_to_discard_unused_list`, `function remove_from_discard_list`, `function block_group_is_empty`, `function find_next_block_group`, `function btrfs_discard_check_filter`, `function btrfs_update_discard_index`, `function btrfs_discard_cancel_work`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.