From 50b89ccac3d145d0173eed1a72ad15b21e7a26c2 Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac Date: Sun, 2 Jul 2023 22:02:18 +0200 Subject: [PATCH 115/115] vdo: support version 4 Properly parse VDO volumes formatted with geometry block version 4.0. (cherry picked from commit b90c5d60156c59c33ac440dd5ea7681457684f64) --- device_mapper/vdo/vdo_reader.c | 38 ++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/device_mapper/vdo/vdo_reader.c b/device_mapper/vdo/vdo_reader.c index 2451947cd..15d8b7abb 100644 --- a/device_mapper/vdo/vdo_reader.c +++ b/device_mapper/vdo/vdo_reader.c @@ -128,6 +128,14 @@ struct vdo_volume_geometry { struct vdo_index_config index_config; } __packed; +struct vdo_volume_geometry_4 { + uint32_t release_version; + uint64_t nonce; + uuid_t uuid; + struct vdo_volume_region regions[VDO_VOLUME_REGION_COUNT]; + struct vdo_index_config index_config; +} __packed; + /* Decoding mostly only some used stucture members */ static void _vdo_decode_version(struct vdo_version_number *v) @@ -157,6 +165,16 @@ static void _vdo_decode_volume_geometry(struct vdo_volume_geometry *vg) _vdo_decode_geometry_region(&vg->regions[VDO_DATA_REGION]); } +static void _vdo_decode_volume_geometry_4(struct vdo_volume_geometry *vg, + struct vdo_volume_geometry_4 *vg_4) +{ + vg->release_version = le32_to_cpu(vg_4->release_version); + vg->nonce = le64_to_cpu(vg_4->nonce); + vg->bio_offset = 0; + vg->regions[VDO_DATA_REGION] = vg_4->regions[VDO_DATA_REGION]; + _vdo_decode_geometry_region(&vg->regions[VDO_DATA_REGION]); +} + static void _vdo_decode_config(struct vdo_config *vc) { vc->logical_blocks = le64_to_cpu(vc->logical_blocks); @@ -185,6 +203,7 @@ bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks) struct vdo_header h; struct vdo_version_number vn; struct vdo_volume_geometry vg; + struct vdo_volume_geometry_4 vg_4; struct vdo_component_41_0 pvc; *logical_blocks = 0; @@ -221,17 +240,24 @@ bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks) memcpy(&h, buffer + MAGIC_NUMBER_SIZE, sizeof(h)); _vdo_decode_header(&h); - if (h.version.major_version != 5) { - log_debug_activation("Unsupported VDO version %u.%u.", h.version.major_version, h.version.minor_version); + if (h.id != 5) { + log_debug_activation("Expected geometry VDO block instead of block %u.", h.id); goto err; } - if (h.id != 5) { - log_debug_activation("Expected geometry VDO block instead of block %u.", h.id); + switch (h.version.major_version) { + case 4: + memcpy(&vg_4, buffer + MAGIC_NUMBER_SIZE + sizeof(h), sizeof(vg_4)); + _vdo_decode_volume_geometry_4(&vg, &vg_4); + break; + case 5: + memcpy(&vg, buffer + MAGIC_NUMBER_SIZE + sizeof(h), sizeof(vg)); + _vdo_decode_volume_geometry(&vg); + break; + default: + log_debug_activation("Unsupported VDO version %u.%u.", h.version.major_version, h.version.minor_version); goto err; } - memcpy(&vg, buffer + MAGIC_NUMBER_SIZE + sizeof(h), sizeof(vg)); - _vdo_decode_volume_geometry(&vg); regpos = (vg.regions[VDO_DATA_REGION].start_block - vg.bio_offset) * 4096; -- 2.41.0