LVM: allow lv_extend of empty layered volumes
PATCH 1/1 LVM: allow lv_extend of empty layered volumes
Patch name: lvm-allow-lv_extend-of-empty-layered-volumes.patch
This patch adds the ability to extend 0 length layered LVs. This allows us to allocate all images of a mirror (or RAID array) at one time during create.
The current mirror implementation still requires a separate allocation for the log, however.
lib/metadata/lv_manip.c +111 -26
@@ -2106,29 +2106,90 @@ int lv_add_log_segment(struct alloc_hand 0, status, 0); } -static int _lv_extend_mirror (struct alloc_handle *ah, -struct logical_volume *lv, -uint32_t extents,uint32_t first_area, -uint32_t stripes,uint32_t stripe_size) +static int _lv_insert_empty_layer (struct logical_volume *lv, +const struct segment_type *segtype, +uint32_t region_size, +uint32_t devices) +{ +struct logical_volume *sub_lv; +uint32_t i; +uint64_t status =0 ; +char *img_name; +size_t len; +struct lv_segment *mapseg; + +if (lv->le_count ||first_seg (lv)) { +/* +* This should never happen. The message is meant +* to help developers. +*/ +log_error ("Bad arguments to _lv_insert_empty_layer" ); +return 0 ; + } + +/* FIXME: Mirror specific */ + lv->status |=MIRRORED ; + +/* +* First, create our top-level segment for our top-level LV +*/ +if (!(mapseg =alloc_lv_segment (lv->vg->cmd->mem, segtype, + lv,0 ,0 , lv->status,0 ,NULL , + devices,0 ,0 , region_size,0 ,NULL ))) { +log_error ("Failed to create mapping segment for %s" , lv->name); +return 0 ; + } + +/* +* Next, create all of our sub_lv's and link them in. +*/ + len =strlen (lv->name) +32 ; +if (!(img_name =alloca (len))) + return_0; +if (dm_snprintf (img_name, len,"%s%s" , lv->name,"_mimage_%d" ) <0 ) + return_0; + +for (i =0 ; i < devices; i++) { + sub_lv =lv_create_empty (img_name,NULL , +MIRROR_IMAGE , lv->alloc, lv->vg); +if (!sub_lv) { +log_error ("Failed to allocate sub_lv for %s" , lv->name); +return 0 ; + } +if (!set_lv_segment_area_lv (mapseg, i, sub_lv,0 , status)) + return_0; + } +dm_list_add (&lv->segments, &mapseg->list); + +return 1 ; +} + +static int _lv_extend_layered_lv (struct alloc_handle *ah, +struct logical_volume *lv, +uint32_t extents,uint32_t first_area, +uint32_t stripes,uint32_t stripe_size) { +struct logical_volume *sub_lv;struct lv_segment *seg;uint32_t m, s; seg =first_seg (lv);for (m = first_area, s =0 ; s < seg->area_count; s++) {if (is_temporary_mirror_layer (seg_lv (seg, s))) { -if (!_lv_extend_mirror (ah,seg_lv (seg, s), extents, m, stripes, stripe_size)) +if (!_lv_extend_layered_lv (ah,seg_lv (seg, s), extents, + m, stripes, stripe_size)) return_0; m +=lv_mirror_count (seg_lv (seg, s));continue ; } -if (!lv_add_segment (ah, m, stripes,seg_lv (seg, s), + sub_lv =seg_lv (seg, s); +if (!lv_add_segment (ah, m, stripes, sub_lv,get_segtype_from_string (lv->vg->cmd,"striped" ), - stripe_size,0 ,0 )) { -log_error ("Aborting. Failed to extend %s." , -seg_lv (seg, s)->name); + stripe_size, sub_lv->status,0 )) { +log_error ("Aborting. Failed to extend %s in %s." , + sub_lv->name, lv->name);return 0 ; } m += stripes;
@@ -2147,9 +2208,9 @@ static int _lv_extend_mirror(struct alloint lv_extend (struct logical_volume *lv,const struct segment_type *segtype,uint32_t stripes,uint32_t stripe_size, -uint32_t mirrors,uint32_t extents, -struct dm_list *allocatable_pvs, -alloc_policy_t alloc) +uint32_t mirrors,uint32_t region_size, +uint32_t extents, +struct dm_list *allocatable_pvs,alloc_policy_t alloc) {int r =1 ;struct alloc_handle *ah;
@@ -2161,12 +2222,34 @@ int lv_extend(struct logical_volume *lv, extents, allocatable_pvs, alloc, NULL))) return_0; -if (mirrors <2 ) +if (!segtype_is_mirrored (segtype)) r =lv_add_segment (ah,0 , ah->area_count, lv, segtype, stripe_size,0u ,0 ); -else - r =_lv_extend_mirror (ah, lv, extents,0 , stripes, stripe_size); +else { +uint32_t dev_count; + +/* +* When RAID is introduced, all the devices are AREA_LV. +* However, when LVM does 'mirror on stripe' using legacy +* targets, the mirror legs are AREA_LV while the stripes +* underneath are AREA_PV +* +if (segtype_is_raid(segtype)) +dev_count = mirrors * stripes; +else +*/ + dev_count = mirrors; +if (!lv->le_count && + !_lv_insert_empty_layer (lv, segtype, + region_size, dev_count)) { +log_error ("Failed to insert layer for %s" , lv->name); +alloc_destroy (ah); +return 0 ; + } + r =_lv_extend_layered_lv (ah, lv, extents,0 , + stripes, stripe_size); + }alloc_destroy (ah);return r; }
@@ -3387,7 +3470,7 @@ static struct logical_volume *_create_vi ALLOC_INHERIT, vg))) return_NULL; -if (!lv_extend (lv, segtype,1 ,0 ,1 , voriginextents, +if (!lv_extend (lv, segtype,1 ,0 ,1 ,0 , voriginextents,NULL ,ALLOC_INHERIT )) return_NULL;
@@ -3586,6 +3669,10 @@ int lv_create_single(struct volume_group "Don't read what you didn't write!"); status |=LV_NOTSYNCED ; } + + lp->segtype =get_segtype_from_string (cmd,"mirror" ); +if (!lp->segtype) + return_0; } if (!(lv = lv_create_empty(lp->lv_name ? lp->lv_name : "lvol%d", NULL,
@@ -3609,19 +3696,17 @@ int lv_create_single(struct volume_groupdm_list_splice (&lv->tags, &lp->tags);if (!lv_extend (lv, lp->segtype, lp->stripes, lp->stripe_size, -1 , lp->extents, lp->pvh, lp->alloc)) + lp->mirrors, +adjusted_mirror_region_size (vg->extent_size, + lv->le_count, + lp->region_size), + lp->extents, lp->pvh, lp->alloc)) return_0;if (lp->mirrors >1 ) { -if (!lv_add_mirrors (cmd, lv, lp->mirrors -1 , lp->stripes, - lp->stripe_size, -adjusted_mirror_region_size ( - vg->extent_size, - lv->le_count, - lp->region_size), - lp->log_count, lp->pvh, lp->alloc, -MIRROR_BY_LV | - (lp->nosync ?MIRROR_SKIP_INIT_SYNC :0 ))) { +if (!add_mirror_log (cmd, lv, lp->log_count, +first_seg (lv)->region_size, + lp->pvh, lp->alloc)) { stack; goto revert_new_lv; }
lib/metadata/metadata-exported.h +3 -3
@@ -500,9 +500,9 @@ int replace_lv_with_error_segment(structint lv_extend (struct logical_volume *lv,const struct segment_type *segtype,uint32_t stripes,uint32_t stripe_size, -uint32_t mirrors,uint32_t extents, -struct dm_list *allocatable_pvs, -alloc_policy_t alloc); +uint32_t mirrors,uint32_t region_size, +uint32_t extents, +struct dm_list *allocatable_pvs,alloc_policy_t alloc);/* lv must be part of lv->vg->lvs */ int lv_remove (struct logical_volume *lv);
tools/lvresize.c +3 -2
@@ -670,8 +670,9 @@ static int _lvresize(struct cmd_contextreturn ECMD_FAILED ; } }else if ((lp->extents > lv->le_count) &&/* Ensure we extend */ - !lv_extend (lv, lp->segtype, lp->stripes, - lp->stripe_size, lp->mirrors, + !lv_extend (lv, lp->segtype, + lp->stripes, lp->stripe_size, + lp->mirrors,first_seg (lv)->region_size, lp->extents - lv->le_count, pvh, alloc)) { stack;
PATCH 1/1 LVM: allow lv_extend of empty layered volumes
Dne 29.3.2011 15:04, Jonathan Brassow napsal(a):
Quoted 29 lines
Patch name: lvm-allow-lv_extend-of-empty-layered-volumes.patch
This patch adds the ability to extend 0 length layered LVs. This allows us to allocate all images of a mirror (or RAID array) at one time during create.
The current mirror implementation still requires a separate allocation for the log, however.
Index:
LVM2/lib/metadata/lv_manip.c
===================================================================lib/metadata/lv_manip.c +8
-4@@ -2106,29 +2106,90 @@ int lv_add_log_segment(struct alloc_hand 0, status, 0); } -static int _lv_extend_mirror (struct alloc_handle *ah, -struct logical_volume *lv, -uint32_t extents,uint32_t first_area, -uint32_t stripes,uint32_t stripe_size) +static int _lv_insert_empty_layer (struct logical_volume *lv, +const struct segment_type *segtype, +uint32_t region_size, +uint32_t devices) +{ +struct logical_volume *sub_lv; +uint32_t i; +uint64_t status =0 ;
lib/metadata/lv_manip.c int lv_add_log_segment(struct alloc_hand · line 2126
Quoted 10 lines
lib/metadata/lv_manip.c +10
-0+char *img_name; +size_t len; +struct lv_segment *mapseg; + +if (lv->le_count ||first_seg (lv)) { +/* +* This should never happen. The message is meant +* to help developers. +*/ +log_error ("Bad arguments to _lv_insert_empty_layer" );
log_error(INTERNAL_ERROR...) - so it's catched by buildbot
Quoted 20 lines
lib/metadata/lv_manip.c +20
-0+return 0 ; + } + +/* FIXME: Mirror specific */ + lv->status |=MIRRORED ; + +/* +* First, create our top-level segment for our top-level LV +*/ +if (!(mapseg =alloc_lv_segment (lv->vg->cmd->mem, segtype, + lv,0 ,0 , lv->status,0 ,NULL , + devices,0 ,0 , region_size,0 ,NULL ))) { +log_error ("Failed to create mapping segment for %s" , lv->name); +return 0 ; + } + +/* +* Next, create all of our sub_lv's and link them in. +*/ + len =strlen (lv->name) +32 ;
lib/metadata/lv_manip.c int lv_add_log_segment(struct alloc_hand · line 2156
Quoted 10 lines
lib/metadata/lv_manip.c +10
-0+if (!(img_name =alloca (len))) + return_0; +if (dm_snprintf (img_name, len,"%s%s" , lv->name,"_mimage_%d" ) <0 ) + return_0; + +for (i =0 ; i < devices; i++) { + sub_lv =lv_create_empty (img_name,NULL , +MIRROR_IMAGE , lv->alloc, lv->vg); +if (!sub_lv) { +log_error ("Failed to allocate sub_lv for %s" , lv->name);
log_warn()/log_debug() // as we already get log_error from lv_create_empty(). return_0;
Zdenek