drivers/md/dm-io.c
Source file repositories/reference/linux-study-clean/drivers/md/dm-io.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/md/dm-io.c- Extension
.c- Size
- 13031 bytes
- Lines
- 541
- Domain
- Driver Families
- Bucket
- drivers/md
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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
dm-core.hlinux/device-mapper.hlinux/bio.hlinux/completion.hlinux/mempool.hlinux/module.hlinux/sched.hlinux/slab.hlinux/dm-io.h
Detected Declarations
struct dm_io_clientstruct iostruct dpagesstruct sync_iofunction dm_io_client_destroyfunction store_io_and_region_in_biofunction retrieve_io_and_region_from_biofunction complete_iofunction dec_countfunction endiofunction list_get_pagefunction list_next_pagefunction list_dp_initfunction bio_get_pagefunction bio_next_pagefunction bio_dp_initfunction vm_get_pagefunction vm_next_pagefunction vm_dp_initfunction km_get_pagefunction km_next_pagefunction km_dp_initfunction do_regionfunction dispatch_iofunction async_iofunction sync_io_completefunction sync_iofunction dp_initfunction dm_iofunction dm_io_initfunction dm_io_exitexport dm_io_client_createexport dm_io_client_destroyexport dm_io
Annotated Snippet
struct dm_io_client {
mempool_t pool;
struct bio_set bios;
};
/*
* Aligning 'struct io' reduces the number of bits required to store
* its address. Refer to store_io_and_region_in_bio() below.
*/
struct io {
unsigned long error_bits;
atomic_t count;
struct dm_io_client *client;
io_notify_fn callback;
void *context;
void *vma_invalidate_address;
unsigned long vma_invalidate_size;
} __aligned(DM_IO_MAX_REGIONS);
static struct kmem_cache *_dm_io_cache;
/*
* Create a client with mempool and bioset.
*/
struct dm_io_client *dm_io_client_create(void)
{
struct dm_io_client *client;
unsigned int min_ios = dm_get_reserved_bio_based_ios();
int ret;
client = kzalloc_obj(*client);
if (!client)
return ERR_PTR(-ENOMEM);
ret = mempool_init_slab_pool(&client->pool, min_ios, _dm_io_cache);
if (ret)
goto bad;
ret = bioset_init(&client->bios, min_ios, 0, BIOSET_NEED_BVECS);
if (ret)
goto bad;
return client;
bad:
mempool_exit(&client->pool);
kfree(client);
return ERR_PTR(ret);
}
EXPORT_SYMBOL(dm_io_client_create);
void dm_io_client_destroy(struct dm_io_client *client)
{
mempool_exit(&client->pool);
bioset_exit(&client->bios);
kfree(client);
}
EXPORT_SYMBOL(dm_io_client_destroy);
/*
*-------------------------------------------------------------------
* We need to keep track of which region a bio is doing io for.
* To avoid a memory allocation to store just 5 or 6 bits, we
* ensure the 'struct io' pointer is aligned so enough low bits are
* always zero and then combine it with the region number directly in
* bi_private.
*-------------------------------------------------------------------
*/
static void store_io_and_region_in_bio(struct bio *bio, struct io *io,
unsigned int region)
{
if (unlikely(!IS_ALIGNED((unsigned long)io, DM_IO_MAX_REGIONS))) {
DMCRIT("Unaligned struct io pointer %p", io);
BUG();
}
bio->bi_private = (void *)((unsigned long)io | region);
}
static void retrieve_io_and_region_from_bio(struct bio *bio, struct io **io,
unsigned int *region)
{
unsigned long val = (unsigned long)bio->bi_private;
*io = (void *)(val & -(unsigned long)DM_IO_MAX_REGIONS);
*region = val & (DM_IO_MAX_REGIONS - 1);
}
/*
*--------------------------------------------------------------
Annotation
- Immediate include surface: `dm-core.h`, `linux/device-mapper.h`, `linux/bio.h`, `linux/completion.h`, `linux/mempool.h`, `linux/module.h`, `linux/sched.h`, `linux/slab.h`.
- Detected declarations: `struct dm_io_client`, `struct io`, `struct dpages`, `struct sync_io`, `function dm_io_client_destroy`, `function store_io_and_region_in_bio`, `function retrieve_io_and_region_from_bio`, `function complete_io`, `function dec_count`, `function endio`.
- Atlas domain: Driver Families / drivers/md.
- Implementation status: integration 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.