summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAlasdair Kergon <agk@redhat.com>2005-04-22 15:44:00 +0000
committerAlasdair Kergon <agk@redhat.com>2005-04-22 15:44:00 +0000
commit22c1a65f74835218ce743a6fb540dc60b7b458ba (patch)
tree68de75e3ca72a6de7f05b99e242ea2812da51e20 /lib
parente40d124e14b921a48677e3785b066c31e43f3c95 (diff)
downloadlvm2-22c1a65f74835218ce743a6fb540dc60b7b458ba.tar.gz
lvm2-22c1a65f74835218ce743a6fb540dc60b7b458ba.tar.xz
lvm2-22c1a65f74835218ce743a6fb540dc60b7b458ba.zip
extend alloc_lv_segment
Diffstat (limited to 'lib')
-rw-r--r--lib/format1/import-extents.c110
-rw-r--r--lib/format_pool/import_export.c73
-rw-r--r--lib/format_text/import_vsn1.c12
-rw-r--r--lib/metadata/lv_alloc.h12
-rw-r--r--lib/metadata/lv_manip.c114
-rw-r--r--lib/metadata/merge.c10
6 files changed, 170 insertions, 161 deletions
diff --git a/lib/format1/import-extents.c b/lib/format1/import-extents.c
index d93c8953..2080f0e6 100644
--- a/lib/format1/import-extents.c
+++ b/lib/format1/import-extents.c
@@ -207,56 +207,55 @@ static int _check_maps_are_complete(struct hash_table *maps)
static int _read_linear(struct cmd_context *cmd, struct lv_map *lvm)
{
- uint32_t le = 0;
+ uint32_t le = 0, len;
struct lv_segment *seg;
+ struct segment_type *segtype;
+
+ if (!(segtype = get_segtype_from_string(cmd, "striped"))) {
+ stack;
+ return 0;
+ }
while (le < lvm->lv->le_count) {
- seg = alloc_lv_segment(cmd->mem, 1);
+ len = 0;
- seg->lv = lvm->lv;
- if (!(seg->segtype = get_segtype_from_string(cmd, "striped"))) {
- stack;
+ do
+ len++;
+ while ((lvm->map[le + len].pv == lvm->map[le].pv) &&
+ (lvm->map[le].pv &&
+ lvm->map[le + len].pe == lvm->map[le].pe + len));
+
+ if (!(seg = alloc_lv_segment(cmd->mem, segtype, lvm->lv, le,
+ len, 0, 0, 1, len, 0, 0))) {
+ log_error("Failed to allocate linear segment.");
return 0;
}
- seg->le = le;
- seg->len = 0;
- seg->area_len = 0;
- seg->stripe_size = 0;
-
set_lv_segment_area_pv(seg, 0, lvm->map[le].pv, lvm->map[le].pe);
- do {
- seg->len++;
- seg->area_len++;
- } while ((lvm->map[le + seg->len].pv == seg->area[0].u.pv.pv) &&
- (seg->area[0].u.pv.pv &&
- lvm->map[le + seg->len].pe == seg->area[0].u.pv.pe +
- seg->len));
+ list_add(&lvm->lv->segments, &seg->list);
le += seg->len;
-
- list_add(&lvm->lv->segments, &seg->list);
}
return 1;
}
-static int _check_stripe(struct lv_map *lvm, struct lv_segment *seg,
- uint32_t base_le, uint32_t len)
+static int _check_stripe(struct lv_map *lvm, uint32_t area_count,
+ uint32_t seg_len, uint32_t base_le, uint32_t len)
{
- uint32_t le, st;
-
- le = base_le + seg->len;
+ uint32_t st;
/*
* Is the next physical extent in every stripe adjacent to the last?
*/
- for (st = 0; st < seg->area_count; st++)
- if ((lvm->map[le + st * len].pv != seg->area[st].u.pv.pv) ||
- (seg->area[st].u.pv.pv &&
- lvm->map[le + st * len].pe !=
- seg->area[st].u.pv.pe + seg->len)) return 0;
+ for (st = 0; st < area_count; st++)
+ if ((lvm->map[base_le + st * len + seg_len].pv !=
+ lvm->map[base_le + st * len].pv) ||
+ (lvm->map[base_le + st * len].pv &&
+ lvm->map[base_le + st * len + seg_len].pe !=
+ lvm->map[base_le + st * len].pe + seg_len))
+ return 0;
return 1;
}
@@ -264,7 +263,9 @@ static int _check_stripe(struct lv_map *lvm, struct lv_segment *seg,
static int _read_stripes(struct cmd_context *cmd, struct lv_map *lvm)
{
uint32_t st, le = 0, len;
+ uint32_t area_len;
struct lv_segment *seg;
+ struct segment_type *segtype;
/*
* Work out overall striped length
@@ -276,43 +277,42 @@ static int _read_stripes(struct cmd_context *cmd, struct lv_map *lvm)
}
len = lvm->lv->le_count / lvm->stripes;
+ if (!(segtype = get_segtype_from_string(cmd, "striped"))) {
+ stack;
+ return 0;
+ }
+
while (le < len) {
- if (!(seg = alloc_lv_segment(cmd->mem, lvm->stripes))) {
- stack;
- return 0;
- }
+ area_len = 1;
- seg->lv = lvm->lv;
- if (!(seg->segtype = get_segtype_from_string(cmd, "striped"))) {
- stack;
+ /*
+ * Find how many blocks are contiguous in all stripes
+ * and so can form part of this segment
+ */
+ while (_check_stripe(lvm, lvm->stripes,
+ area_len * lvm->stripes, le, len))
+ area_len++;
+
+ if (!(seg = alloc_lv_segment(cmd->mem, segtype, lvm->lv,
+ lvm->stripes * le,
+ lvm->stripes * area_len,
+ 0, lvm->stripe_size, lvm->stripes,
+ area_len, 0, 0))) {
+ log_error("Failed to allocate striped segment.");
return 0;
}
- seg->stripe_size = lvm->stripe_size;
- seg->le = seg->area_count * le;
- seg->len = 1;
- seg->area_len = 1;
/*
* Set up start positions of each stripe in this segment
*/
- for (st = 0; st < seg->area_count; st++) {
- seg->area[st].u.pv.pv = lvm->map[le + st * len].pv;
- seg->area[st].u.pv.pe = lvm->map[le + st * len].pe;
- }
+ for (st = 0; st < seg->area_count; st++)
+ set_lv_segment_area_pv(seg, st,
+ lvm->map[le + st * len].pv,
+ lvm->map[le + st * len].pe);
- /*
- * Find how many blocks are contiguous in all stripes
- * and so can form part of this segment
- */
- while (_check_stripe(lvm, seg, le, len)) {
- seg->len++;
- seg->area_len++;
- }
+ list_add(&lvm->lv->segments, &seg->list);
le += seg->len;
- seg->len *= seg->area_count;
-
- list_add(&lvm->lv->segments, &seg->list);
}
return 1;
diff --git a/lib/format_pool/import_export.c b/lib/format_pool/import_export.c
index 21a0262d..5f6a0e35 100644
--- a/lib/format_pool/import_export.c
+++ b/lib/format_pool/import_export.c
@@ -212,40 +212,41 @@ static int _add_stripe_seg(struct pool *mem,
uint32_t *le_cur)
{
struct lv_segment *seg;
+ struct segment_type *segtype;
int j;
+ uint32_t area_len;
- if (!(seg = alloc_lv_segment(mem, usp->num_devs))) {
- log_error("Unable to allocate striped lv_segment structure");
- return 0;
- }
if (usp->striping & (usp->striping - 1)) {
log_error("Stripe size must be a power of 2");
return 0;
}
- seg->stripe_size = usp->striping;
- seg->status |= 0;
- seg->le += *le_cur;
- seg->lv = lv;
- /* add the subpool type to the segment tag list */
- str_list_add(mem, &seg->tags, _cvt_sptype(usp->type));
+ area_len = (usp->devs[0].blocks) / POOL_PE_SIZE;
- for (j = 0; j < usp->num_devs; j++) {
- if (!(seg->segtype = get_segtype_from_string(lv->vg->cmd,
- "striped"))) {
- stack;
- return 0;
- }
+ if (!(segtype = get_segtype_from_string(lv->vg->cmd,
+ "striped"))) {
+ stack;
+ return 0;
+ }
- seg->area_len = (usp->devs[j].blocks) / POOL_PE_SIZE;
- seg->len += seg->area_len;
- *le_cur += seg->area_len;
+ if (!(seg = alloc_lv_segment(mem, segtype, lv, *le_cur,
+ area_len * usp->num_devs, 0,
+ usp->striping, usp->num_devs, area_len,
+ 0, 0))) {
+ log_error("Unable to allocate striped lv_segment structure");
+ return 0;
+ }
+ for (j = 0; j < usp->num_devs; j++)
set_lv_segment_area_pv(seg, j, usp->devs[j].pv, 0);
- }
+
+ /* add the subpool type to the segment tag list */
+ str_list_add(mem, &seg->tags, _cvt_sptype(usp->type));
list_add(&lv->segments, &seg->list);
+ *le_cur += seg->len;
+
return 1;
}
@@ -254,35 +255,35 @@ static int _add_linear_seg(struct pool *mem,
uint32_t *le_cur)
{
struct lv_segment *seg;
+ struct segment_type *segtype;
int j;
+ uint32_t area_len;
+
+ if (!(segtype = get_segtype_from_string(lv->vg->cmd, "striped"))) {
+ stack;
+ return 0;
+ }
for (j = 0; j < usp->num_devs; j++) {
- /* linear segments only have 1 data area */
- if (!(seg = alloc_lv_segment(mem, 1))) {
+ area_len = (usp->devs[j].blocks) / POOL_PE_SIZE;
+
+ if (!(seg = alloc_lv_segment(mem, segtype, lv, *le_cur,
+ area_len, 0, usp->striping,
+ 1, area_len, POOL_PE_SIZE, 0))) {
log_error("Unable to allocate linear lv_segment "
"structure");
return 0;
}
- seg->stripe_size = usp->striping;
- seg->le += *le_cur;
- seg->chunk_size = POOL_PE_SIZE;
- seg->status |= 0;
- if (!(seg->segtype = get_segtype_from_string(lv->vg->cmd,
- "striped"))) {
- stack;
- return 0;
- }
+
/* add the subpool type to the segment tag list */
str_list_add(mem, &seg->tags, _cvt_sptype(usp->type));
- seg->lv = lv;
-
- seg->area_len = (usp->devs[j].blocks) / POOL_PE_SIZE;
- seg->len = seg->area_len;
- *le_cur += seg->len;
set_lv_segment_area_pv(seg, 0, usp->devs[j].pv, 0);
list_add(&lv->segments, &seg->list);
+
+ *le_cur += seg->len;
}
+
return 1;
}
diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c
index cc06d19a..1d8eff07 100644
--- a/lib/format_text/import_vsn1.c
+++ b/lib/format_text/import_vsn1.c
@@ -291,19 +291,13 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
return 0;
}
- if (!(seg = alloc_lv_segment(mem, area_count))) {
+ if (!(seg = alloc_lv_segment(mem, segtype, lv, start_extent,
+ extent_count, 0, 0, area_count,
+ extent_count, 0, 0))) {
log_error("Segment allocation failed");
return 0;
}
- seg->lv = lv;
- seg->le = start_extent;
- seg->len = extent_count;
- seg->area_len = extent_count;
- seg->status = 0u;
- seg->segtype = segtype;
- seg->extents_copied = 0u;
-
if (seg->segtype->ops->text_import &&
!seg->segtype->ops->text_import(seg, sn, pv_hash)) {
stack;
diff --git a/lib/metadata/lv_alloc.h b/lib/metadata/lv_alloc.h
index 5c77943c..e44fe89a 100644
--- a/lib/metadata/lv_alloc.h
+++ b/lib/metadata/lv_alloc.h
@@ -16,7 +16,17 @@
#ifndef _LVM_LV_ALLOC_H
#include "pool.h"
-struct lv_segment *alloc_lv_segment(struct pool *mem, uint32_t num_areas);
+struct lv_segment *alloc_lv_segment(struct pool *mem,
+ struct segment_type *segtype,
+ struct logical_volume *lv,
+ uint32_t le, uint32_t len,
+ uint32_t status,
+ uint32_t stripe_size,
+ uint32_t area_count,
+ uint32_t area_len,
+ uint32_t chunk_size,
+ uint32_t extents_copied);
+
struct lv_segment *alloc_snapshot_seg(struct logical_volume *lv,
uint32_t allocated);
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index d0d63a2d..20bc2ad7 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -61,17 +61,35 @@ static void _put_extents(struct lv_segment *seg)
}
}
-struct lv_segment *alloc_lv_segment(struct pool *mem, uint32_t num_areas)
+struct lv_segment *alloc_lv_segment(struct pool *mem,
+ struct segment_type *segtype,
+ struct logical_volume *lv,
+ uint32_t le, uint32_t len,
+ uint32_t status,
+ uint32_t stripe_size,
+ uint32_t area_count,
+ uint32_t area_len,
+ uint32_t chunk_size,
+ uint32_t extents_copied)
{
struct lv_segment *seg;
- uint32_t len = sizeof(*seg) + (num_areas * sizeof(seg->area[0]));
+ uint32_t sz = sizeof(*seg) + (area_count * sizeof(seg->area[0]));
- if (!(seg = pool_zalloc(mem, len))) {
+ if (!(seg = pool_zalloc(mem, sz))) {
stack;
return NULL;
}
- seg->area_count = num_areas;
+ seg->segtype = segtype;
+ seg->lv = lv;
+ seg->le = le;
+ seg->len = len;
+ seg->status = status;
+ seg->stripe_size = stripe_size;
+ seg->area_count = area_count;
+ seg->area_len = area_len;
+ seg->chunk_size = chunk_size;
+ seg->extents_copied = extents_copied;
list_init(&seg->tags);
return seg;
@@ -115,19 +133,14 @@ static int _alloc_parallel_area(struct logical_volume *lv, uint32_t area_count,
if (smallest < area_len)
area_len = smallest;
- if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, area_count))) {
- log_err("Couldn't allocate new parallel segment.");
+ if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv, *ix,
+ area_len * (striped ? area_count : 1),
+ 0u, stripe_size, area_count, area_len,
+ 0u, 0u))) {
+ log_error("Couldn't allocate new parallel segment.");
return 0;
}
- seg->lv = lv;
- seg->segtype = segtype;
- seg->le = *ix;
- seg->len = area_len * (striped ? area_count : 1);
- seg->area_len = area_len;
- seg->stripe_size = stripe_size;
- seg->extents_copied = 0u;
-
for (s = 0; s < area_count; s++) {
struct pv_area *pva = areas[s];
set_lv_segment_area_pv(seg, s, pva->map->pvl->pv, pva->start);
@@ -236,32 +249,31 @@ static int _alloc_linear_area(struct logical_volume *lv, uint32_t *ix,
{
uint32_t count, remaining;
struct lv_segment *seg;
+ struct segment_type *segtype;
count = pva->count;
remaining = lv->le_count - *ix;
if (count > remaining)
count = remaining;
- if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, 1))) {
- log_err("Couldn't allocate new stripe segment.");
+ if (!(segtype = get_segtype_from_string(lv->vg->cmd, "striped"))) {
+ stack;
return 0;
}
- seg->lv = lv;
- if (!(seg->segtype = get_segtype_from_string(lv->vg->cmd, "striped"))) {
- stack;
+ if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv, *ix,
+ count, 0, 0, 1, count, 0, 0))) {
+ log_error("Couldn't allocate new stripe segment.");
return 0;
}
- seg->le = *ix;
- seg->len = count;
- seg->area_len = count;
- seg->stripe_size = 0;
+
set_lv_segment_area_pv(seg, 0, map->pvl->pv, pva->start);
list_add(&lv->segments, &seg->list);
- consume_pv_area(pva, count);
- *ix += count;
+ consume_pv_area(pva, seg->len);
+ *ix += seg->len;
+
return 1;
}
@@ -279,26 +291,21 @@ static int _alloc_mirrored_area(struct logical_volume *lv, uint32_t *ix,
if (count > remaining)
count = remaining;
- if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, 2))) {
+ if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv, *ix,
+ count, 0, 0, 2, count, 0, 0))) {
log_err("Couldn't allocate new mirrored segment.");
return 0;
}
- seg->lv = lv;
- seg->segtype = segtype;
- seg->le = *ix;
- seg->status = 0u;
- seg->len = count;
- seg->area_len = count;
- seg->stripe_size = 0;
- seg->extents_copied = 0u;
/* FIXME Remove AREA_PV restriction here? */
set_lv_segment_area_pv(seg, 0, mirrored_pv, mirrored_pe);
set_lv_segment_area_pv(seg, 1, map->pvl->pv, pva->start);
+
list_add(&lv->segments, &seg->list);
- consume_pv_area(pva, count);
- *ix += count;
+ consume_pv_area(pva, seg->len);
+ *ix += seg->len;
+
return 1;
}
@@ -430,19 +437,13 @@ static int _alloc_virtual(struct logical_volume *lv,
{
struct lv_segment *seg;
- if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, 0))) {
- log_err("Couldn't allocate new zero segment.");
+ if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv, allocated,
+ lv->le_count - allocated, 0, 0, 0,
+ lv->le_count - allocated, 0, 0))) {
+ log_error("Couldn't allocate new zero segment.");
return 0;
}
- seg->lv = lv;
- seg->segtype = segtype;
- seg->status = 0u;
- seg->le = allocated;
- seg->len = lv->le_count - allocated;
- seg->area_len = seg->len;
- seg->stripe_size = 0;
- seg->extents_copied = 0u;
list_add(&lv->segments, &seg->list);
lv->status |= VIRTUAL;
@@ -453,24 +454,21 @@ struct lv_segment *alloc_snapshot_seg(struct logical_volume *lv,
uint32_t allocated)
{
struct lv_segment *seg;
+ struct segment_type *segtype;
- if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, 0))) {
- log_err("Couldn't allocate new zero segment.");
+ segtype = get_segtype_from_string(lv->vg->cmd, "snapshot");
+ if (!segtype) {
+ log_error("Failed to find snapshot segtype");
return NULL;
}
- seg->lv = lv;
- seg->segtype = get_segtype_from_string(lv->vg->cmd, "snapshot");
- if (!seg->segtype) {
- log_error("Failed to find snapshot segtype");
+ if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv, allocated,
+ lv->le_count - allocated, 0, 0, 0,
+ lv->le_count - allocated, 0, 0))) {
+ log_error("Couldn't allocate new snapshot segment.");
return NULL;
}
- seg->status = 0u;
- seg->le = allocated;
- seg->len = lv->le_count - allocated;
- seg->area_len = seg->len;
- seg->stripe_size = 0;
- seg->extents_copied = 0u;
+
list_add(&lv->segments, &seg->list);
lv->status |= VIRTUAL;
diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c
index b7cc6457..ecfd8379 100644
--- a/lib/metadata/merge.c
+++ b/lib/metadata/merge.c
@@ -98,11 +98,17 @@ static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
}
/* Clone the existing segment */
- if (!(split_seg = alloc_lv_segment(lv->vg->cmd->mem, seg->area_count))) {
- log_error("Couldn't allocate new LV segment.");
+ if (!(split_seg = alloc_lv_segment(lv->vg->cmd->mem, seg->segtype,
+ seg->lv, seg->le, seg->len,
+ seg->status, seg->stripe_size,
+ seg->area_count, seg->area_len,
+ seg->chunk_size,
+ seg->extents_copied))) {
+ log_error("Couldn't allocate cloned LV segment.");
return 0;
}
+ /* FIXME Avoid the memcpy */
len = sizeof(*seg) + (seg->area_count * sizeof(seg->area[0]));
memcpy(split_seg, seg, len);