drivers/md/bcache/journal.c
Source file repositories/reference/linux-study-clean/drivers/md/bcache/journal.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/md/bcache/journal.c- Extension
.c- Size
- 22138 bytes
- Lines
- 924
- 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.htrace/events/bcache.h
Detected Declarations
function entriesfunction journal_read_bucketfunction list_for_each_entry_reversefunction bch_journal_readfunction bch_journal_markfunction list_for_each_entry_reversefunction bch_journal_replayfunction list_for_each_entryfunction bch_journal_space_reservefunction btree_flush_writefunction nowfunction free_journal_bucketsfunction journal_reclaimfunction bch_journal_nextfunction journal_write_endiofunction CLOSURE_CALLBACKfunction CLOSURE_CALLBACKfunction CLOSURE_CALLBACKfunction CLOSURE_CALLBACKfunction journal_try_writefunction journal_write_workfunction bch_journalfunction bch_journal_metafunction bch_journal_freefunction bch_journal_alloc
Annotated Snippet
while (len) {
struct list_head *where;
size_t blocks, bytes = set_bytes(j);
if (j->magic != jset_magic(&ca->sb)) {
pr_debug("%u: bad magic\n", bucket_index);
return ret;
}
if (bytes > left << 9 ||
bytes > PAGE_SIZE << JSET_BITS) {
pr_info("%u: too big, %zu bytes, offset %u\n",
bucket_index, bytes, offset);
return ret;
}
if (bytes > len << 9)
goto reread;
if (j->csum != csum_set(j)) {
pr_info("%u: bad csum, %zu bytes, offset %u\n",
bucket_index, bytes, offset);
return ret;
}
blocks = set_blocks(j, block_bytes(ca));
/*
* Nodes in 'list' are in linear increasing order of
* i->j.seq, the node on head has the smallest (oldest)
* journal seq, the node on tail has the biggest
* (latest) journal seq.
*/
/*
* Check from the oldest jset for last_seq. If
* i->j.seq < j->last_seq, it means the oldest jset
* in list is expired and useless, remove it from
* this list. Otherwise, j is a candidate jset for
* further following checks.
*/
while (!list_empty(list)) {
i = list_first_entry(list,
struct journal_replay, list);
if (i->j.seq >= j->last_seq)
break;
list_del(&i->list);
kfree(i);
}
/* iterate list in reverse order (from latest jset) */
list_for_each_entry_reverse(i, list, list) {
if (j->seq == i->j.seq)
goto next_set;
/*
* if j->seq is less than any i->j.last_seq
* in list, j is an expired and useless jset.
*/
if (j->seq < i->j.last_seq)
goto next_set;
/*
* 'where' points to first jset in list which
* is elder then j.
*/
if (j->seq > i->j.seq) {
where = &i->list;
goto add;
}
}
where = list;
add:
i = kmalloc(offsetof(struct journal_replay, j) +
bytes, GFP_KERNEL);
if (!i)
return -ENOMEM;
unsafe_memcpy(&i->j, j, bytes,
/* "bytes" was calculated by set_bytes() above */);
/* Add to the location after 'where' points to */
list_add(&i->list, where);
ret = 1;
if (j->seq > ja->seq[bucket_index])
ja->seq[bucket_index] = j->seq;
next_set:
offset += blocks * ca->sb.block_size;
len -= blocks * ca->sb.block_size;
j = ((void *) j) + blocks * block_bytes(ca);
Annotation
- Immediate include surface: `bcache.h`, `btree.h`, `debug.h`, `extents.h`, `trace/events/bcache.h`.
- Detected declarations: `function entries`, `function journal_read_bucket`, `function list_for_each_entry_reverse`, `function bch_journal_read`, `function bch_journal_mark`, `function list_for_each_entry_reverse`, `function bch_journal_replay`, `function list_for_each_entry`, `function bch_journal_space_reserve`, `function btree_flush_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.