diff options
author | Alasdair Kergon <agk@redhat.com> | 2005-04-22 15:44:00 +0000 |
---|---|---|
committer | Alasdair Kergon <agk@redhat.com> | 2005-04-22 15:44:00 +0000 |
commit | 22c1a65f74835218ce743a6fb540dc60b7b458ba (patch) | |
tree | 68de75e3ca72a6de7f05b99e242ea2812da51e20 /lib | |
parent | e40d124e14b921a48677e3785b066c31e43f3c95 (diff) | |
download | lvm2-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.c | 110 | ||||
-rw-r--r-- | lib/format_pool/import_export.c | 73 | ||||
-rw-r--r-- | lib/format_text/import_vsn1.c | 12 | ||||
-rw-r--r-- | lib/metadata/lv_alloc.h | 12 | ||||
-rw-r--r-- | lib/metadata/lv_manip.c | 114 | ||||
-rw-r--r-- | lib/metadata/merge.c | 10 |
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); |