Skip to content

Commit 427bf2c

Browse files
bjohnstoMikulas Patocka
authored andcommitted
dm vdo: add geometry block encoding
Add vdo_encode_volume_geometry() to write the geometry block into a buffer so that it can be written to disk. The corresponding decode path already exists. 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 beced13 commit 427bf2c

2 files changed

Lines changed: 58 additions & 0 deletions

File tree

drivers/md/dm-vdo/encodings.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,62 @@ static void decode_volume_geometry(u8 *buffer, size_t *offset,
287287
};
288288
}
289289

290+
/**
291+
* vdo_encode_volume_geometry() - Encode the on-disk representation of a volume geometry into a buffer.
292+
* @buffer: A buffer to store the encoding.
293+
* @geometry: The geometry to encode.
294+
* @version: The geometry block version to encode.
295+
*
296+
* Return: VDO_SUCCESS or an error.
297+
*/
298+
int vdo_encode_volume_geometry(u8 *buffer, const struct volume_geometry *geometry,
299+
u32 version)
300+
{
301+
int result;
302+
enum volume_region_id id;
303+
u32 checksum;
304+
size_t offset = 0;
305+
const struct header *header;
306+
307+
memcpy(buffer, VDO_GEOMETRY_MAGIC_NUMBER, VDO_GEOMETRY_MAGIC_NUMBER_SIZE);
308+
offset += VDO_GEOMETRY_MAGIC_NUMBER_SIZE;
309+
310+
header = (version > 4) ? &GEOMETRY_BLOCK_HEADER_5_0 : &GEOMETRY_BLOCK_HEADER_4_0;
311+
vdo_encode_header(buffer, &offset, header);
312+
313+
/* This is for backwards compatibility */
314+
encode_u32_le(buffer, &offset, geometry->unused);
315+
encode_u64_le(buffer, &offset, geometry->nonce);
316+
memcpy(buffer + offset, (unsigned char *) &geometry->uuid, sizeof(uuid_t));
317+
offset += sizeof(uuid_t);
318+
319+
if (version > 4)
320+
encode_u64_le(buffer, &offset, geometry->bio_offset);
321+
322+
for (id = 0; id < VDO_VOLUME_REGION_COUNT; id++) {
323+
encode_u32_le(buffer, &offset, geometry->regions[id].id);
324+
encode_u64_le(buffer, &offset, geometry->regions[id].start_block);
325+
}
326+
327+
encode_u32_le(buffer, &offset, geometry->index_config.mem);
328+
encode_u32_le(buffer, &offset, 0);
329+
330+
if (geometry->index_config.sparse)
331+
buffer[offset++] = 1;
332+
else
333+
buffer[offset++] = 0;
334+
335+
result = VDO_ASSERT(header->size == offset + sizeof(u32),
336+
"should have encoded up to the geometry checksum");
337+
if (result != VDO_SUCCESS)
338+
return result;
339+
340+
checksum = vdo_crc32(buffer, offset);
341+
encode_u32_le(buffer, &offset, checksum);
342+
343+
return VDO_SUCCESS;
344+
}
345+
290346
/**
291347
* vdo_parse_geometry_block() - Decode and validate an encoded geometry block.
292348
* @block: The encoded geometry block.

drivers/md/dm-vdo/encodings.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,8 @@ int vdo_initialize_volume_geometry(nonce_t nonce, uuid_t *uuid,
813813
const struct index_config *index_config,
814814
struct volume_geometry *geometry);
815815

816+
int vdo_encode_volume_geometry(u8 *buffer, const struct volume_geometry *geometry,
817+
u32 version);
816818
int __must_check vdo_parse_geometry_block(unsigned char *block,
817819
struct volume_geometry *geometry);
818820

0 commit comments

Comments
 (0)