1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-10-25 03:33:16 +03:00

lv_manip: detect insufficient space for RAID with split metadata

When approx_alloc reduces allocation and we have RAID/mirror with
split metadata (alloc_and_split_meta), verify that we allocated at
least 1 extent per data area.

If total_area_len < area_count, the integer division during parallel
area allocation (area_len = max_to_allocate / ah->area_multiple) results
in area_len=0 for individual data areas. This causes those areas to be
skipped (empty allocation), creating RAID image LVs with no segments.

This create invalid metadata with LVs without segments.

Example:
- Need 52 extents total (4 data areas x 13 extents)
- Metadata allocated: 4 extents (4 rmeta x 1 extent each)
- Only 1 extent remains for data
- Result: area_len = 1/4 = 0, all data areas get empty allocation

Fix by failing allocation early with clear error message instead of
creating corrupted RAID LVs that trigger internal errors.

Resolves: https://issues.redhat.com/browse/RHEL-116884

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Zdenek Kabelac
2025-10-22 16:44:09 +02:00
parent a4d5c8ee9a
commit d2715e01f5

View File

@@ -3490,6 +3490,19 @@ static int _allocate(struct alloc_handle *ah,
lv ? lv->name : "");
goto out;
}
/*
* For RAID/mirror with split metadata, verify we allocated
* at least 1 extent per data area. If total_area_len is less
* than area_count, integer division during allocation would
* result in some areas getting 0 extents, creating LVs with
* no segments which triggers internal errors during vg_write.
*/
if (ah->alloc_and_split_meta && ah->total_area_len < ah->area_count) {
log_error("Insufficient suitable allocatable extents for logical volume %s: "
"%u extents found but at least %u required (1 extent per data image).",
lv ? lv->name : "", ah->total_area_len, ah->area_count);
goto out;
}
log_verbose("Found fewer %sallocatable extents "
"for logical volume %s than requested: using %" PRIu32 " extents (reduced by %u).",
can_split ? "" : "contiguous ",