recalculate free space on PE resize
PATCH 1/1 recalculate free space on PE resize
Hi folks
This patch makes it possible to extend the size of PE. It recalculates free space infos. Also it collects all errors which makes a resize fail before bailing out.
Bastian
Index: lib/metadata/metadata.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/metadata/metadata.c,v retrieving revision 1.195
metadata/metadata.c +52 -36
@@ -567,18 +567,12 @@return NULL ; } -static int _recalc_extents (uint32_t *extents,const char *desc1, -const char *desc2,uint32_t old_size, -uint32_t new_size) +static int _recalc_extents_adjust (uint32_t *extents,const char *desc1, +const char *desc2,uint32_t old_size, +uint32_t new_size) {uint64_t size = (uint64_t ) old_size * (*extents); -if (size % new_size) { -log_error ("New size %" PRIu64" for %s%s not an exact number " -"of new extents." , size, desc1, desc2); -return 0 ; - } - size /= new_size;if (size >UINT32_MAX ) {
@@ -587,15 +581,35 @@return 0 ; } +log_debug ("Changed %s%s from %u to %u." , desc1, desc2, *extents, + (uint32_t )size); + *extents = (uint32_t ) size;return 1 ; } +static int _recalc_extents (uint32_t *extents,const char *desc1, +const char *desc2,uint32_t old_size, +uint32_t new_size) +{ +uint64_t size = (uint64_t ) old_size * (*extents); + +if (size % new_size) { +log_error ("New size %" PRIu64" for %s%s not an exact number " +"of new extents." , size, desc1, desc2); +return 0 ; + } + +return _recalc_extents_adjust (extents, desc1, desc2, old_size, + new_size); +} +int vg_change_pesize (struct cmd_context *cmd __attribute((unused)),struct volume_group *vg,uint32_t new_size) {uint32_t old_size = vg->extent_size; +uint32_t new_extent_count =0 , new_free_count =0 ;struct pv_list *pvl;struct lv_list *lvl;struct physical_volume *pv;
@@ -603,6 +617,7 @@struct lv_segment *seg;struct pv_segment *pvseg;uint32_t s; +int ret =1 ; vg->extent_size = new_size;
@@ -610,26 +625,21 @@ !vg->fid->fmt->ops->vg_setup(vg->fid, vg))return_0 ; -if (!_recalc_extents (&vg->extent_count, vg->name,"" , old_size, - new_size)) - return_0; - -if (!_recalc_extents (&vg->free_count, vg->name," free space" , - old_size, new_size)) - return_0; -/* foreach PV */ dm_list_iterate_items(pvl, &vg->pvs) { pv = pvl->pv; pv->pe_size = new_size; -if (!_recalc_extents (&pv->pe_count,pv_dev_name (pv),"" , - old_size, new_size)) - return_0; +if (!_recalc_extents_adjust (&pv->pe_count,pv_dev_name (pv),"" , + old_size, new_size)) + ret =0 ;if (!_recalc_extents (&pv->pe_alloc_count,pv_dev_name (pv)," allocated space" , old_size, new_size)) - return_0; + ret =0 ; + + new_extent_count += pv->pe_count; + new_free_count += pv->pe_count - pv->pe_alloc_count;/* foreach free PV Segment */ dm_list_iterate_items(pvseg, &pv->segments) {
@@ -639,11 +649,11 @@if (!_recalc_extents (&pvseg->pe,pv_dev_name (pv)," PV segment start" , old_size, new_size)) - return_0; -if (!_recalc_extents (&pvseg->len,pv_dev_name (pv), -" PV segment length" , old_size, - new_size)) - return_0; + ret =0 ; +if (!_recalc_extents_adjust (&pvseg->len,pv_dev_name (pv), +" PV segment length" , old_size, + new_size)) + ret =0 ; } }
@@ -653,28 +663,28 @@if (!_recalc_extents (&lv->le_count, lv->name,"" , old_size, new_size)) - return_0; + ret =0 ; dm_list_iterate_items(seg, &lv->segments) {if (!_recalc_extents (&seg->le, lv->name," segment start" , old_size, new_size)) - return_0; + ret =0 ;if (!_recalc_extents (&seg->len, lv->name," segment length" , old_size, new_size)) - return_0; + ret =0 ;if (!_recalc_extents (&seg->area_len, lv->name," area length" , old_size, new_size)) - return_0; + ret =0 ;if (!_recalc_extents (&seg->extents_copied, lv->name," extents moved" , old_size, new_size)) - return_0; + ret =0 ;/* foreach area */ for (s =0 ; s < seg->area_count; s++) {
@@ -685,32 +695,38 @@ lv->name, " pvseg start", old_size, new_size)) - return_0; + ret =0 ;if (!_recalc_extents (&seg_pvseg (seg, s)->len, lv->name," pvseg length" , old_size, new_size)) - return_0; + ret =0 ;break ;case AREA_LV :if (!_recalc_extents (&seg_le (seg, s), lv->name," area start" , old_size, new_size)) - return_0; + ret =0 ;break ;case AREA_UNASSIGNED :log_error ("Unassigned area %u found in " "segment" , s); -return 0 ; + ret =0 ; } } } } -return 1 ; + vg->extent_count = new_extent_count; + vg->free_count = new_free_count; + +if (ret ==0 ) + stack; + +return ret; }/*
Index: tools/vgchange.c
===================================================================
RCS file: /cvs/lvm2/LVM2/tools/vgchange.c,v
retrieving revision 1.66
vgchange.c +0 -8
@@ -409,14 +409,6 @@return EINVALID_CMD_LINE ; } -if (extent_size > vg->extent_size) { -if ((uint64_t ) vg->extent_size * vg->extent_count % extent_size) { -/* FIXME Adjust used PV sizes instead */ -log_error ("New extent size is not a perfect fit" ); -return EINVALID_CMD_LINE ; - } - } -if (!archive (vg))return ECMD_FAILED ;
Signature · 2 lines
First study the enemy. Seek weakness. -- Romulan Commander, "Balance of Terror", stardate 1709.2