drivers/md/dm-pcache/cache_writeback.c
Source file repositories/reference/linux-study-clean/drivers/md/dm-pcache/cache_writeback.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/md/dm-pcache/cache_writeback.c- Extension
.c- Size
- 7337 bytes
- Lines
- 262
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bio.hcache.hbacking_dev.hcache_dev.hdm_pcache.h
Detected Declarations
function writeback_ctx_endfunction writeback_end_reqfunction is_cache_cleanfunction cache_writeback_exitfunction cache_writeback_initfunction cache_key_writebackfunction cache_wb_tree_writebackfunction cache_kset_insert_treefunction last_kset_writebackfunction cache_writeback_fn
Annotated Snippet
while (node) {
key = CACHE_KEY(node);
node = rb_next(node);
cache_key_writeback(cache, key);
cache_key_delete(key);
}
}
writeback_ctx_end(cache, 0);
}
static int cache_kset_insert_tree(struct pcache_cache *cache, struct pcache_cache_kset_onmedia *kset_onmedia)
{
struct pcache_cache_key_onmedia *key_onmedia;
struct pcache_cache_subtree *cache_subtree;
struct pcache_cache_key *key;
int ret;
u32 i;
/* Iterate through all keys in the kset and write each back to storage */
for (i = 0; i < kset_onmedia->key_num; i++) {
key_onmedia = &kset_onmedia->data[i];
key = cache_key_alloc(&cache->writeback_key_tree, GFP_NOIO);
ret = cache_key_decode(cache, key_onmedia, key);
if (ret) {
cache_key_put(key);
goto clear_tree;
}
cache_subtree = get_subtree(&cache->writeback_key_tree, key->off);
spin_lock(&cache_subtree->tree_lock);
cache_key_insert(&cache->writeback_key_tree, key, true);
spin_unlock(&cache_subtree->tree_lock);
}
return 0;
clear_tree:
cache_tree_clear(&cache->writeback_key_tree);
return ret;
}
static void last_kset_writeback(struct pcache_cache *cache,
struct pcache_cache_kset_onmedia *last_kset_onmedia)
{
struct dm_pcache *pcache = CACHE_TO_PCACHE(cache);
struct pcache_cache_segment *next_seg;
pcache_dev_debug(pcache, "last kset, next: %u\n", last_kset_onmedia->next_cache_seg_id);
next_seg = &cache->segments[last_kset_onmedia->next_cache_seg_id];
mutex_lock(&cache->dirty_tail_lock);
cache->dirty_tail.cache_seg = next_seg;
cache->dirty_tail.seg_off = 0;
cache_encode_dirty_tail(cache);
mutex_unlock(&cache->dirty_tail_lock);
}
void cache_writeback_fn(struct work_struct *work)
{
struct pcache_cache *cache = container_of(work, struct pcache_cache, writeback_work.work);
struct dm_pcache *pcache = CACHE_TO_PCACHE(cache);
struct pcache_cache_pos dirty_tail;
struct pcache_cache_kset_onmedia *kset_onmedia;
u32 delay;
int ret;
mutex_lock(&cache->writeback_lock);
if (atomic_read(&cache->writeback_ctx.pending))
goto unlock;
if (pcache_is_stopping(pcache))
goto unlock;
kset_onmedia = (struct pcache_cache_kset_onmedia *)cache->wb_kset_onmedia_buf;
mutex_lock(&cache->dirty_tail_lock);
cache_pos_copy(&dirty_tail, &cache->dirty_tail);
mutex_unlock(&cache->dirty_tail_lock);
if (is_cache_clean(cache, &dirty_tail)) {
delay = PCACHE_CACHE_WRITEBACK_INTERVAL;
goto queue_work;
}
if (kset_onmedia->flags & PCACHE_KSET_FLAGS_LAST) {
last_kset_writeback(cache, kset_onmedia);
delay = 0;
goto queue_work;
Annotation
- Immediate include surface: `linux/bio.h`, `cache.h`, `backing_dev.h`, `cache_dev.h`, `dm_pcache.h`.
- Detected declarations: `function writeback_ctx_end`, `function writeback_end_req`, `function is_cache_clean`, `function cache_writeback_exit`, `function cache_writeback_init`, `function cache_key_writeback`, `function cache_wb_tree_writeback`, `function cache_kset_insert_tree`, `function last_kset_writeback`, `function cache_writeback_fn`.
- 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.