Skip to content

Commit 4b4a8d9

Browse files
bjohnstoMikulas Patocka
authored andcommitted
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: Bruce Johnston <bjohnsto@redhat.com> Reviewed-by: Matthew Sakai <msakai@redhat.com> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
1 parent 0be6c2b commit 4b4a8d9

4 files changed

Lines changed: 103 additions & 0 deletions

File tree

drivers/md/dm-vdo/encodings.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "permassert.h"
1313

1414
#include "constants.h"
15+
#include "indexer.h"
1516
#include "status-codes.h"
1617
#include "types.h"
1718

@@ -1486,3 +1487,71 @@ int vdo_decode_super_block(u8 *buffer)
14861487

14871488
return ((checksum != saved_checksum) ? VDO_CHECKSUM_MISMATCH : VDO_SUCCESS);
14881489
}
1490+
1491+
/**
1492+
* vdo_compute_index_blocks() - Compute the number of blocks that the indexer will use.
1493+
* @config: The index config from which the blocks are calculated.
1494+
* @index_blocks_ptr: The number of blocks the index will use.
1495+
*
1496+
* Return: VDO_SUCCESS or an error code.
1497+
*/
1498+
static int vdo_compute_index_blocks(const struct index_config *config,
1499+
block_count_t *index_blocks_ptr)
1500+
{
1501+
int result;
1502+
u64 index_bytes;
1503+
struct uds_parameters uds_parameters = {
1504+
.memory_size = config->mem,
1505+
.sparse = config->sparse,
1506+
};
1507+
1508+
result = uds_compute_index_size(&uds_parameters, &index_bytes);
1509+
if (result != UDS_SUCCESS)
1510+
return vdo_log_error_strerror(result, "error computing index size");
1511+
1512+
*index_blocks_ptr = index_bytes / VDO_BLOCK_SIZE;
1513+
return VDO_SUCCESS;
1514+
}
1515+
1516+
/**
1517+
* vdo_initialize_volume_geometry() - Initialize the volume geometry so it can be written out.
1518+
* @nonce: The nonce to use to identify the vdo.
1519+
* @uuid: The uuid to use to identify the vdo.
1520+
* @index_config: The config used for structure initialization.
1521+
* @geometry: The volume geometry to initialize.
1522+
*
1523+
* Return: VDO_SUCCESS or an error code.
1524+
*/
1525+
int vdo_initialize_volume_geometry(nonce_t nonce, uuid_t *uuid,
1526+
const struct index_config *index_config,
1527+
struct volume_geometry *geometry)
1528+
{
1529+
int result;
1530+
block_count_t index_blocks = 0;
1531+
1532+
result = vdo_compute_index_blocks(index_config, &index_blocks);
1533+
if (result != VDO_SUCCESS)
1534+
return result;
1535+
1536+
*geometry = (struct volume_geometry) {
1537+
/* This is for backwards compatibility. */
1538+
.unused = 0,
1539+
.nonce = nonce,
1540+
.bio_offset = 0,
1541+
.regions = {
1542+
[VDO_INDEX_REGION] = {
1543+
.id = VDO_INDEX_REGION,
1544+
.start_block = 1,
1545+
},
1546+
[VDO_DATA_REGION] = {
1547+
.id = VDO_DATA_REGION,
1548+
.start_block = 1 + index_blocks,
1549+
}
1550+
}
1551+
};
1552+
1553+
memcpy(&(geometry->uuid), uuid, sizeof(uuid_t));
1554+
memcpy(&geometry->index_config, index_config, sizeof(struct index_config));
1555+
1556+
return VDO_SUCCESS;
1557+
}

drivers/md/dm-vdo/encodings.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,10 @@ vdo_get_index_region_size(struct volume_geometry geometry)
803803
vdo_get_index_region_start(geometry);
804804
}
805805

806+
int vdo_initialize_volume_geometry(nonce_t nonce, uuid_t *uuid,
807+
const struct index_config *index_config,
808+
struct volume_geometry *geometry);
809+
806810
int __must_check vdo_parse_geometry_block(unsigned char *block,
807811
struct volume_geometry *geometry);
808812

drivers/md/dm-vdo/indexer/index-layout.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,32 @@ static int __must_check compute_sizes(const struct uds_configuration *config,
249249
return UDS_SUCCESS;
250250
}
251251

252+
int uds_compute_index_size(const struct uds_parameters *parameters, u64 *index_size)
253+
{
254+
int result;
255+
struct uds_configuration *index_config;
256+
struct save_layout_sizes sizes;
257+
258+
if (index_size == NULL) {
259+
vdo_log_error("Missing output size pointer");
260+
return -EINVAL;
261+
}
262+
263+
result = uds_make_configuration(parameters, &index_config);
264+
if (result != UDS_SUCCESS) {
265+
vdo_log_error_strerror(result, "cannot compute index size");
266+
return result;
267+
}
268+
269+
result = compute_sizes(index_config, &sizes);
270+
uds_free_configuration(index_config);
271+
if (result != UDS_SUCCESS)
272+
return result;
273+
274+
*index_size = sizes.total_size;
275+
return UDS_SUCCESS;
276+
}
277+
252278
/* Create unique data using the current time and a pseudorandom number. */
253279
static void create_unique_nonce_data(u8 *buffer)
254280
{

drivers/md/dm-vdo/indexer/indexer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,10 @@ struct uds_request {
282282
);
283283
};
284284

285+
/* Compute the number of bytes needed to store an index. */
286+
int __must_check uds_compute_index_size(const struct uds_parameters *parameters,
287+
u64 *index_size);
288+
285289
/* A session is required for most index operations. */
286290
int __must_check uds_create_index_session(struct uds_index_session **session);
287291

0 commit comments

Comments
 (0)