summaryrefslogtreecommitdiff
path: root/lib/metadata/pv_map.c
diff options
context:
space:
mode:
authorJoe Thornber <thornber@redhat.com>2001-11-29 18:45:35 +0000
committerJoe Thornber <thornber@redhat.com>2001-11-29 18:45:35 +0000
commit488a58a9987fa578817f2d2144b45e00ac35d1e8 (patch)
tree7ed9ff0162a0b096506bd57c7b86394c0fbb5017 /lib/metadata/pv_map.c
parent74af29faaef3d094a1437070707702e9049756f5 (diff)
downloadlvm2-488a58a9987fa578817f2d2144b45e00ac35d1e8.tar.gz
o Striped allocator
o Changed pv_map.c to maintain the list of free areas in size order, which is more helpful to the allocators. If you want to allocate a bit of an area call consume_area(area, size), this will adjust the area if there's some space left and shuffle it to the correct place in the list. Not tested.
Diffstat (limited to 'lib/metadata/pv_map.c')
-rw-r--r--lib/metadata/pv_map.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/lib/metadata/pv_map.c b/lib/metadata/pv_map.c
index 200a7d715..2075fdfed 100644
--- a/lib/metadata/pv_map.c
+++ b/lib/metadata/pv_map.c
@@ -103,6 +103,27 @@ static int _fill_bitsets(struct volume_group *vg, struct list *maps)
return r;
}
+/*
+ * Areas are maintained in size order.
+ */
+static void _insert_area(struct list *head, struct pv_area *a)
+{
+ struct list *pvah;
+ struct pv_area *pva;
+
+ list_iterate (pvah, head) {
+ pva = list_item(pvah, struct pv_area);
+
+ if (pva->count < a->count)
+ break;
+ }
+
+ a->list.n = &pva->list;
+ a->list.p = pva->list.p;
+ pva->list.p->n = &a->list;
+ pva->list.p = &a->list;
+}
+
static int _create_single_area(struct pool *mem, struct pv_map *pvm,
uint32_t *extent)
{
@@ -127,9 +148,10 @@ static int _create_single_area(struct pool *mem, struct pv_map *pvm,
return 0;
}
+ pva->map = pvm;
pva->start = b;
pva->count = e - b;
- list_add(&pvm->areas, &pva->list);
+ _insert_area(&pvm->areas, pva);
*extent = e;
return 1;
@@ -200,3 +222,17 @@ struct list *create_pv_maps(struct pool *mem, struct volume_group *vg,
pool_free(mem, maps);
return NULL;
}
+
+void consume_pv_area(struct pv_area *pva, uint32_t to_go)
+{
+ list_del(&pva->list);
+
+ assert(to_go <= pva->count);
+
+ if (to_go < pva->count) {
+ /* split the area */
+ pva->start += to_go;
+ pva->count -= to_go;
+ _insert_area(&pva->map->areas, pva);
+ }
+}