summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Johnston <bjohnsto@redhat.com>2026-03-24 21:06:45 +0300
committerMikulas Patocka <mpatocka@redhat.com>2026-03-26 20:17:42 +0300
commite073bb098ae28a909ece08ec05a6c59dbd282b12 (patch)
tree02830227cfdd401caa08326294485c95e1ec11a2
parent4b4a8d9560d987f4df17b7248ab1c8146138d0f5 (diff)
downloadlinux-e073bb098ae28a909ece08ec05a6c59dbd282b12.tar.xz
dm vdo: add super block initialization to encodings.c
Add vdo_initialize_component_states() to populate the super block, computing the space required for the main VDO components on disk. Those include the slab depot, block map, and recovery journal. Signed-off-by: Bruce Johnston <bjohnsto@redhat.com> Reviewed-by: Matthew Sakai <msakai@redhat.com> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
-rw-r--r--drivers/md/dm-vdo/constants.h3
-rw-r--r--drivers/md/dm-vdo/encodings.c82
-rw-r--r--drivers/md/dm-vdo/encodings.h5
3 files changed, 90 insertions, 0 deletions
diff --git a/drivers/md/dm-vdo/constants.h b/drivers/md/dm-vdo/constants.h
index 2a8b03779f87..cc7bc3571ba1 100644
--- a/drivers/md/dm-vdo/constants.h
+++ b/drivers/md/dm-vdo/constants.h
@@ -44,6 +44,9 @@ enum {
/* The default size of each slab journal, in blocks */
DEFAULT_VDO_SLAB_JOURNAL_SIZE = 224,
+ /* The recovery journal starting sequence number set at format time */
+ RECOVERY_JOURNAL_STARTING_SEQUENCE_NUMBER = 1,
+
/*
* The initial size of lbn_operations and pbn_operations, which is based upon the expected
* maximum number of outstanding VIOs. This value was chosen to make it highly unlikely
diff --git a/drivers/md/dm-vdo/encodings.c b/drivers/md/dm-vdo/encodings.c
index 9961cb40f890..441c9aee1749 100644
--- a/drivers/md/dm-vdo/encodings.c
+++ b/drivers/md/dm-vdo/encodings.c
@@ -1489,6 +1489,88 @@ int vdo_decode_super_block(u8 *buffer)
}
/**
+ * vdo_initialize_component_states() - Initialize the components so they can be written out.
+ * @vdo_config: The config used for component state initialization.
+ * @geometry: The volume geometry used to calculate the data region offset.
+ * @nonce: The nonce to use to identify the vdo.
+ * @states: The component states to initialize.
+ *
+ * Return: VDO_SUCCESS or an error code.
+ */
+int vdo_initialize_component_states(const struct vdo_config *vdo_config,
+ const struct volume_geometry *geometry,
+ nonce_t nonce,
+ struct vdo_component_states *states)
+{
+ int result;
+ struct slab_config slab_config;
+ struct partition *partition;
+
+ states->vdo.config = *vdo_config;
+ states->vdo.nonce = nonce;
+ states->volume_version = VDO_VOLUME_VERSION_67_0;
+
+ states->recovery_journal = (struct recovery_journal_state_7_0) {
+ .journal_start = RECOVERY_JOURNAL_STARTING_SEQUENCE_NUMBER,
+ .logical_blocks_used = 0,
+ .block_map_data_blocks = 0,
+ };
+
+ /*
+ * The layout starts 1 block past the beginning of the data region, as the
+ * data region contains the super block but the layout does not.
+ */
+ result = vdo_initialize_layout(vdo_config->physical_blocks,
+ vdo_get_data_region_start(*geometry) + 1,
+ DEFAULT_VDO_BLOCK_MAP_TREE_ROOT_COUNT,
+ vdo_config->recovery_journal_size,
+ VDO_SLAB_SUMMARY_BLOCKS,
+ &states->layout);
+ if (result != VDO_SUCCESS)
+ return result;
+
+ result = vdo_configure_slab(vdo_config->slab_size,
+ vdo_config->slab_journal_blocks,
+ &slab_config);
+ if (result != VDO_SUCCESS) {
+ vdo_uninitialize_layout(&states->layout);
+ return result;
+ }
+
+ result = vdo_get_partition(&states->layout, VDO_SLAB_DEPOT_PARTITION,
+ &partition);
+ if (result != VDO_SUCCESS) {
+ vdo_uninitialize_layout(&states->layout);
+ return result;
+ }
+
+ result = vdo_configure_slab_depot(partition, slab_config, 0,
+ &states->slab_depot);
+ if (result != VDO_SUCCESS) {
+ vdo_uninitialize_layout(&states->layout);
+ return result;
+ }
+
+ result = vdo_get_partition(&states->layout, VDO_BLOCK_MAP_PARTITION,
+ &partition);
+ if (result != VDO_SUCCESS) {
+ vdo_uninitialize_layout(&states->layout);
+ return result;
+ }
+
+ states->block_map = (struct block_map_state_2_0) {
+ .flat_page_origin = VDO_BLOCK_MAP_FLAT_PAGE_ORIGIN,
+ .flat_page_count = 0,
+ .root_origin = partition->offset,
+ .root_count = DEFAULT_VDO_BLOCK_MAP_TREE_ROOT_COUNT,
+ };
+
+ states->vdo.state = VDO_NEW;
+
+ return VDO_SUCCESS;
+}
+
+/**
* vdo_compute_index_blocks() - Compute the number of blocks that the indexer will use.
* @config: The index config from which the blocks are calculated.
* @index_blocks_ptr: The number of blocks the index will use.
diff --git a/drivers/md/dm-vdo/encodings.h b/drivers/md/dm-vdo/encodings.h
index 0bc5ae696a6a..3cfbe4771a1c 100644
--- a/drivers/md/dm-vdo/encodings.h
+++ b/drivers/md/dm-vdo/encodings.h
@@ -1268,6 +1268,11 @@ int __must_check vdo_validate_component_states(struct vdo_component_states *stat
void vdo_encode_super_block(u8 *buffer, struct vdo_component_states *states);
int __must_check vdo_decode_super_block(u8 *buffer);
+int vdo_initialize_component_states(const struct vdo_config *vdo_config,
+ const struct volume_geometry *geometry,
+ nonce_t nonce,
+ struct vdo_component_states *states);
+
/* We start with 0L and postcondition with ~0L to match our historical usage in userspace. */
static inline u32 vdo_crc32(const void *buf, unsigned long len)
{