Commit 4b4a8d95 authored by Bruce Johnston's avatar Bruce Johnston Committed by Mikulas Patocka
Browse files

dm vdo: add geometry block initialization to encodings.c



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: default avatarBruce Johnston <bjohnsto@redhat.com>
Reviewed-by: default avatarMatthew Sakai <msakai@redhat.com>
Signed-off-by: default avatarMikulas Patocka <mpatocka@redhat.com>
parent 0be6c2b1
Loading
Loading
Loading
Loading
+69 −0
Original line number Diff line number Diff line
@@ -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;
}
+4 −0
Original line number Diff line number Diff line
@@ -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);

+26 −0
Original line number Diff line number Diff line
@@ -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)
{
+4 −0
Original line number Diff line number Diff line
@@ -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);