From: Alasdair Kergon Date: Tue, 18 Oct 2005 13:43:40 +0000 (+0000) Subject: Split lv_segment_area from lv_segment to permit extension. X-Git-Tag: v2_02_91~4738 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=06820362bdc96511a72d0aa0e85b55db5b69ed84;p=lvm2.git Split lv_segment_area from lv_segment to permit extension. --- diff --git a/WHATS_NEW b/WHATS_NEW index b406d2eed..db61adeb1 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.00 - =================================== + Split lv_segment_area from lv_segment to permit extension. Replacement deactivation code using libdevmapper dependency tree. Simplify dev_manager_info(). Attempt to load missing targets using modprobe. diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index 322453cc1..9b22b95d3 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -67,9 +67,15 @@ struct lv_segment *alloc_lv_segment(struct dm_pool *mem, uint32_t extents_copied) { struct lv_segment *seg; - uint32_t sz = sizeof(*seg) + (area_count * sizeof(seg->area[0])); + uint32_t areas_sz = area_count * sizeof(*seg->areas); - if (!(seg = dm_pool_zalloc(mem, sz))) { + if (!(seg = dm_pool_zalloc(mem, sizeof(*seg)))) { + stack; + return NULL; + } + + if (!(seg->areas = dm_pool_zalloc(mem, areas_sz))) { + dm_pool_free(mem, seg); stack; return NULL; } @@ -199,7 +205,7 @@ int move_lv_segment_area(struct lv_segment *seg_to, uint32_t area_to, int set_lv_segment_area_pv(struct lv_segment *seg, uint32_t area_num, struct physical_volume *pv, uint32_t pe) { - seg->area[area_num].type = AREA_PV; + seg->areas[area_num].type = AREA_PV; if (!(seg_pvseg(seg, area_num) = assign_peg_to_lvseg(pv, pe, seg->area_len, seg, area_num))) { @@ -217,12 +223,35 @@ void set_lv_segment_area_lv(struct lv_segment *seg, uint32_t area_num, struct logical_volume *lv, uint32_t le, uint32_t flags) { - seg->area[area_num].type = AREA_LV; + seg->areas[area_num].type = AREA_LV; seg_lv(seg, area_num) = lv; seg_le(seg, area_num) = le; lv->status |= flags; } +/* + * Prepare for adding parallel areas to an existing segment. + */ +static int _lv_segment_add_areas(struct logical_volume *lv, + struct lv_segment *seg, + uint32_t new_area_count) +{ + struct lv_segment_area *newareas; + uint32_t areas_sz = new_area_count * sizeof(*newareas); + + if (!(newareas = dm_pool_zalloc(lv->vg->cmd->mem, areas_sz))) { + stack; + return 0; + } + + memcpy(newareas, seg->areas, seg->area_count * sizeof(*seg->areas)); + + seg->areas = newareas; + seg->area_count = new_area_count; + + return 1; +} + /* * Reduce the size of an lv_segment. New size can be zero. */ diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h index aa850aed4..7a87504e9 100644 --- a/lib/metadata/metadata.h +++ b/lib/metadata/metadata.h @@ -214,6 +214,20 @@ struct volume_group { struct list tags; }; +/* There will be one area for each stripe */ +struct lv_segment_area { + area_type_t type; + union { + struct { + struct pv_segment *pvseg; + } pv; + struct { + struct logical_volume *lv; + uint32_t le; + } lv; + } u; +}; + struct segment_type; struct lv_segment { struct list list; @@ -239,28 +253,16 @@ struct lv_segment { struct list tags; - /* There will be one area for each stripe */ - struct { - area_type_t type; - union { - struct { - struct pv_segment *pvseg; - } pv; - struct { - struct logical_volume *lv; - uint32_t le; - } lv; - } u; - } area[0]; + struct lv_segment_area *areas; }; -#define seg_type(seg, s) (seg)->area[(s)].type -#define seg_pvseg(seg, s) (seg)->area[(s)].u.pv.pvseg -#define seg_pv(seg, s) (seg)->area[(s)].u.pv.pvseg->pv -#define seg_dev(seg, s) (seg)->area[(s)].u.pv.pvseg->pv->dev -#define seg_pe(seg, s) (seg)->area[(s)].u.pv.pvseg->pe -#define seg_lv(seg, s) (seg)->area[(s)].u.lv.lv -#define seg_le(seg, s) (seg)->area[(s)].u.lv.le +#define seg_type(seg, s) (seg)->areas[(s)].type +#define seg_pvseg(seg, s) (seg)->areas[(s)].u.pv.pvseg +#define seg_pv(seg, s) (seg)->areas[(s)].u.pv.pvseg->pv +#define seg_dev(seg, s) (seg)->areas[(s)].u.pv.pvseg->pv->dev +#define seg_pe(seg, s) (seg)->areas[(s)].u.pv.pvseg->pe +#define seg_lv(seg, s) (seg)->areas[(s)].u.lv.lv +#define seg_le(seg, s) (seg)->areas[(s)].u.lv.le struct logical_volume { union lvid lvid; diff --git a/lib/striped/striped.c b/lib/striped/striped.c index 4c83acf72..a11e96422 100644 --- a/lib/striped/striped.c +++ b/lib/striped/striped.c @@ -112,8 +112,8 @@ static int _segments_compatible(struct lv_segment *first, /* FIXME Relax this to first area type != second area type */ /* plus the additional AREA_LV checks needed */ - if ((first->area[s].type != AREA_PV) || - (second->area[s].type != AREA_PV)) + if ((first->areas[s].type != AREA_PV) || + (second->areas[s].type != AREA_PV)) return 0; width = first->area_len; @@ -142,7 +142,7 @@ static int _merge_segments(struct lv_segment *seg1, struct lv_segment *seg2) seg1->area_len += seg2->area_len; for (s = 0; s < seg1->area_count; s++) - if (seg1->area[s].type == AREA_PV) + if (seg1->areas[s].type == AREA_PV) merge_pv_segments(seg_pvseg(seg1, s), seg_pvseg(seg2, s));