drivers/md/persistent-data/dm-block-manager.c
Source file repositories/reference/linux-study-clean/drivers/md/persistent-data/dm-block-manager.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/md/persistent-data/dm-block-manager.c- Extension
.c- Size
- 14260 bytes
- Lines
- 663
- 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-block-manager.hdm-persistent-data-internal.hlinux/dm-bufio.hlinux/crc32c.hlinux/module.hlinux/slab.hlinux/rwsem.hlinux/device-mapper.hlinux/stacktrace.hlinux/sched/task.h
Detected Declarations
struct stack_storestruct block_lockstruct waiterstruct buffer_auxstruct dm_block_managerfunction __find_holderfunction __add_holderfunction __del_holderfunction __check_holderfunction __waitfunction __wake_waiterfunction __wake_manyfunction bl_initfunction __available_for_readfunction bl_down_readfunction bl_down_read_nonblockfunction bl_up_readfunction bl_down_writefunction bl_up_writefunction report_recursive_bugfunction dm_block_locationfunction dm_block_manager_alloc_callbackfunction dm_block_manager_write_callbackfunction dm_block_manager_destroyfunction dm_block_manager_resetfunction dm_bm_block_sizefunction dm_bm_nr_blocksfunction dm_bm_validate_bufferfunction dm_bm_read_lockfunction dm_bm_write_lockfunction dm_bm_read_try_lockfunction dm_bm_write_lock_zerofunction dm_bm_unlockfunction dm_bm_flushfunction dm_bm_prefetchfunction dm_bm_is_read_onlyfunction dm_bm_set_read_onlyfunction dm_bm_set_read_writefunction dm_bm_checksumexport dm_block_locationexport dm_block_dataexport dm_block_manager_createexport dm_block_manager_destroyexport dm_block_manager_resetexport dm_bm_block_sizeexport dm_bm_read_lockexport dm_bm_write_lockexport dm_bm_write_lock_zero
Annotated Snippet
struct stack_store {
unsigned int nr_entries;
unsigned long entries[MAX_STACK];
};
struct block_lock {
spinlock_t lock;
__s32 count;
struct list_head waiters;
struct task_struct *holders[MAX_HOLDERS];
#ifdef CONFIG_DM_DEBUG_BLOCK_STACK_TRACING
struct stack_store traces[MAX_HOLDERS];
#endif
};
struct waiter {
struct list_head list;
struct task_struct *task;
int wants_write;
};
static unsigned int __find_holder(struct block_lock *lock,
struct task_struct *task)
{
unsigned int i;
for (i = 0; i < MAX_HOLDERS; i++)
if (lock->holders[i] == task)
break;
BUG_ON(i == MAX_HOLDERS);
return i;
}
/* call this *after* you increment lock->count */
static void __add_holder(struct block_lock *lock, struct task_struct *task)
{
unsigned int h = __find_holder(lock, NULL);
#ifdef CONFIG_DM_DEBUG_BLOCK_STACK_TRACING
struct stack_store *t;
#endif
get_task_struct(task);
lock->holders[h] = task;
#ifdef CONFIG_DM_DEBUG_BLOCK_STACK_TRACING
t = lock->traces + h;
t->nr_entries = stack_trace_save(t->entries, MAX_STACK, 2);
#endif
}
/* call this *before* you decrement lock->count */
static void __del_holder(struct block_lock *lock, struct task_struct *task)
{
unsigned int h = __find_holder(lock, task);
lock->holders[h] = NULL;
put_task_struct(task);
}
static int __check_holder(struct block_lock *lock)
{
unsigned int i;
for (i = 0; i < MAX_HOLDERS; i++) {
if (lock->holders[i] == current) {
DMERR("recursive lock detected in metadata");
#ifdef CONFIG_DM_DEBUG_BLOCK_STACK_TRACING
DMERR("previously held here:");
stack_trace_print(lock->traces[i].entries,
lock->traces[i].nr_entries, 4);
DMERR("subsequent acquisition attempted here:");
dump_stack();
#endif
return -EINVAL;
}
}
return 0;
}
static void __wait(struct waiter *w)
{
for (;;) {
set_current_state(TASK_UNINTERRUPTIBLE);
if (!w->task)
break;
Annotation
- Immediate include surface: `dm-block-manager.h`, `dm-persistent-data-internal.h`, `linux/dm-bufio.h`, `linux/crc32c.h`, `linux/module.h`, `linux/slab.h`, `linux/rwsem.h`, `linux/device-mapper.h`.
- Detected declarations: `struct stack_store`, `struct block_lock`, `struct waiter`, `struct buffer_aux`, `struct dm_block_manager`, `function __find_holder`, `function __add_holder`, `function __del_holder`, `function __check_holder`, `function __wait`.
- 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.