drivers/md/dm-vdo/packer.h
Source file repositories/reference/linux-study-clean/drivers/md/dm-vdo/packer.h
File Facts
- System
- Linux kernel
- Corpus path
drivers/md/dm-vdo/packer.h- Extension
.h- Size
- 4301 bytes
- Lines
- 123
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/list.hadmin-state.hconstants.hencodings.hstatistics.htypes.hwait-queue.h
Detected Declarations
struct compressed_block_headerstruct compressed_blockstruct packer_binstruct packer
Annotated Snippet
struct compressed_block_header {
/* Unsigned 32-bit major and minor versions, little-endian */
struct packed_version_number version;
/* List of unsigned 16-bit compressed block sizes, little-endian */
__le16 sizes[VDO_MAX_COMPRESSION_SLOTS];
} __packed;
enum {
VDO_COMPRESSED_BLOCK_DATA_SIZE = VDO_BLOCK_SIZE - sizeof(struct compressed_block_header),
/*
* A compressed block is only written if we can pack at least two fragments into it, so a
* fragment which fills the entire data portion of a compressed block is too big.
*/
VDO_MAX_COMPRESSED_FRAGMENT_SIZE = VDO_COMPRESSED_BLOCK_DATA_SIZE - 1,
};
/* * The compressed block overlay. */
struct compressed_block {
struct compressed_block_header header;
char data[VDO_COMPRESSED_BLOCK_DATA_SIZE];
} __packed;
/*
* Each packer_bin holds an incomplete batch of data_vios that only partially fill a compressed
* block. The bins are kept in a list sorted by the amount of unused space so the first bin with
* enough space to hold a newly-compressed data_vio can easily be found. When the bin fills up or
* is flushed, the first uncanceled data_vio in the bin is selected to be the agent for that bin.
* Upon entering the packer, each data_vio already has its compressed data in the first slot of the
* data_vio's compressed_block (overlaid on the data_vio's scratch_block). So the agent's fragment
* is already in place. The fragments for the other uncanceled data_vios in the bin are packed into
* the agent's compressed block. The agent then writes out the compressed block. If the write is
* successful, the agent shares its pbn lock which each of the other data_vios in its compressed
* block and sends each on its way. Finally the agent itself continues on the write path as before.
*
* There is one special bin which is used to hold data_vios which have been canceled and removed
* from their bin by the packer. These data_vios need to wait for the canceller to rendezvous with
* them and so they sit in this special bin.
*/
struct packer_bin {
/* List links for packer.packer_bins */
struct list_head list;
/* The number of items in the bin */
slot_number_t slots_used;
/* The number of compressed block bytes remaining in the current batch */
size_t free_space;
/* The current partial batch of data_vios, waiting for more */
struct data_vio *incoming[];
};
struct packer {
/* The ID of the packer's callback thread */
thread_id_t thread_id;
/* The number of bins */
block_count_t size;
/* A list of all packer_bins, kept sorted by free_space */
struct list_head bins;
/*
* A bin to hold data_vios which were canceled out of the packer and are waiting to
* rendezvous with the canceling data_vio.
*/
struct packer_bin *canceled_bin;
/* The current flush generation */
sequence_number_t flush_generation;
/* The administrative state of the packer */
struct admin_state state;
/* Statistics are only updated on the packer thread, but are accessed from other threads */
struct packer_statistics statistics;
};
int vdo_get_compressed_block_fragment(enum block_mapping_state mapping_state,
struct compressed_block *block,
u16 *fragment_offset, u16 *fragment_size);
int __must_check vdo_make_packer(struct vdo *vdo, block_count_t bin_count,
struct packer **packer_ptr);
void vdo_free_packer(struct packer *packer);
struct packer_statistics __must_check vdo_get_packer_statistics(const struct packer *packer);
void vdo_attempt_packing(struct data_vio *data_vio);
void vdo_flush_packer(struct packer *packer);
void vdo_remove_lock_holder_from_packer(struct vdo_completion *completion);
Annotation
- Immediate include surface: `linux/list.h`, `admin-state.h`, `constants.h`, `encodings.h`, `statistics.h`, `types.h`, `wait-queue.h`.
- Detected declarations: `struct compressed_block_header`, `struct compressed_block`, `struct packer_bin`, `struct packer`.
- Atlas domain: Driver Families / drivers/md.
- Implementation status: source 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.