drivers/md/bcache/btree.c
Source file repositories/reference/linux-study-clean/drivers/md/bcache/btree.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/md/bcache/btree.c- Extension
.c- Size
- 65542 bytes
- Lines
- 2832
- Domain
- Driver Families
- Bucket
- drivers/md
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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
bcache.hbtree.hdebug.hextents.hlinux/slab.hlinux/bitops.hlinux/hash.hlinux/kthread.hlinux/prefetch.hlinux/random.hlinux/rcupdate.hlinux/sched/clock.hlinux/rculist.hlinux/delay.hlinux/sort.htrace/events/bcache.h
Detected Declarations
struct gc_merge_infostruct btree_insert_opstruct refillfunction bch_btree_init_nextfunction bkey_putfunction btree_csum_setfunction bch_btree_node_read_donefunction btree_node_read_endiofunction bch_btree_node_readfunction btree_complete_writefunction CLOSURE_CALLBACKfunction CLOSURE_CALLBACKfunction CLOSURE_CALLBACKfunction btree_node_write_endiofunction do_btree_node_writefunction bio_for_each_segment_allfunction __bch_btree_node_writefunction bch_btree_node_writefunction bch_btree_node_write_syncfunction btree_node_write_workfunction bch_btree_leaf_dirtyfunction mca_data_freefunction mca_bucket_freefunction btree_orderfunction mca_data_allocfunction btree_lock_cmp_fnfunction btree_lock_print_fnfunction mca_reapfunction btree_flush_writefunction bch_mca_scanfunction list_for_each_entry_safe_reversefunction bch_mca_countfunction bch_btree_cache_freefunction cache_set_freefunction bch_btree_cache_allocfunction mca_cannibalize_lockfunction cannibalize_bucketfunction btree_node_prefetchfunction btree_node_freefunction btree_flush_writefunction make_btree_freeing_keyfunction btree_check_reservefunction __bch_btree_mark_keyfunction bch_initial_mark_keyfunction bch_update_bucket_in_usefunction btree_gc_mark_nodefunction for_each_key_filterfunction btree_gc_coalesce
Annotated Snippet
struct gc_merge_info {
struct btree *b;
unsigned int keys;
};
static int bch_btree_insert_node(struct btree *b, struct btree_op *op,
struct keylist *insert_keys,
atomic_t *journal_ref,
struct bkey *replace_key);
static int btree_gc_coalesce(struct btree *b, struct btree_op *op,
struct gc_stat *gc, struct gc_merge_info *r)
{
unsigned int i, nodes = 0, keys = 0, blocks;
struct btree *new_nodes[GC_MERGE_NODES];
struct keylist keylist;
struct closure cl;
struct bkey *k;
bch_keylist_init(&keylist);
if (btree_check_reserve(b, NULL))
return 0;
memset(new_nodes, 0, sizeof(new_nodes));
closure_init_stack(&cl);
while (nodes < GC_MERGE_NODES && !IS_ERR_OR_NULL(r[nodes].b))
keys += r[nodes++].keys;
blocks = btree_default_blocks(b->c) * 2 / 3;
if (nodes < 2 ||
__set_blocks(b->keys.set[0].data, keys,
block_bytes(b->c->cache)) > blocks * (nodes - 1))
return 0;
for (i = 0; i < nodes; i++) {
new_nodes[i] = btree_node_alloc_replacement(r[i].b, NULL);
if (IS_ERR(new_nodes[i]))
goto out_nocoalesce;
}
/*
* We have to check the reserve here, after we've allocated our new
* nodes, to make sure the insert below will succeed - we also check
* before as an optimization to potentially avoid a bunch of expensive
* allocs/sorts
*/
if (btree_check_reserve(b, NULL))
goto out_nocoalesce;
for (i = 0; i < nodes; i++)
mutex_lock(&new_nodes[i]->write_lock);
for (i = nodes - 1; i > 0; --i) {
struct bset *n1 = btree_bset_first(new_nodes[i]);
struct bset *n2 = btree_bset_first(new_nodes[i - 1]);
struct bkey *k, *last = NULL;
keys = 0;
if (i > 1) {
for (k = n2->start;
k < bset_bkey_last(n2);
k = bkey_next(k)) {
if (__set_blocks(n1, n1->keys + keys +
bkey_u64s(k),
block_bytes(b->c->cache)) > blocks)
break;
last = k;
keys += bkey_u64s(k);
}
} else {
/*
* Last node we're not getting rid of - we're getting
* rid of the node at r[0]. Have to try and fit all of
* the remaining keys into this node; we can't ensure
* they will always fit due to rounding and variable
* length keys (shouldn't be possible in practice,
* though)
*/
if (__set_blocks(n1, n1->keys + n2->keys,
block_bytes(b->c->cache)) >
btree_blocks(new_nodes[i]))
goto out_unlock_nocoalesce;
keys = n2->keys;
/* Take the key of the node we're getting rid of */
Annotation
- Immediate include surface: `bcache.h`, `btree.h`, `debug.h`, `extents.h`, `linux/slab.h`, `linux/bitops.h`, `linux/hash.h`, `linux/kthread.h`.
- Detected declarations: `struct gc_merge_info`, `struct btree_insert_op`, `struct refill`, `function bch_btree_init_next`, `function bkey_put`, `function btree_csum_set`, `function bch_btree_node_read_done`, `function btree_node_read_endio`, `function bch_btree_node_read`, `function btree_complete_write`.
- Atlas domain: Driver Families / drivers/md.
- 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.