summaryrefslogtreecommitdiffstats
path: root/lib/metadata/pv_map.c
diff options
context:
space:
mode:
authorJoe Thornber <thornber@redhat.com>2001-11-27 16:37:33 +0000
committerJoe Thornber <thornber@redhat.com>2001-11-27 16:37:33 +0000
commit0bab65915db98d6521272a2d772db760f3289264 (patch)
tree740398522905bc00213857f512ff3f51f8893c2d /lib/metadata/pv_map.c
parent52dc2139266df81da4e06d8de02c9d936226bd83 (diff)
downloadlvm2-0bab65915db98d6521272a2d772db760f3289264.tar.gz
lvm2-0bab65915db98d6521272a2d772db760f3289264.tar.xz
lvm2-0bab65915db98d6521272a2d772db760f3289264.zip
o Sync up todays work on converting to the segmented representation of
logical volumes. It includes: format1 changes. metadata.h changes. lv_manip.c changed (striped allocation still not done though). activate.c changes. Nothing has been near a compiler as yet. Alasdair can you look at changing display.c to use to output the mappings in a more segment oriented format please ? I haven't put the span list into struct physical_volume to represent allocated extents. I think the burden of maintaining it for things like lv_extend may out weigh it's uses.
Diffstat (limited to 'lib/metadata/pv_map.c')
-rw-r--r--lib/metadata/pv_map.c74
1 files changed, 51 insertions, 23 deletions
diff --git a/lib/metadata/pv_map.c b/lib/metadata/pv_map.c
index 9666e1b8..64cd4ba3 100644
--- a/lib/metadata/pv_map.c
+++ b/lib/metadata/pv_map.c
@@ -7,6 +7,8 @@
#include "pv_map.h"
#include "log.h"
+#include <assert.h>
+
static int _create_maps(struct pool *mem, struct list *pvs, struct list *maps)
{
struct list *tmp;
@@ -35,42 +37,68 @@ static int _create_maps(struct pool *mem, struct list *pvs, struct list *maps)
return 1;
}
+static int _set_allocated(struct hash_table *hash,
+ struct physical_volume *pv, int pe)
+{
+ struct pv_map *pvm;
+
+ if (!(pvm = (struct pv_map *) hash_lookup(hash, dev_name(pv->dev)))) {
+ log_err("pv_map not present in hash table.");
+ return 0;
+ }
+
+ /* sanity check */
+ assert(!bit(pvm->allocated_extents, pe));
+
+ bit_set(pvm->allocated_extents, pe);
+ 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;
+ uint32_t i, r = 0;
+ struct hash_table *hash;
- list_iterate(lvh, &vg->lvs) {
- lv = &(list_item(lvh, struct lv_list)->lv);
+ if (!(hash = hash_table_create(128))) {
+ log_err("Couldn't create hash table for pv maps.");
+ return 0;
+ }
- for (le = 0; le < lv->le_count; le++) {
- pes = lv->map + le;
+ /* populate the hash table */
+ list_iterate (pvmh, maps) {
+ pvm = list_item(pvmh, struct pv_map);
+ if (!hash_insert(hash, dev_name(pvm->pv->dev), pvm)) {
+ stack;
+ goto out;
+ }
+ }
- /* this is the nasty that will kill performance */
- list_iterate(pvmh, maps) {
- pvm = list_item(pvmh, struct pv_map);
+ /* iterate through all the lv's setting bit's for used pe's */
+ list_iterate (lvh, &vg->lvs) {
+ lv = &(list_item(lvh, struct lv_list)->lv);
- if (pvm->pv == pes->pv)
- break;
+ list_iterate (segh, &lv->segments) {
+ seg = list_item(segh, struct stripe_segment);
+
+ for (i = 0; i < seg->len; i++) {
+ if (!_set_allocated(hash,
+ seg->area[i % seg->stripes].pv,
+ seg->area[i % seg->stripes].pe +
+ (i / stripes))) {
+ stack;
+ goto out;
+ }
}
-
- /* not all pvs are necc. in the list */
- if (pvmh == maps)
- continue;
-
- bit_set(pvm->allocated_extents, pes->pe);
}
}
+ r = 1;
- return 1;
+ out:
+ hash_table_destroy(hash);
+ return r;
}
static int _create_single_area(struct pool *mem, struct pv_map *pvm,