diff options
author | Alasdair Kergon <agk@redhat.com> | 2010-03-25 21:19:26 +0000 |
---|---|---|
committer | Alasdair Kergon <agk@redhat.com> | 2010-03-25 21:19:26 +0000 |
commit | 2abbc07f3c5cf0263dd3fcf11fdda046a2f5aa3a (patch) | |
tree | e0abf1cd41d9866262e5a012fa9c734350943881 /lib/metadata/pv_map.c | |
parent | 8ca4d4436d0b36a4df4fe264276d21be31ebd81e (diff) | |
download | lvm2-2abbc07f3c5cf0263dd3fcf11fdda046a2f5aa3a.tar.gz lvm2-2abbc07f3c5cf0263dd3fcf11fdda046a2f5aa3a.tar.xz lvm2-2abbc07f3c5cf0263dd3fcf11fdda046a2f5aa3a.zip |
Allow ALLOC_ANYWHERE to split contiguous areas.
Diffstat (limited to 'lib/metadata/pv_map.c')
-rw-r--r-- | lib/metadata/pv_map.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/lib/metadata/pv_map.c b/lib/metadata/pv_map.c index 8ba7856a..8ddb6985 100644 --- a/lib/metadata/pv_map.c +++ b/lib/metadata/pv_map.c @@ -24,19 +24,25 @@ * * FIXME Cope with overlap. */ -static void _insert_area(struct dm_list *head, struct pv_area *a) +static void _insert_area(struct dm_list *head, struct pv_area *a, unsigned reduced) { struct pv_area *pva; - - dm_list_iterate_items(pva, head) { - if (a->count > pva->count) + uint32_t count = reduced ? a->unreserved : a->count; + + dm_list_iterate_items(pva, head) + if (count > pva->count) break; - } dm_list_add(&pva->list, &a->list); a->map->pe_count += a->count; } +static void _remove_area(struct pv_area *a) +{ + dm_list_del(&a->list); + a->map->pe_count -= a->count; +} + static int _create_single_area(struct dm_pool *mem, struct pv_map *pvm, uint32_t start, uint32_t length) { @@ -50,7 +56,8 @@ static int _create_single_area(struct dm_pool *mem, struct pv_map *pvm, pva->map = pvm; pva->start = start; pva->count = length; - _insert_area(&pvm->areas, pva); + pva->unreserved = pva->count; + _insert_area(&pvm->areas, pva, 0); return 1; } @@ -184,8 +191,7 @@ struct dm_list *create_pv_maps(struct dm_pool *mem, struct volume_group *vg, void consume_pv_area(struct pv_area *pva, uint32_t to_go) { - dm_list_del(&pva->list); - pva->map->pe_count -= pva->count; + _remove_area(pva); assert(to_go <= pva->count); @@ -193,10 +199,21 @@ void consume_pv_area(struct pv_area *pva, uint32_t to_go) /* split the area */ pva->start += to_go; pva->count -= to_go; - _insert_area(&pva->map->areas, pva); + pva->unreserved = pva->count; + _insert_area(&pva->map->areas, pva, 0); } } +/* + * Remove an area from list and reinsert it based on its new smaller size + * after a provisional allocation. + */ +void reinsert_reduced_pv_area(struct pv_area *pva) +{ + _remove_area(pva); + _insert_area(&pva->map->areas, pva, 1); +} + uint32_t pv_maps_size(struct dm_list *pvms) { struct pv_map *pvm; |