From 242019fdf44544812f41b3b9bb3434e3dab229a4 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Mon, 5 Nov 2001 16:41:38 +0000 Subject: [PATCH] o code for building free area lists on a pv. Compiles but not run. --- lib/Makefile.in | 1 + lib/metadata/metadata.h | 17 ++-- lib/metadata/pv_map.c | 171 ++++++++++++++++++++++++++++++++++++++++ lib/metadata/pv_map.h | 39 +++++++++ 4 files changed, 223 insertions(+), 5 deletions(-) create mode 100644 lib/metadata/pv_map.c create mode 100644 lib/metadata/pv_map.h diff --git a/lib/Makefile.in b/lib/Makefile.in index a171123a8..b71579d46 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -29,6 +29,7 @@ SOURCES=\ format1/vg_number.c \ log/log.c \ metadata/metadata.c \ + metadata/pv_map.c \ mm/dbg_malloc.c \ mm/pool.c \ regex/matcher.c \ diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h index 2d6492148..a684397e0 100644 --- a/lib/metadata/metadata.h +++ b/lib/metadata/metadata.h @@ -33,7 +33,7 @@ #define CLUSTERED 0x00000400 /* VG */ #define SHARED 0x00000800 /* VG */ -#define ALLOC_STRICT 0x00001000 /* LV */ +#define ALLOC_STRICT 0x00001000 /* LV */ #define ALLOC_CONTIGUOUS 0x00002000 /* LV */ #define SNAPSHOT 0x00004000 /* LV */ #define SNAPSHOT_ORG 0x00008000 /* LV */ @@ -208,10 +208,17 @@ struct volume_group *vg_create(struct io_space *ios, const char *name, int pv_count, char **pv_names); struct physical_volume *pv_create(struct io_space *ios, const char *name); -struct logical_volume *lv_create(struct io_space *ios, const char *name, - uint32_t status, int stripes, - uint64_t extents, char **pv_names); - +/* + * This will insert the new lv into the + * volume_group. + */ +struct logical_volume *lv_create(struct io_space *ios, + const char *name, + uint32_t status, + uint32_t stripes, + uint32_t stripe_size, + struct volume_group *vg, + struct pv_list *acceptable_pvs); int vg_extend(struct io_space *ios, struct volume_group *vg, int pv_count, char **pv_names); diff --git a/lib/metadata/pv_map.c b/lib/metadata/pv_map.c new file mode 100644 index 000000000..0e4244d28 --- /dev/null +++ b/lib/metadata/pv_map.c @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2001 Sistina Software + * + * This file is released under the LGPL. + */ + +#include "pv_map.h" +#include "log.h" + + +static int _create_maps(struct pool *mem, struct volume_group *vg, + struct list *maps) +{ + struct list *tmp; + struct physical_volume *pv; + struct pv_map *pvm; + + list_iterate(tmp, &vg->pvs) { + pv = &(list_item(tmp, struct pv_list)->pv); + + if (!(pvm = pool_zalloc(mem, sizeof(*pvm)))) { + stack; + return 0; + } + + pvm->pv = pv; + if (!(pvm->allocated_extents = + bitset_create(mem, pv->pe_count))) { + stack; + return 0; + } + + list_add(maps, &pvm->list); + } + + return 1; +} + +static int _fill_bitsets(struct volume_group *vg, struct list *maps) +{ + /* + * FIXME: should put pvm's in a table for + * O(1) access, and remove the nasty inner + * loop in this code. + */ + struct list *lvh, *pvmh; + struct logical_volume *lv; + struct pe_specifier *pes; + struct pv_map *pvm; + uint32_t le; + + list_iterate(lvh, &vg->lvs) { + lv = &(list_item(lvh, struct lv_list)->lv); + + for (le = 0; le < lv->le_count; le++) { + pes = lv->map + le; + + /* this is the nasty that will kill performance */ + list_iterate(pvmh, maps) { + pvm = list_item(pvmh, struct pv_map); + + if (pvm->pv == pes->pv) + break; + } + + if (pvmh == maps) { + log_err("couldn't find pv specified " + "in extent map !"); + return 0; + } + + bit_set(pvm->allocated_extents, pes->pe); + } + } + + return 1; +} + +static int _create_single_area(struct pool *mem, struct pv_map *pvm, + uint32_t *extent) +{ + uint32_t e = *extent, b, count = pvm->pv->pe_count; + struct pv_area *pva; + + while (e < count && bit(pvm->allocated_extents, e)) + e++; + + if (e == count) { + *extent = e; + return 1; + } + + b = e++; + + while (e < count && !bit(pvm->allocated_extents, e)) + e++; + + if (!(pva = pool_zalloc(mem, sizeof(*pva)))) { + stack; + return 0; + } + + pva->start = b; + pva->count = e - b; + list_add(&pvm->areas, &pva->list); + + return 1; +} + +static int _create_areas(struct pool *mem, struct pv_map *pvm) +{ + uint32_t pe = 0; + + while (pe < pvm->pv->pe_count) + if (!_create_single_area(mem, pvm, &pe)) { + stack; + return 0; + } + + return 1; +} + +static int _create_all_areas(struct pool *mem, struct list *maps) +{ + struct list *tmp; + struct pv_map *pvm; + + list_iterate(tmp, maps) { + pvm = list_item(tmp, struct pv_map); + + if (!_create_areas(mem, pvm)) { + stack; + return 0; + } + } + + return 1; +} + +struct list *create_pv_maps(struct pool *mem, struct volume_group *vg) +{ + struct list *maps = pool_zalloc(mem, sizeof(*maps)); + + if (!maps) { + stack; + return NULL; + } + + list_init(maps); + + if (!_create_maps(mem, vg, maps)) { + log_err("couldn't create pv maps."); + goto bad; + } + + if (!_fill_bitsets(vg, maps)) { + log_err("couldn't fill extent allocation bitmaps."); + goto bad; + } + + if (!_create_all_areas(mem, maps)) { + log_err("couldn't create area maps."); + goto bad; + } + + return maps; + + bad: + pool_free(mem, maps); + return NULL; +} diff --git a/lib/metadata/pv_map.h b/lib/metadata/pv_map.h new file mode 100644 index 000000000..d8180eb73 --- /dev/null +++ b/lib/metadata/pv_map.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2001 Sistina Software + * + * This file is released under the LGPL. + */ + +#ifndef _LVM_PV_MAP_H +#define _LVM_PV_MAP_H + +#include "metadata.h" +#include "bitset.h" +#include "pool.h" + +/* + * The in core rep. only stores a mapping from + * logical extents to physical extents against an + * lv. Sometimes, when allocating a new lv for + * instance, it is useful to have the inverse + * mapping available. + */ + +struct pv_area { + uint32_t start; + uint32_t count; + + struct list list; +}; + +struct pv_map { + struct physical_volume *pv; + bitset_t allocated_extents; + struct list areas; + + struct list list; +}; + +struct list *create_pv_maps(struct pool *mem, struct volume_group *vg); + +#endif -- 2.43.5