1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

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.
This commit is contained in:
Zdenek Kabelac 2012-01-05 15:38:18 +00:00
parent 1aae627433
commit 4fbde0143a
8 changed files with 32 additions and 18 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.89 -
==================================
Supports rounding of percentage (%LV, %VG...) for LV resize upward.
Use dmeventd_lvm2_command in dmeventd plugins snapshot, raid, mirror.
Add helper dmeventd_lvm2_command() into libdevmapper-event-lvm2 library.
Updated documentation for dmeventd.

View File

@ -43,6 +43,7 @@ free space for the specified PhysicalVolume(s) with the suffix %PVS,
as a percentage of the remaining free space in the Volume Group
with the suffix %FREE, or (for a snapshot) as a percentage of the total
space in the Origin Logical Volume with the suffix %ORIGIN.
The resulting value is rounded upward.
.TP
.I \-L, \-\-size [+]LogicalVolumeSize[bBsSkKmMgGtTpPeE]
Extend or set the logical volume size in units of megabytes.

View File

@ -66,6 +66,8 @@ size of the Logical Volume with the suffix \fI%LV\fP, as a percentage of the
remaining free space in the Volume Group with the suffix \fI%FREE\fP, or (for
a snapshot) as a percentage of the total space in the Origin Logical
Volume with the suffix \fI%ORIGIN\fP.
The resulting value for the substraction is rounded downward, for the absolute
size it is rounded upward.
.TP
.IR \fB\-L ", " \fB\-\-size " [" \- ] LogicalVolumeSize [ bBsSkKmMgGtTpPeE ]
Reduce or set the logical volume size in units of megabytes.

View File

@ -54,15 +54,18 @@ the remaining free space of the PhysicalVolumes on the command line with the
suffix \fI%PVS\fP, as a percentage of the remaining free space in the
Volume Group with the suffix \fI%FREE\fP, or (for a snapshot) as a percentage
of the total space in the Origin Logical Volume with the suffix \fI%ORIGIN\fP.
The resulting value is rounded downward for the substraction otherwise
it is rounded upward.
.TP
.IR \fB\-L ", " \fB\-\-size " [" + | - ] LogicalVolumeSize [ bBsSkKmMgGtTpPeE ]
Change or set the logical volume size in units of megabytes.
A size suffix of \fIM\fP for megabytes,
\fIG\fP for gigabytes, \fIT\fP for terabytes, \fIP\fP for petabytes
or \fIE\fP for exabytes is optional.
With the \fI+\fP or \fI-\fP sign the value is added to or subtracted from
the actual size of the logical volume and without it, the value is taken as an
absolute one.
With the \fI+\fP or \fI-\fP sign the value is added or subtracted
from the actual size of the logical volume and rounded
to the full extent size and without it,
the value is taken as an absolute one.
.TP
.BR \-i ", " \-\-stripes " " \fIStripes
Gives the number of stripes to use when extending a Logical Volume.

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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