drivers/md/bcache/request.c
Source file repositories/reference/linux-study-clean/drivers/md/bcache/request.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/md/bcache/request.c- Extension
.c- Size
- 34796 bytes
- Lines
- 1347
- 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.hrequest.hwriteback.hlinux/module.hlinux/hash.hlinux/random.hlinux/backing-dev.htrace/events/bcache.h
Detected Declarations
struct searchfunction cache_modefunction verifyfunction bio_csumfunction bio_for_each_segmentfunction CLOSURE_CALLBACKfunction bch_keylist_reallocfunction bch_data_invalidatefunction CLOSURE_CALLBACKfunction bch_data_insert_endiofunction CLOSURE_CALLBACKfunction bch_get_congestedfunction add_sequentialfunction check_should_bypassfunction bch_cache_read_endiofunction cache_lookup_fnfunction CLOSURE_CALLBACKfunction devicefunction request_endiofunction backing_request_endiofunction cached_dev_writefunction bio_completefunction do_bio_hookfunction CLOSURE_CALLBACKfunction CLOSURE_CALLBACKfunction CLOSURE_CALLBACKfunction CLOSURE_CALLBACKfunction datafunction CLOSURE_CALLBACKfunction CLOSURE_CALLBACKfunction CLOSURE_CALLBACKfunction cached_dev_cache_missfunction cached_dev_readfunction CLOSURE_CALLBACKfunction cached_dev_writefunction CLOSURE_CALLBACKfunction detached_dev_end_iofunction detached_dev_do_requestfunction quit_max_writeback_ratefunction devicesfunction cached_dev_submit_biofunction cached_dev_ioctlfunction bch_cached_dev_request_initfunction flash_dev_cache_missfunction CLOSURE_CALLBACKfunction flash_dev_submit_biofunction flash_dev_ioctlfunction bch_flash_dev_request_init
Annotated Snippet
struct search {
/* Stack frame for bio_complete */
struct closure cl;
struct bbio bio;
struct bio *orig_bio;
struct bio *cache_miss;
struct bcache_device *d;
unsigned int insert_bio_sectors;
unsigned int recoverable:1;
unsigned int write:1;
unsigned int read_dirty_data:1;
unsigned int cache_missed:1;
struct block_device *orig_bdev;
unsigned long start_time;
struct btree_op op;
struct data_insert_op iop;
};
static void bch_cache_read_endio(struct bio *bio)
{
struct bbio *b = container_of(bio, struct bbio, bio);
struct closure *cl = bio->bi_private;
struct search *s = container_of(cl, struct search, cl);
/*
* If the bucket was reused while our bio was in flight, we might have
* read the wrong data. Set s->error but not error so it doesn't get
* counted against the cache device, but we'll still reread the data
* from the backing device.
*/
if (bio->bi_status)
s->iop.status = bio->bi_status;
else if (!KEY_DIRTY(&b->key) &&
ptr_stale(s->iop.c, &b->key, 0)) {
atomic_long_inc(&s->iop.c->cache_read_races);
s->iop.status = BLK_STS_IOERR;
}
bch_bbio_endio(s->iop.c, bio, bio->bi_status, "reading from cache");
}
/*
* Read from a single key, handling the initial cache miss if the key starts in
* the middle of the bio
*/
static int cache_lookup_fn(struct btree_op *op, struct btree *b, struct bkey *k)
{
struct search *s = container_of(op, struct search, op);
struct bio *n, *bio = &s->bio.bio;
struct bkey *bio_key;
unsigned int ptr;
if (bkey_cmp(k, &KEY(s->iop.inode, bio->bi_iter.bi_sector, 0)) <= 0)
return MAP_CONTINUE;
if (KEY_INODE(k) != s->iop.inode ||
KEY_START(k) > bio->bi_iter.bi_sector) {
unsigned int bio_sectors = bio_sectors(bio);
unsigned int sectors = KEY_INODE(k) == s->iop.inode
? min_t(uint64_t, INT_MAX,
KEY_START(k) - bio->bi_iter.bi_sector)
: INT_MAX;
int ret = s->d->cache_miss(b, s, bio, sectors);
if (ret != MAP_CONTINUE)
return ret;
/* if this was a complete miss we shouldn't get here */
BUG_ON(bio_sectors <= sectors);
}
if (!KEY_SIZE(k))
return MAP_CONTINUE;
/* XXX: figure out best pointer - for multiple cache devices */
ptr = 0;
PTR_BUCKET(b->c, k, ptr)->prio = INITIAL_PRIO;
if (KEY_DIRTY(k))
s->read_dirty_data = true;
n = bio_next_split(bio, min_t(uint64_t, INT_MAX,
KEY_OFFSET(k) - bio->bi_iter.bi_sector),
GFP_NOIO, &s->d->bio_split);
Annotation
- Immediate include surface: `bcache.h`, `btree.h`, `debug.h`, `request.h`, `writeback.h`, `linux/module.h`, `linux/hash.h`, `linux/random.h`.
- Detected declarations: `struct search`, `function cache_mode`, `function verify`, `function bio_csum`, `function bio_for_each_segment`, `function CLOSURE_CALLBACK`, `function bch_keylist_realloc`, `function bch_data_invalidate`, `function CLOSURE_CALLBACK`, `function bch_data_insert_endio`.
- 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.