drivers/md/dm-pcache/cache_req.c
Source file repositories/reference/linux-study-clean/drivers/md/dm-pcache/cache_req.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/md/dm-pcache/cache_req.c- Extension
.c- Size
- 26699 bytes
- Lines
- 837
- 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
cache.hbacking_dev.hcache_dev.hdm_pcache.h
Detected Declarations
function cache_data_head_initfunction cache_data_allocfunction cache_copy_from_req_biofunction cache_copy_to_req_biofunction emptyfunction submit_cache_miss_reqfunction cache_miss_req_freefunction cache_miss_req_initfunction nodefunction nodefunction read_overlap_containfunction read_overlap_containedfunction read_overlap_headfunction read_walk_finallyfunction list_for_each_entry_safefunction processedfunction treefunction list_for_each_entry_safefunction list_for_each_entry_safefunction cache_writefunction pcache_cache_flushfunction pcache_cache_handle_req
Annotated Snippet
if (cache_key_empty(key)) {
/* Check if the backing request was successful. */
if (read_ret) {
cache_key_delete(key);
goto unlock;
}
/* Allocate cache space for the key and copy data from the backing_dev. */
ret = cache_data_alloc(cache, key);
if (ret) {
cache_key_delete(key);
goto unlock;
}
ret = cache_copy_from_req_bio(cache, key, pcache_req, backing_req->req.bio_off);
if (ret) {
cache_seg_put(key->cache_pos.cache_seg);
cache_key_delete(key);
goto unlock;
}
key->flags &= ~PCACHE_CACHE_KEY_FLAGS_EMPTY;
key->flags |= PCACHE_CACHE_KEY_FLAGS_CLEAN;
/* Append the key to the cache. */
ret = cache_key_append(cache, key, false);
if (ret) {
cache_seg_put(key->cache_pos.cache_seg);
cache_key_delete(key);
goto unlock;
}
}
unlock:
spin_unlock(&cache_subtree->tree_lock);
cache_key_put(key);
}
}
/**
* submit_cache_miss_req - Submit a backing request when cache data is missing
* @cache: The cache context that manages cache operations
* @backing_req: The cache request containing information about the read request
*
* This function is used to handle cases where a cache read request cannot locate
* the required data in the cache. When such a miss occurs during `cache_subtree_walk`,
* it triggers a backing read request to fetch data from the backing storage.
*
* If `pcache_req->priv_data` is set, it points to a `pcache_cache_key`, representing
* a new cache key to be inserted into the cache. The function calls `cache_key_insert`
* to attempt adding the key. On insertion failure, it releases the key reference and
* clears `priv_data` to avoid further processing.
*/
static void submit_cache_miss_req(struct pcache_cache *cache, struct pcache_backing_dev_req *backing_req)
{
if (backing_req->priv_data) {
struct pcache_cache_key *key;
/* Attempt to insert the key into the cache if priv_data is set */
key = (struct pcache_cache_key *)backing_req->priv_data;
cache_key_insert(&cache->req_key_tree, key, true);
}
backing_dev_req_submit(backing_req, false);
}
static void cache_miss_req_free(struct pcache_backing_dev_req *backing_req)
{
struct pcache_cache_key *key;
if (backing_req->priv_data) {
key = backing_req->priv_data;
backing_req->priv_data = NULL;
cache_key_put(key); /* for ->priv_data */
cache_key_put(key); /* for init ref in alloc */
}
backing_dev_req_end(backing_req);
}
static struct pcache_backing_dev_req *cache_miss_req_alloc(struct pcache_cache *cache,
struct pcache_request *parent,
gfp_t gfp_mask)
{
struct pcache_backing_dev *backing_dev = cache->backing_dev;
struct pcache_backing_dev_req *backing_req;
struct pcache_cache_key *key = NULL;
struct pcache_backing_dev_req_opts req_opts = { 0 };
req_opts.type = BACKING_DEV_REQ_TYPE_REQ;
req_opts.gfp_mask = gfp_mask;
req_opts.req.upper_req = parent;
Annotation
- Immediate include surface: `cache.h`, `backing_dev.h`, `cache_dev.h`, `dm_pcache.h`.
- Detected declarations: `function cache_data_head_init`, `function cache_data_alloc`, `function cache_copy_from_req_bio`, `function cache_copy_to_req_bio`, `function empty`, `function submit_cache_miss_req`, `function cache_miss_req_free`, `function cache_miss_req_init`, `function node`, `function node`.
- 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.