]> sourceware.org Git - lvm2.git/commitdiff
o lv_manip.c will contain the code for lv_create, lv_extend and lv_reduce.
authorJoe Thornber <thornber@redhat.com>
Tue, 6 Nov 2001 10:29:56 +0000 (10:29 +0000)
committerJoe Thornber <thornber@redhat.com>
Tue, 6 Nov 2001 10:29:56 +0000 (10:29 +0000)
lib/Makefile.in
lib/metadata/lv_manip.c [new file with mode: 0644]
lib/metadata/metadata.h
lib/metadata/pv_map.c

index b71579d46c61d002cbdde36cf845ec9d9ec6a93d..60f06318f968fe3d86d7d140487d33a59a838b7f 100644 (file)
@@ -28,6 +28,7 @@ SOURCES=\
        format1/layout.c \
        format1/vg_number.c \
        log/log.c \
+       metadata/lv_manip.c \
        metadata/metadata.c \
        metadata/pv_map.c \
        mm/dbg_malloc.c \
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
new file mode 100644 (file)
index 0000000..3af0d5c
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2001 Sistina Software
+ *
+ * This file is released under the LGPL.
+ */
+
+#include "metadata.h"
+#include "pv_map.h"
+#include "log.h"
+
+/*
+ * The heart of the allocation code.  This
+ * function takes a pv_area and allocates it to
+ * the lv.  If the lv doesn't need the complete
+ * area then the area is split, otherwise the area
+ * is unlinked from the pv_map.
+ */
+static int _alloc_area(struct logical_volume *lv, uint32_t index,
+                      struct physical_volume *pv, struct pv_area *pva)
+{
+       uint32_t count, remaining, i, start;
+
+       start = pva->start;
+
+       count = pva->count;
+       remaining = lv->le_count - index;
+
+       if (remaining < count) {
+               /* split the area */
+               count = remaining;
+               pva->start += count;
+               pva->count -= count;
+
+       } else {
+               /* unlink the area */
+               list_del(&pva->list);
+       }
+
+       for (i = 0; i < count; i++) {
+               lv->map[i + index].pv = pv;
+               lv->map[i + index].pe = start + i;
+       }
+
+       return count;
+}
+
+static int _alloc_striped(struct logical_volume *lv, struct list *pvms)
+{
+       log_err("striped allocation not implemented yet.");
+       return 0;
+}
+
+static int _alloc_contiguous(struct logical_volume *lv, struct list *pvms)
+{
+       log_err("contiguous allocation not implemented yet.");
+       return 0;
+}
+
+static int _alloc_simple(struct logical_volume *lv, struct list *pvms)
+{
+       struct list *tmp1, *tmp2;
+       struct pv_map *pvm;
+       struct pv_area *pva;
+       uint32_t allocated = 0;
+
+       list_iterate (tmp1, pvms) {
+               pvm = list_item(tmp1, struct pv_map);
+
+               list_iterate (tmp2, &pvm->areas) {
+                       pva = list_item(tmp2, struct pv_area);
+                       allocated += _alloc_area(lv, allocated, pvm->pv, pva);
+
+                       if (allocated == lv->le_count)
+                               break;
+               }
+
+               if (allocated == lv->le_count) /* FIXME: yuck, repeated test */
+                       break;
+       }
+
+       if (allocated != lv->le_count) {
+               log_err("insufficient free extents to "
+                       "allocate logical volume");
+               return 0;
+       }
+
+       return 1;
+}
+
+struct logical_volume *lv_create(struct io_space *ios,
+                                const char *name,
+                                uint32_t status,
+                                uint32_t stripes,
+                                uint32_t stripe_size,
+                                uint32_t extents,
+                                struct volume_group *vg,
+                                struct pv_list *acceptable_pvs)
+{
+       struct lv_list *ll = NULL;
+       struct logical_volume *lv;
+       struct list *pvms;
+       struct pool *scratch;
+       int r;
+
+       if (!(scratch = pool_create(1024))) {
+               stack;
+               return NULL;
+       }
+
+       if (!extents) {
+               log_err("Attempt to create an lv with zero extents");
+               return NULL;
+       }
+
+       if (vg->free_count < extents) {
+               log_err("Insufficient free extents in volume group");
+               goto bad;
+       }
+
+       if (vg->max_lv == vg->lv_count) {
+               log_err("Maximum logical volumes already reached "
+                       "for this volume group.");
+               goto bad;
+       }
+
+       if (!(ll = pool_zalloc(ios->mem, sizeof(*ll)))) {
+               stack;
+               return NULL;
+       }
+
+       lv = &ll->lv;
+
+       strcpy(lv->id.uuid, "");
+
+       if (!(lv->name = pool_strdup(ios->mem, name))) {
+               stack;
+               goto bad;
+       }
+
+       lv->vg = vg;
+       lv->status = status;
+       lv->read_ahead = 0;
+       lv->stripes = stripes;
+       lv->size = extents * vg->extent_size;
+       lv->le_count = extents;
+
+       if (!(lv->map = pool_zalloc(ios->mem, sizeof(*lv->map) * extents))) {
+               stack;
+               goto bad;
+       }
+
+       /*
+        * Build the sets of available areas on
+        * the pv's.
+        */
+       if (!(pvms = create_pv_maps(scratch, vg))) {
+               log_err("couldn't create extent mappings");
+               goto bad;
+       }
+
+       if (stripes > 1)
+               r = _alloc_striped(lv, pvms);
+
+       else if (status & ALLOC_CONTIGUOUS)
+               r = _alloc_contiguous(lv, pvms);
+
+       else
+               r = _alloc_simple(lv, pvms);
+
+       if (!r) {
+               log_err("Extent allocation failed.");
+               goto bad;
+       }
+
+       list_add(&ll->list, &vg->lvs);
+       vg->lv_count++;
+       vg->free_count -= extents;
+
+       pool_destroy(scratch);
+       return lv;
+
+ bad:
+       if (ll)
+               pool_free(ios->mem, ll);
+
+       pool_destroy(scratch);
+       return NULL;
+}
index 6e741f4e19fc339f3eec17be4356ee28f8237e21..7eb557997a3c307bfb920b968e8c4e4abd4364a3 100644 (file)
@@ -217,7 +217,7 @@ struct logical_volume *lv_create(struct io_space *ios,
                                 uint32_t status,
                                 uint32_t stripes,
                                 uint32_t stripe_size,
-                                uint64_t extents,
+                                uint32_t extents,
                                 struct volume_group *vg,
                                 struct pv_list *acceptable_pvs);
 
index 0e4244d280534971992ba2972066744d82a1396c..0ff7a81d097f4b359c13d4c8779686b0f453ff36 100644 (file)
@@ -103,6 +103,7 @@ static int _create_single_area(struct pool *mem, struct pv_map *pvm,
        pva->start = b;
        pva->count = e - b;
        list_add(&pvm->areas, &pva->list);
+       *extent = e;
 
        return 1;
 }
This page took 0.044781 seconds and 5 git commands to generate.