1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

RAID: Fix _sufficient_pes_free calculation for RAID

lib/metadata/lv_manip.c:_sufficient_pes_free() was calculating the
required space for RAID allocations incorrectly due to double
accounting.  This resulted in failure to allocate when available
space was tight.

When RAID data and metadata areas are allocated together, the total
amount is stored in ah->new_extents and ah->alloc_and_split_meta is
set.  '_sufficient_pes_free' was adding the necessary metadata extents
to ah->new_extents without ever checking ah->alloc_and_split_meta.
This often led to double accounting of the metadata extents.  This
patch checks 'ah->alloc_and_split_meta' to perform proper calculations
for RAID.

This error is only present in the function that checks for the needed
space, not in the functions that do the actual allocation.
This commit is contained in:
Jonathan Brassow 2013-09-26 11:30:07 -05:00
parent d6516d2f79
commit acdc731e83
2 changed files with 2 additions and 1 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.103 -
======================================
Fix RAID calculation for sufficient allocatable space.
Conversion from linear to mirror or RAID1 now honors mirror_segtype_default.
Add thin-performance configuration profile.
Add lvm.conf allocation/thin_pool_chunk_size_calculation option.

View File

@ -1162,7 +1162,7 @@ static int _sufficient_pes_free(struct alloc_handle *ah, struct dm_list *pvms,
{
uint32_t area_extents_needed = (extents_still_needed - allocated) * ah->area_count / ah->area_multiple;
uint32_t parity_extents_needed = (extents_still_needed - allocated) * ah->parity_count / ah->area_multiple;
uint32_t metadata_extents_needed = ah->metadata_area_count * RAID_METADATA_AREA_LEN; /* One each */
uint32_t metadata_extents_needed = (ah->alloc_and_split_meta) ? 0 : ah->metadata_area_count * RAID_METADATA_AREA_LEN; /* One each */
uint32_t total_extents_needed = area_extents_needed + parity_extents_needed + metadata_extents_needed;
uint32_t free_pes = pv_maps_size(pvms);