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:
parent
1aae627433
commit
4fbde0143a
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user