summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorZdenek Kabelac <zkabelac@redhat.com>2012-01-05 15:38:18 +0000
committerZdenek Kabelac <zkabelac@redhat.com>2012-01-05 15:38:18 +0000
commit4fbde0143a553a7135558cc8e8bc0503beacdb78 (patch)
tree535afe3dc1d4a2ccdd7a58df69fcb20b03deea3a /tools
parent1aae627433e7ec2a4acbcffa04be4bf4f89dba65 (diff)
downloadlvm2-4fbde0143a553a7135558cc8e8bc0503beacdb78.tar.gz
lvm2-4fbde0143a553a7135558cc8e8bc0503beacdb78.tar.xz
lvm2-4fbde0143a553a7135558cc8e8bc0503beacdb78.zip
Support rounding of percentage upward
We want to keep this logic - when LV is extend - extend the LV by at least given amount, when LV is reduced - reduce the LV by at most given amount. So for this the rounding needs to be used. Current logic which seems to satisfy give rule is to round up all extent values for LV resize upward except for values with '-' sign that are round downward. This patch also fixes the problem when lvextend --use-polices tried to extend LV the by i.e. 20% - but the resulting 20% were smaller the extent size thus before this patch no extension happened.
Diffstat (limited to 'tools')
-rw-r--r--tools/lvcreate.c10
-rw-r--r--tools/lvresize.c18
-rw-r--r--tools/toollib.c7
-rw-r--r--tools/tools.h2
4 files changed, 22 insertions, 15 deletions
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 6118ab5f..7de835ea 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -257,17 +257,17 @@ static int _update_extents_params(struct volume_group *vg,
switch(lcp->percent) {
case PERCENT_VG:
- lp->extents = percent_of_extents(lp->extents, vg->extent_count);
+ lp->extents = percent_of_extents(lp->extents, vg->extent_count, 0);
break;
case PERCENT_FREE:
- lp->extents = percent_of_extents(lp->extents, vg->free_count);
+ lp->extents = percent_of_extents(lp->extents, vg->free_count, 0);
break;
case PERCENT_PVS:
if (!lcp->pv_count)
- lp->extents = percent_of_extents(lp->extents, vg->extent_count);
+ lp->extents = percent_of_extents(lp->extents, vg->extent_count, 0);
else {
pv_extent_count = pv_list_extents_free(lp->pvh);
- lp->extents = percent_of_extents(lp->extents, pv_extent_count);
+ lp->extents = percent_of_extents(lp->extents, pv_extent_count, 0);
}
break;
case PERCENT_LV:
@@ -285,7 +285,7 @@ static int _update_extents_params(struct volume_group *vg,
log_error(INTERNAL_ERROR "Couldn't find origin volume.");
return 0;
}
- lp->extents = percent_of_extents(lp->extents, origin->le_count);
+ lp->extents = percent_of_extents(lp->extents, origin->le_count, 0);
break;
case PERCENT_NONE:
break;
diff --git a/tools/lvresize.c b/tools/lvresize.c
index 9fc56e07..e867deff 100644
--- a/tools/lvresize.c
+++ b/tools/lvresize.c
@@ -464,27 +464,33 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
switch(lp->percent) {
case PERCENT_VG:
- lp->extents = percent_of_extents(lp->extents, vg->extent_count);
+ lp->extents = percent_of_extents(lp->extents, vg->extent_count,
+ (lp->sign != SIGN_MINUS));
break;
case PERCENT_FREE:
- lp->extents = percent_of_extents(lp->extents, vg->free_count);
+ lp->extents = percent_of_extents(lp->extents, vg->free_count,
+ (lp->sign != SIGN_MINUS));
break;
case PERCENT_LV:
- lp->extents = percent_of_extents(lp->extents, lv->le_count);
+ lp->extents = percent_of_extents(lp->extents, lv->le_count,
+ (lp->sign != SIGN_MINUS));
break;
case PERCENT_PVS:
if (lp->argc) {
pv_extent_count = pv_list_extents_free(pvh);
- lp->extents = percent_of_extents(lp->extents, pv_extent_count);
+ lp->extents = percent_of_extents(lp->extents, pv_extent_count,
+ (lp->sign != SIGN_MINUS));
} else
- lp->extents = percent_of_extents(lp->extents, vg->extent_count);
+ lp->extents = percent_of_extents(lp->extents, vg->extent_count,
+ (lp->sign != SIGN_MINUS));
break;
case PERCENT_ORIGIN:
if (!lv_is_cow(lv)) {
log_error("Specified LV does not have an origin LV.");
return EINVALID_CMD_LINE;
}
- lp->extents = percent_of_extents(lp->extents, origin_from_cow(lv)->le_count);
+ lp->extents = percent_of_extents(lp->extents, origin_from_cow(lv)->le_count,
+ (lp->sign != SIGN_MINUS));
break;
case PERCENT_NONE:
break;
diff --git a/tools/toollib.c b/tools/toollib.c
index 1e139612..6be0fe7a 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1630,8 +1630,9 @@ int change_tag(struct cmd_context *cmd, struct volume_group *vg,
return 1;
}
-/* Return percents of extents and avoid overflow */
-uint32_t percent_of_extents(uint32_t percents, uint32_t count)
+/* Return percents of extents and avoid overflow, with optional roundup */
+uint32_t percent_of_extents(uint32_t percents, uint32_t count, int roundup)
{
- return (uint32_t)((uint64_t)percents * (uint64_t)count / 100);
+ return (uint32_t)(((uint64_t)percents * (uint64_t)count +
+ ((roundup) ? 99 : 0)) / 100);
}
diff --git a/tools/tools.h b/tools/tools.h
index f1ae1732..50a0fc9e 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -181,5 +181,5 @@ int lvconvert_poll(struct cmd_context *cmd, struct logical_volume *lv, unsigned
int mirror_remove_missing(struct cmd_context *cmd,
struct logical_volume *lv, int force);
-uint32_t percent_of_extents(uint32_t percents, uint32_t count);
+uint32_t percent_of_extents(uint32_t percents, uint32_t count, int roundup);
#endif