linux/drivers/md/dm-vdo/encodings.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2023 Red Hat
 */

#include "encodings.h"

#include <linux/log2.h>

#include "logger.h"
#include "memory-alloc.h"
#include "permassert.h"

#include "constants.h"
#include "status-codes.h"
#include "types.h"

/** The maximum logical space is 4 petabytes, which is 1 terablock. */
static const block_count_t MAXIMUM_VDO_LOGICAL_BLOCKS =;

/** The maximum physical space is 256 terabytes, which is 64 gigablocks. */
static const block_count_t MAXIMUM_VDO_PHYSICAL_BLOCKS =;

struct geometry_block {} __packed;

static const struct header GEOMETRY_BLOCK_HEADER_5_0 =;

static const struct header GEOMETRY_BLOCK_HEADER_4_0 =;

const u8 VDO_GEOMETRY_MAGIC_NUMBER[VDO_GEOMETRY_MAGIC_NUMBER_SIZE + 1] =;

#define PAGE_HEADER_4_1_SIZE

static const struct version_number BLOCK_MAP_4_1 =;

const struct header VDO_BLOCK_MAP_HEADER_2_0 =;

const struct header VDO_RECOVERY_JOURNAL_HEADER_7_0 =;

const struct header VDO_SLAB_DEPOT_HEADER_2_0 =;

static const struct header VDO_LAYOUT_HEADER_3_0 =;

static const enum partition_id REQUIRED_PARTITIONS[] =;

/*
 * The current version for the data encoded in the super block. This must be changed any time there
 * is a change to encoding of the component data of any VDO component.
 */
static const struct version_number VDO_COMPONENT_DATA_41_0 =;

const struct version_number VDO_VOLUME_VERSION_67_0 =;

static const struct header SUPER_BLOCK_HEADER_12_0 =;

/**
 * validate_version() - Check whether a version matches an expected version.
 * @expected_version: The expected version.
 * @actual_version: The version being validated.
 * @component_name: The name of the component or the calling function (for error logging).
 *
 * Logs an error describing a mismatch.
 *
 * Return: VDO_SUCCESS             if the versions are the same,
 *         VDO_UNSUPPORTED_VERSION if the versions don't match.
 */
static int __must_check validate_version(struct version_number expected_version,
					 struct version_number actual_version,
					 const char *component_name)
{}

/**
 * vdo_validate_header() - Check whether a header matches expectations.
 * @expected_header: The expected header.
 * @actual_header: The header being validated.
 * @exact_size: If true, the size fields of the two headers must be the same, otherwise it is
 *              required that actual_header.size >= expected_header.size.
 * @name: The name of the component or the calling function (for error logging).
 *
 * Logs an error describing the first mismatch found.
 *
 * Return: VDO_SUCCESS             if the header meets expectations,
 *         VDO_INCORRECT_COMPONENT if the component ids don't match,
 *         VDO_UNSUPPORTED_VERSION if the versions or sizes don't match.
 */
int vdo_validate_header(const struct header *expected_header,
			const struct header *actual_header, bool exact_size,
			const char *name)
{}

static void encode_version_number(u8 *buffer, size_t *offset,
				  struct version_number version)
{}

void vdo_encode_header(u8 *buffer, size_t *offset, const struct header *header)
{}

static void decode_version_number(u8 *buffer, size_t *offset,
				  struct version_number *version)
{}

void vdo_decode_header(u8 *buffer, size_t *offset, struct header *header)
{}

/**
 * decode_volume_geometry() - Decode the on-disk representation of a volume geometry from a buffer.
 * @buffer: A buffer to decode from.
 * @offset: The offset in the buffer at which to decode.
 * @geometry: The structure to receive the decoded fields.
 * @version: The geometry block version to decode.
 */
static void decode_volume_geometry(u8 *buffer, size_t *offset,
				   struct volume_geometry *geometry, u32 version)
{}

/**
 * vdo_parse_geometry_block() - Decode and validate an encoded geometry block.
 * @block: The encoded geometry block.
 * @geometry: The structure to receive the decoded fields.
 */
int __must_check vdo_parse_geometry_block(u8 *block, struct volume_geometry *geometry)
{}

struct block_map_page *vdo_format_block_map_page(void *buffer, nonce_t nonce,
						 physical_block_number_t pbn,
						 bool initialized)
{}

enum block_map_page_validity vdo_validate_block_map_page(struct block_map_page *page,
							 nonce_t nonce,
							 physical_block_number_t pbn)
{}

static int decode_block_map_state_2_0(u8 *buffer, size_t *offset,
				      struct block_map_state_2_0 *state)
{}

static void encode_block_map_state_2_0(u8 *buffer, size_t *offset,
				       struct block_map_state_2_0 state)
{}

/**
 * vdo_compute_new_forest_pages() - Compute the number of pages which must be allocated at each
 *                                  level in order to grow the forest to a new number of entries.
 * @entries: The new number of entries the block map must address.
 *
 * Return: The total number of non-leaf pages required.
 */
block_count_t vdo_compute_new_forest_pages(root_count_t root_count,
					   struct boundary *old_sizes,
					   block_count_t entries,
					   struct boundary *new_sizes)
{}

/**
 * encode_recovery_journal_state_7_0() - Encode the state of a recovery journal.
 *
 * Return: VDO_SUCCESS or an error code.
 */
static void encode_recovery_journal_state_7_0(u8 *buffer, size_t *offset,
					      struct recovery_journal_state_7_0 state)
{}

/**
 * decode_recovery_journal_state_7_0() - Decode the state of a recovery journal saved in a buffer.
 * @buffer: The buffer containing the saved state.
 * @state: A pointer to a recovery journal state to hold the result of a successful decode.
 *
 * Return: VDO_SUCCESS or an error code.
 */
static int __must_check decode_recovery_journal_state_7_0(u8 *buffer, size_t *offset,
							  struct recovery_journal_state_7_0 *state)
{}

/**
 * vdo_get_journal_operation_name() - Get the name of a journal operation.
 * @operation: The operation to name.
 *
 * Return: The name of the operation.
 */
const char *vdo_get_journal_operation_name(enum journal_operation operation)
{}

/**
 * encode_slab_depot_state_2_0() - Encode the state of a slab depot into a buffer.
 */
static void encode_slab_depot_state_2_0(u8 *buffer, size_t *offset,
					struct slab_depot_state_2_0 state)
{}

/**
 * decode_slab_depot_state_2_0() - Decode slab depot component state version 2.0 from a buffer.
 *
 * Return: VDO_SUCCESS or an error code.
 */
static int decode_slab_depot_state_2_0(u8 *buffer, size_t *offset,
				       struct slab_depot_state_2_0 *state)
{}

/**
 * vdo_configure_slab_depot() - Configure the slab depot.
 * @partition: The slab depot partition
 * @slab_config: The configuration of a single slab.
 * @zone_count: The number of zones the depot will use.
 * @state: The state structure to be configured.
 *
 * Configures the slab_depot for the specified storage capacity, finding the number of data blocks
 * that will fit and still leave room for the depot metadata, then return the saved state for that
 * configuration.
 *
 * Return: VDO_SUCCESS or an error code.
 */
int vdo_configure_slab_depot(const struct partition *partition,
			     struct slab_config slab_config, zone_count_t zone_count,
			     struct slab_depot_state_2_0 *state)
{}

/**
 * vdo_configure_slab() - Measure and initialize the configuration to use for each slab.
 * @slab_size: The number of blocks per slab.
 * @slab_journal_blocks: The number of blocks for the slab journal.
 * @slab_config: The slab configuration to initialize.
 *
 * Return: VDO_SUCCESS or an error code.
 */
int vdo_configure_slab(block_count_t slab_size, block_count_t slab_journal_blocks,
		       struct slab_config *slab_config)
{}

/**
 * vdo_decode_slab_journal_entry() - Decode a slab journal entry.
 * @block: The journal block holding the entry.
 * @entry_count: The number of the entry.
 *
 * Return: The decoded entry.
 */
struct slab_journal_entry vdo_decode_slab_journal_entry(struct packed_slab_journal_block *block,
							journal_entry_count_t entry_count)
{}

/**
 * allocate_partition() - Allocate a partition and add it to a layout.
 * @layout: The layout containing the partition.
 * @id: The id of the partition.
 * @offset: The offset into the layout at which the partition begins.
 * @size: The size of the partition in blocks.
 *
 * Return: VDO_SUCCESS or an error.
 */
static int allocate_partition(struct layout *layout, u8 id,
			      physical_block_number_t offset, block_count_t size)
{}

/**
 * make_partition() - Create a new partition from the beginning or end of the unused space in a
 *                    layout.
 * @layout: The layout.
 * @id: The id of the partition to make.
 * @size: The number of blocks to carve out; if 0, all remaining space will be used.
 * @beginning: True if the partition should start at the beginning of the unused space.
 *
 * Return: A success or error code, particularly VDO_NO_SPACE if there are fewer than size blocks
 *         remaining.
 */
static int __must_check make_partition(struct layout *layout, enum partition_id id,
				       block_count_t size, bool beginning)
{}

/**
 * vdo_initialize_layout() - Lay out the partitions of a vdo.
 * @size: The entire size of the vdo.
 * @origin: The start of the layout on the underlying storage in blocks.
 * @block_map_blocks: The size of the block map partition.
 * @journal_blocks: The size of the journal partition.
 * @summary_blocks: The size of the slab summary partition.
 * @layout: The layout to initialize.
 *
 * Return: VDO_SUCCESS or an error.
 */
int vdo_initialize_layout(block_count_t size, physical_block_number_t offset,
			  block_count_t block_map_blocks, block_count_t journal_blocks,
			  block_count_t summary_blocks, struct layout *layout)
{}

/**
 * vdo_uninitialize_layout() - Clean up a layout.
 * @layout: The layout to clean up.
 *
 * All partitions created by this layout become invalid pointers.
 */
void vdo_uninitialize_layout(struct layout *layout)
{}

/**
 * vdo_get_partition() - Get a partition by id.
 * @layout: The layout from which to get a partition.
 * @id: The id of the partition.
 * @partition_ptr: A pointer to hold the partition.
 *
 * Return: VDO_SUCCESS or an error.
 */
int vdo_get_partition(struct layout *layout, enum partition_id id,
		      struct partition **partition_ptr)
{}

/**
 * vdo_get_known_partition() - Get a partition by id from a validated layout.
 * @layout: The layout from which to get a partition.
 * @id: The id of the partition.
 *
 * Return: the partition
 */
struct partition *vdo_get_known_partition(struct layout *layout, enum partition_id id)
{}

static void encode_layout(u8 *buffer, size_t *offset, const struct layout *layout)
{}

static int decode_layout(u8 *buffer, size_t *offset, physical_block_number_t start,
			 block_count_t size, struct layout *layout)
{}

/**
 * pack_vdo_config() - Convert a vdo_config to its packed on-disk representation.
 * @config: The vdo config to convert.
 *
 * Return: The platform-independent representation of the config.
 */
static struct packed_vdo_config pack_vdo_config(struct vdo_config config)
{}

/**
 * pack_vdo_component() - Convert a vdo_component to its packed on-disk representation.
 * @component: The VDO component data to convert.
 *
 * Return: The platform-independent representation of the component.
 */
static struct packed_vdo_component_41_0 pack_vdo_component(const struct vdo_component component)
{}

static void encode_vdo_component(u8 *buffer, size_t *offset,
				 struct vdo_component component)
{}

/**
 * unpack_vdo_config() - Convert a packed_vdo_config to its native in-memory representation.
 * @config: The packed vdo config to convert.
 *
 * Return: The native in-memory representation of the vdo config.
 */
static struct vdo_config unpack_vdo_config(struct packed_vdo_config config)
{}

/**
 * unpack_vdo_component_41_0() - Convert a packed_vdo_component_41_0 to its native in-memory
 *				 representation.
 * @component: The packed vdo component data to convert.
 *
 * Return: The native in-memory representation of the component.
 */
static struct vdo_component unpack_vdo_component_41_0(struct packed_vdo_component_41_0 component)
{}

/**
 * decode_vdo_component() - Decode the component data for the vdo itself out of the super block.
 *
 * Return: VDO_SUCCESS or an error.
 */
static int decode_vdo_component(u8 *buffer, size_t *offset, struct vdo_component *component)
{}

/**
 * vdo_validate_config() - Validate constraints on a VDO config.
 * @config: The VDO config.
 * @physical_block_count: The minimum block count of the underlying storage.
 * @logical_block_count: The expected logical size of the VDO, or 0 if the logical size may be
 *			 unspecified.
 *
 * Return: A success or error code.
 */
int vdo_validate_config(const struct vdo_config *config,
			block_count_t physical_block_count,
			block_count_t logical_block_count)
{}

/**
 * vdo_destroy_component_states() - Clean up any allocations in a vdo_component_states.
 * @states: The component states to destroy.
 */
void vdo_destroy_component_states(struct vdo_component_states *states)
{}

/**
 * decode_components() - Decode the components now that we know the component data is a version we
 *                       understand.
 * @buffer: The buffer being decoded.
 * @offset: The offset to start decoding from.
 * @geometry: The vdo geometry
 * @states: An object to hold the successfully decoded state.
 *
 * Return: VDO_SUCCESS or an error.
 */
static int __must_check decode_components(u8 *buffer, size_t *offset,
					  struct volume_geometry *geometry,
					  struct vdo_component_states *states)
{}

/**
 * vdo_decode_component_states() - Decode the payload of a super block.
 * @buffer: The buffer containing the encoded super block contents.
 * @geometry: The vdo geometry
 * @states: A pointer to hold the decoded states.
 *
 * Return: VDO_SUCCESS or an error.
 */
int vdo_decode_component_states(u8 *buffer, struct volume_geometry *geometry,
				struct vdo_component_states *states)
{}

/**
 * vdo_validate_component_states() - Validate the decoded super block configuration.
 * @states: The state decoded from the super block.
 * @geometry_nonce: The nonce from the geometry block.
 * @physical_size: The minimum block count of the underlying storage.
 * @logical_size: The expected logical size of the VDO, or 0 if the logical size may be
 *                unspecified.
 *
 * Return: VDO_SUCCESS or an error if the configuration is invalid.
 */
int vdo_validate_component_states(struct vdo_component_states *states,
				  nonce_t geometry_nonce, block_count_t physical_size,
				  block_count_t logical_size)
{}

/**
 * vdo_encode_component_states() - Encode the state of all vdo components in the super block.
 */
static void vdo_encode_component_states(u8 *buffer, size_t *offset,
					const struct vdo_component_states *states)
{}

/**
 * vdo_encode_super_block() - Encode a super block into its on-disk representation.
 */
void vdo_encode_super_block(u8 *buffer, struct vdo_component_states *states)
{}

/**
 * vdo_decode_super_block() - Decode a super block from its on-disk representation.
 */
int vdo_decode_super_block(u8 *buffer)
{}