[linux-lvm] [PATCH] recalculate free space on PE resize
Bastian Blank
bastian at waldi.eu.org
Fri Nov 7 11:45:15 UTC 2008
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
diff -u -r1.195 metadata.c
--- lib/metadata/metadata.c 3 Nov 2008 22:14:29 -0000 1.195
+++ lib/metadata/metadata.c 7 Nov 2008 11:39:57 -0000
@@ -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
diff -u -r1.66 vgchange.c
--- tools/vgchange.c 3 Nov 2008 22:14:30 -0000 1.66
+++ tools/vgchange.c 7 Nov 2008 11:40:00 -0000
@@ -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;
--
First study the enemy. Seek weakness.
-- Romulan Commander, "Balance of Terror", stardate 1709.2
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/linux-lvm/attachments/20081107/54683ca6/attachment.sig>
More information about the linux-lvm
mailing list