summaryrefslogtreecommitdiffstats
path: root/lib/metadata/pv_map.c
diff options
context:
space:
mode:
authorAlasdair Kergon <agk@redhat.com>2010-03-25 21:19:26 +0000
committerAlasdair Kergon <agk@redhat.com>2010-03-25 21:19:26 +0000
commit2abbc07f3c5cf0263dd3fcf11fdda046a2f5aa3a (patch)
treee0abf1cd41d9866262e5a012fa9c734350943881 /lib/metadata/pv_map.c
parent8ca4d4436d0b36a4df4fe264276d21be31ebd81e (diff)
downloadlvm2-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.c35
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;