Add vdo_initialize_volume_geometry() to populate the geometry block,
computing the space required for the two main regions on disk.

Add uds_compute_index_size() to calculate the space required for the
UDS indexer from the UDS configuration.

Signed-off-by: Bruce Johnston <[email protected]>
---
 drivers/md/dm-vdo/encodings.c            | 69 ++++++++++++++++++++++++
 drivers/md/dm-vdo/encodings.h            |  4 ++
 drivers/md/dm-vdo/indexer/index-layout.c | 26 +++++++++
 drivers/md/dm-vdo/indexer/indexer.h      |  4 ++
 4 files changed, 103 insertions(+)

diff --git a/drivers/md/dm-vdo/encodings.c b/drivers/md/dm-vdo/encodings.c
index ec98c539701e..9961cb40f890 100644
--- a/drivers/md/dm-vdo/encodings.c
+++ b/drivers/md/dm-vdo/encodings.c
@@ -12,6 +12,7 @@
 #include "permassert.h"
 
 #include "constants.h"
+#include "indexer.h"
 #include "status-codes.h"
 #include "types.h"
 
@@ -1486,3 +1487,71 @@ int vdo_decode_super_block(u8 *buffer)
 
        return ((checksum != saved_checksum) ? VDO_CHECKSUM_MISMATCH : 
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.
+ *
+ * Return: VDO_SUCCESS or an error code.
+ */
+static int vdo_compute_index_blocks(const struct index_config *config,
+                                   block_count_t *index_blocks_ptr)
+{
+       int result;
+       u64 index_bytes;
+       struct uds_parameters uds_parameters = {
+               .memory_size = config->mem,
+               .sparse = config->sparse,
+       };
+
+       result = uds_compute_index_size(&uds_parameters, &index_bytes);
+       if (result != UDS_SUCCESS)
+               return vdo_log_error_strerror(result, "error computing index 
size");
+
+       *index_blocks_ptr = index_bytes / VDO_BLOCK_SIZE;
+       return VDO_SUCCESS;
+}
+
+/**
+ * vdo_initialize_volume_geometry() - Initialize the volume geometry so it can 
be written out.
+ * @nonce: The nonce to use to identify the vdo.
+ * @uuid: The uuid to use to identify the vdo.
+ * @index_config: The config used for structure initialization.
+ * @geometry: The volume geometry to initialize.
+ *
+ * Return: VDO_SUCCESS or an error code.
+ */
+int vdo_initialize_volume_geometry(nonce_t nonce, uuid_t *uuid,
+                                  const struct index_config *index_config,
+                                  struct volume_geometry *geometry)
+{
+       int result;
+       block_count_t index_blocks = 0;
+
+       result = vdo_compute_index_blocks(index_config, &index_blocks);
+       if (result != VDO_SUCCESS)
+               return result;
+
+       *geometry = (struct volume_geometry) {
+               /* This is for backwards compatibility. */
+               .unused = 0,
+               .nonce = nonce,
+               .bio_offset = 0,
+               .regions = {
+                       [VDO_INDEX_REGION] = {
+                               .id = VDO_INDEX_REGION,
+                               .start_block = 1,
+                       },
+                       [VDO_DATA_REGION] = {
+                               .id = VDO_DATA_REGION,
+                               .start_block = 1 + index_blocks,
+                       }
+               }
+       };
+
+       memcpy(&(geometry->uuid), uuid, sizeof(uuid_t));
+       memcpy(&geometry->index_config, index_config, sizeof(struct 
index_config));
+
+       return VDO_SUCCESS;
+}
diff --git a/drivers/md/dm-vdo/encodings.h b/drivers/md/dm-vdo/encodings.h
index 87b7d2f3b545..0bc5ae696a6a 100644
--- a/drivers/md/dm-vdo/encodings.h
+++ b/drivers/md/dm-vdo/encodings.h
@@ -803,6 +803,10 @@ vdo_get_index_region_size(struct volume_geometry geometry)
                vdo_get_index_region_start(geometry);
 }
 
+int vdo_initialize_volume_geometry(nonce_t nonce, uuid_t *uuid,
+                                  const struct index_config *index_config,
+                                  struct volume_geometry *geometry);
+
 int __must_check vdo_parse_geometry_block(unsigned char *block,
                                          struct volume_geometry *geometry);
 
diff --git a/drivers/md/dm-vdo/indexer/index-layout.c 
b/drivers/md/dm-vdo/indexer/index-layout.c
index 798badcf80ea..74b7774b4be4 100644
--- a/drivers/md/dm-vdo/indexer/index-layout.c
+++ b/drivers/md/dm-vdo/indexer/index-layout.c
@@ -249,6 +249,32 @@ static int __must_check compute_sizes(const struct 
uds_configuration *config,
        return UDS_SUCCESS;
 }
 
+int uds_compute_index_size(const struct uds_parameters *parameters, u64 
*index_size)
+{
+       int result;
+       struct uds_configuration *index_config;
+       struct save_layout_sizes sizes;
+
+       if (index_size == NULL) {
+               vdo_log_error("Missing output size pointer");
+               return -EINVAL;
+       }
+
+       result = uds_make_configuration(parameters, &index_config);
+       if (result != UDS_SUCCESS) {
+               vdo_log_error_strerror(result, "cannot compute index size");
+               return result;
+       }
+
+       result = compute_sizes(index_config, &sizes);
+       uds_free_configuration(index_config);
+       if (result != UDS_SUCCESS)
+               return result;
+
+       *index_size = sizes.total_size;
+       return UDS_SUCCESS;
+}
+
 /* Create unique data using the current time and a pseudorandom number. */
 static void create_unique_nonce_data(u8 *buffer)
 {
diff --git a/drivers/md/dm-vdo/indexer/indexer.h 
b/drivers/md/dm-vdo/indexer/indexer.h
index 7c1fc4577f5b..d765f24328eb 100644
--- a/drivers/md/dm-vdo/indexer/indexer.h
+++ b/drivers/md/dm-vdo/indexer/indexer.h
@@ -282,6 +282,10 @@ struct uds_request {
                     );
 };
 
+/* Compute the number of bytes needed to store an index. */
+int __must_check uds_compute_index_size(const struct uds_parameters 
*parameters,
+                                       u64 *index_size);
+
 /* A session is required for most index operations. */
 int __must_check uds_create_index_session(struct uds_index_session **session);
 
-- 
2.52.0


Reply via email to