#include "permassert.h"
#include "constants.h"
+#include "indexer.h"
#include "status-codes.h"
#include "types.h"
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;
+}
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)
{