drivers/md/persistent-data/dm-array.c
Source file repositories/reference/linux-study-clean/drivers/md/persistent-data/dm-array.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/md/persistent-data/dm-array.c- Extension
.c- Size
- 24625 bytes
- Lines
- 1022
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
dm-array.hdm-space-map.hdm-transaction-manager.hlinux/export.hlinux/device-mapper.h
Detected Declarations
struct array_blockstruct resizestruct walk_infofunction headerfunction array_block_checkfunction on_entriesfunction inc_ablock_entriesfunction dec_ablock_entriesfunction calc_max_entriesfunction alloc_ablockfunction fill_ablockfunction trim_ablockfunction get_ablockfunction unlock_ablockfunction lookup_ablockfunction insert_ablockfunction __shadow_ablockfunction __reinsert_ablockfunction shadow_ablockfunction insert_new_ablockfunction insert_full_ablocksfunction drop_blocksfunction total_nr_blocks_neededfunction shrinkfunction grow_extend_tail_blockfunction grow_add_tail_blockfunction grow_needs_more_blocksfunction growfunction block_incfunction __block_decfunction block_decfunction block_equalfunction dm_array_info_initfunction dm_array_emptyfunction array_resizefunction dm_array_resizefunction populate_ablock_with_valuesfunction dm_array_newfunction dm_array_delfunction dm_array_get_valuefunction array_set_valuefunction dm_array_set_valuefunction walk_ablockfunction dm_array_walkfunction load_ablockfunction dm_array_cursor_beginfunction dm_array_cursor_endfunction dm_array_cursor_next
Annotated Snippet
struct array_block {
__le32 csum;
__le32 max_entries;
__le32 nr_entries;
__le32 value_size;
__le64 blocknr; /* Block this node is supposed to live in. */
} __packed;
/*----------------------------------------------------------------*/
/*
* Validator methods. As usual we calculate a checksum, and also write the
* block location into the header (paranoia about ssds remapping areas by
* mistake).
*/
#define CSUM_XOR 595846735
static void array_block_prepare_for_write(const struct dm_block_validator *v,
struct dm_block *b,
size_t size_of_block)
{
struct array_block *bh_le = dm_block_data(b);
bh_le->blocknr = cpu_to_le64(dm_block_location(b));
bh_le->csum = cpu_to_le32(dm_bm_checksum(&bh_le->max_entries,
size_of_block - sizeof(__le32),
CSUM_XOR));
}
static int array_block_check(const struct dm_block_validator *v,
struct dm_block *b,
size_t size_of_block)
{
struct array_block *bh_le = dm_block_data(b);
__le32 csum_disk;
if (dm_block_location(b) != le64_to_cpu(bh_le->blocknr)) {
DMERR_LIMIT("%s failed: blocknr %llu != wanted %llu", __func__,
(unsigned long long) le64_to_cpu(bh_le->blocknr),
(unsigned long long) dm_block_location(b));
return -ENOTBLK;
}
csum_disk = cpu_to_le32(dm_bm_checksum(&bh_le->max_entries,
size_of_block - sizeof(__le32),
CSUM_XOR));
if (csum_disk != bh_le->csum) {
DMERR_LIMIT("%s failed: csum %u != wanted %u", __func__,
(unsigned int) le32_to_cpu(csum_disk),
(unsigned int) le32_to_cpu(bh_le->csum));
return -EILSEQ;
}
return 0;
}
static const struct dm_block_validator array_validator = {
.name = "array",
.prepare_for_write = array_block_prepare_for_write,
.check = array_block_check
};
/*----------------------------------------------------------------*/
/*
* Functions for manipulating the array blocks.
*/
/*
* Returns a pointer to a value within an array block.
*
* index - The index into _this_ specific block.
*/
static void *element_at(struct dm_array_info *info, struct array_block *ab,
unsigned int index)
{
unsigned char *entry = (unsigned char *) (ab + 1);
entry += index * info->value_type.size;
return entry;
}
/*
* Utility function that calls one of the value_type methods on every value
* in an array block.
*/
static void on_entries(struct dm_array_info *info, struct array_block *ab,
void (*fn)(void *, const void *, unsigned int))
{
Annotation
- Immediate include surface: `dm-array.h`, `dm-space-map.h`, `dm-transaction-manager.h`, `linux/export.h`, `linux/device-mapper.h`.
- Detected declarations: `struct array_block`, `struct resize`, `struct walk_info`, `function header`, `function array_block_check`, `function on_entries`, `function inc_ablock_entries`, `function dec_ablock_entries`, `function calc_max_entries`, `function alloc_ablock`.
- Atlas domain: Driver Families / drivers/md.
- Implementation status: integration implementation candidate.
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.