1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-03-11 20:58:50 +03:00

vdo: fix and enhance vdo metadata reader

Improve metadata parser to handle volume_geometry bio_offset,
which needs to be substracted from 'region' start_block when present.

This bio_offset block is non-zero i.e. with converted VDO volumes.

Also fix some converted structure value (but they are not in use).

(cherry picked from commit 00633f8b668d94a58756d96f5927fd690b8f41d3)
This commit is contained in:
Zdenek Kabelac 2023-06-09 13:21:35 +02:00 committed by Marian Csontos
parent 5e6aa69ec0
commit 3b7c0786cc

View File

@ -146,13 +146,14 @@ static void _vdo_decode_header(struct vdo_header *h)
static void _vdo_decode_geometry_region(struct vdo_volume_region *vr) static void _vdo_decode_geometry_region(struct vdo_volume_region *vr)
{ {
vr->id = le32_to_cpu(vr->id); vr->id = le32_to_cpu(vr->id);
vr->start_block = le32_to_cpu(vr->start_block); vr->start_block = le64_to_cpu(vr->start_block);
} }
static void _vdo_decode_volume_geometry(struct vdo_volume_geometry *vg) static void _vdo_decode_volume_geometry(struct vdo_volume_geometry *vg)
{ {
vg->release_version = le64_to_cpu(vg->release_version); vg->release_version = le32_to_cpu(vg->release_version);
vg->nonce = le64_to_cpu(vg->nonce); vg->nonce = le64_to_cpu(vg->nonce);
vg->bio_offset = le64_to_cpu(vg->bio_offset);
_vdo_decode_geometry_region(&vg->regions[VDO_DATA_REGION]); _vdo_decode_geometry_region(&vg->regions[VDO_DATA_REGION]);
} }
@ -225,10 +226,14 @@ bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks)
goto err; goto err;
} }
if (h.id != 5) {
log_debug_activation("Expected geometry VDO block instead of block %u.", h.id);
goto err;
}
memcpy(&vg, buffer + MAGIC_NUMBER_SIZE + sizeof(h), sizeof(vg)); memcpy(&vg, buffer + MAGIC_NUMBER_SIZE + sizeof(h), sizeof(vg));
_vdo_decode_volume_geometry(&vg); _vdo_decode_volume_geometry(&vg);
regpos = vg.regions[VDO_DATA_REGION].start_block * 4096; regpos = (vg.regions[VDO_DATA_REGION].start_block - vg.bio_offset) * 4096;
if ((regpos + sizeof(buffer)) > size) { if ((regpos + sizeof(buffer)) > size) {
log_debug_activation("File/Device is shorter and can't provide requested VDO volume region at " FMTu64 " > " FMTu64 ".", regpos, size); log_debug_activation("File/Device is shorter and can't provide requested VDO volume region at " FMTu64 " > " FMTu64 ".", regpos, size);
@ -245,7 +250,6 @@ bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks)
goto err; goto err;
} }
memcpy(&vn, buffer + sizeof(struct vdo_geometry_block), sizeof(vn)); memcpy(&vn, buffer + sizeof(struct vdo_geometry_block), sizeof(vn));
_vdo_decode_version(&vn); _vdo_decode_version(&vn);