drivers/md/dm-clone-metadata.c
Source file repositories/reference/linux-study-clean/drivers/md/dm-clone-metadata.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/md/dm-clone-metadata.c- Extension
.c- Size
- 24384 bytes
- Lines
- 1021
- 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
linux/mm.hlinux/err.hlinux/slab.hlinux/rwsem.hlinux/bitops.hlinux/bitmap.hlinux/device-mapper.hpersistent-data/dm-bitset.hpersistent-data/dm-space-map.hpersistent-data/dm-block-manager.hpersistent-data/dm-transaction-manager.hdm-clone-metadata.h
Detected Declarations
struct superblock_diskstruct dirty_mapstruct dm_clone_metadatafunction sb_prepare_for_writefunction sb_checkfunction __superblock_all_zeroesfunction superblock_read_lockfunction superblock_write_lock_zerofunction __copy_sm_rootfunction __prepare_superblockfunction __open_metadatafunction __format_metadatafunction __open_or_format_metadatafunction __create_persistent_data_structuresfunction __destroy_persistent_data_structuresfunction __dirty_map_initfunction __dirty_map_exitfunction dirty_map_initfunction dirty_map_exitfunction __load_bitset_in_corefunction dm_clone_metadata_closefunction dm_clone_is_hydration_donefunction dm_clone_is_region_hydratedfunction dm_clone_is_range_hydratedfunction dm_clone_nr_of_hydrated_regionsfunction dm_clone_find_next_unhydrated_regionfunction __update_metadata_wordfunction __metadata_commitfunction __flush_dmapfunction dm_clone_metadata_pre_commitfunction dm_clone_metadata_commitfunction dm_clone_set_region_hydratedfunction dm_clone_cond_set_rangefunction dm_clone_set_region_hydratedfunction dm_clone_changed_this_transactionfunction dm_clone_metadata_abortfunction dm_clone_metadata_set_read_onlyfunction dm_clone_metadata_set_read_writefunction dm_clone_get_free_metadata_block_countfunction dm_clone_get_metadata_dev_size
Annotated Snippet
struct superblock_disk {
__le32 csum;
__le32 flags;
__le64 blocknr;
__u8 uuid[UUID_LEN];
__le64 magic;
__le32 version;
__u8 metadata_space_map_root[SPACE_MAP_ROOT_SIZE];
__le64 region_size;
__le64 target_size;
__le64 bitset_root;
} __packed;
/*
* Region and Dirty bitmaps.
*
* dm-clone logically splits the source and destination devices in regions of
* fixed size. The destination device's regions are gradually hydrated, i.e.,
* we copy (clone) the source's regions to the destination device. Eventually,
* all regions will get hydrated and all I/O will be served from the
* destination device.
*
* We maintain an on-disk bitmap which tracks the state of each of the
* destination device's regions, i.e., whether they are hydrated or not.
*
* To save constantly doing look ups on disk we keep an in core copy of the
* on-disk bitmap, the region_map.
*
* In order to track which regions are hydrated during a metadata transaction,
* we use a second set of bitmaps, the dmap (dirty bitmap), which includes two
* bitmaps, namely dirty_regions and dirty_words. The dirty_regions bitmap
* tracks the regions that got hydrated during the current metadata
* transaction. The dirty_words bitmap tracks the dirty words, i.e. longs, of
* the dirty_regions bitmap.
*
* This allows us to precisely track the regions that were hydrated during the
* current metadata transaction and update the metadata accordingly, when we
* commit the current transaction. This is important because dm-clone should
* only commit the metadata of regions that were properly flushed to the
* destination device beforehand. Otherwise, in case of a crash, we could end
* up with a corrupted dm-clone device.
*
* When a region finishes hydrating dm-clone calls
* dm_clone_set_region_hydrated(), or for discard requests
* dm_clone_cond_set_range(), which sets the corresponding bits in region_map
* and dmap.
*
* During a metadata commit we scan dmap->dirty_words and dmap->dirty_regions
* and update the on-disk metadata accordingly. Thus, we don't have to flush to
* disk the whole region_map. We can just flush the dirty region_map bits.
*
* We use the helper dmap->dirty_words bitmap, which is smaller than the
* original region_map, to reduce the amount of memory accesses during a
* metadata commit. Moreover, as dm-bitset also accesses the on-disk bitmap in
* 64-bit word granularity, the dirty_words bitmap helps us avoid useless disk
* accesses.
*
* We could update directly the on-disk bitmap, when dm-clone calls either
* dm_clone_set_region_hydrated() or dm_clone_cond_set_range(), buts this
* inserts significant metadata I/O overhead in dm-clone's I/O path. Also, as
* these two functions don't block, we can call them in interrupt context,
* e.g., in a hooked overwrite bio's completion routine, and further reduce the
* I/O completion latency.
*
* We maintain two dirty bitmap sets. During a metadata commit we atomically
* swap the currently used dmap with the unused one. This allows the metadata
* update functions to run concurrently with an ongoing commit.
*/
struct dirty_map {
unsigned long *dirty_words;
unsigned long *dirty_regions;
unsigned int changed;
};
struct dm_clone_metadata {
/* The metadata block device */
struct block_device *bdev;
sector_t target_size;
sector_t region_size;
unsigned long nr_regions;
unsigned long nr_words;
/* Spinlock protecting the region and dirty bitmaps. */
spinlock_t bitmap_lock;
struct dirty_map dmap[2];
Annotation
- Immediate include surface: `linux/mm.h`, `linux/err.h`, `linux/slab.h`, `linux/rwsem.h`, `linux/bitops.h`, `linux/bitmap.h`, `linux/device-mapper.h`, `persistent-data/dm-bitset.h`.
- Detected declarations: `struct superblock_disk`, `struct dirty_map`, `struct dm_clone_metadata`, `function sb_prepare_for_write`, `function sb_check`, `function __superblock_all_zeroes`, `function superblock_read_lock`, `function superblock_write_lock_zero`, `function __copy_sm_root`, `function __prepare_superblock`.
- 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.