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

allocation: improve approx alloc with resize

Start to convert percentage size handling in lvresize to the new
standard.  Note in the man pages that this code is incomplete.
Fix a regression in non-percentage allocation in my last check in.

This is what I am aiming for:

-l<extents>
-l<percent> LV/ORIGIN
	sets or changes the LV size based on the specified quantity
	of logical logical extents (that might be backed by
	a higher number of physical extents)

-l<percent> PVS/VG/FREE
	sets or changes the LV size so as to allocate or free the
	desired quantity of physical extents (that might amount to a
	lower number of logical extents for the LV concerned)

-l+50%FREE - Use up half the remaining free space in the VG when
	carrying out this operation.

-l50%VG - After this operation, this LV should be using up half the
	space in the VG.

-l200%LV - Double the logical size of this LV.

-l+100%LV - Double the logical size of this LV.

-l-50%LV - Reduce the logical size of this LV by half.
This commit is contained in:
Alasdair G Kergon 2014-02-24 22:48:23 +00:00
parent 8083143822
commit b359b86f88
7 changed files with 49 additions and 13 deletions

View File

@ -1197,9 +1197,11 @@ static struct alloc_handle *_alloc_init(struct cmd_context *cmd,
ah->log_len = !metadata_area_count ? 0 :
mirror_log_extents(ah->region_size, extent_size,
new_extents / ah->area_multiple);
ah->new_extents = ah->new_extents * ah->area_multiple / ah->area_count;
ah->new_extents = (ah->new_extents / ah->area_multiple) * ah->area_multiple;
log_debug("Adjusted allocation request to %" PRIu32 " data extents.", ah->new_extents);
if (approx_alloc) {
ah->new_extents = ah->new_extents * ah->area_multiple / ah->area_count;
ah->new_extents = (ah->new_extents / ah->area_multiple) * ah->area_multiple;
log_debug("Adjusted allocation request to %" PRIu32 " data extents.", ah->new_extents);
}
}
for (s = 0; s < alloc_count; s++)
@ -3813,7 +3815,7 @@ static int _lvresize_adjust_extents(struct cmd_context *cmd, struct logical_volu
{
struct volume_group *vg = lv->vg;
uint32_t pv_extent_count;
uint32_t extents_used;
uint32_t extents_used, extents;
uint32_t seg_stripes = 0, seg_stripesize = 0, seg_size;
uint32_t seg_mirrors = 0;
struct lv_segment *seg, *uninitialized_var(mirr_seg);
@ -3825,24 +3827,24 @@ static int _lvresize_adjust_extents(struct cmd_context *cmd, struct logical_volu
/* If percent options were used, convert them into actual numbers of extents */
switch (lp->percent) {
case PERCENT_VG:
lp->extents = percent_of_extents(lp->extents, vg->extent_count,
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,
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,
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,
extents = percent_of_extents(lp->extents, pv_extent_count,
(lp->sign != SIGN_MINUS));
} else
lp->extents = percent_of_extents(lp->extents, vg->extent_count,
extents = percent_of_extents(lp->extents, vg->extent_count,
(lp->sign != SIGN_MINUS));
break;
case PERCENT_ORIGIN:
@ -3850,13 +3852,22 @@ static int _lvresize_adjust_extents(struct cmd_context *cmd, struct logical_volu
log_error("Specified LV does not have an origin LV.");
return 0;
}
lp->extents = percent_of_extents(lp->extents, origin_from_cow(lv)->le_count,
extents = percent_of_extents(lp->extents, origin_from_cow(lv)->le_count,
(lp->sign != SIGN_MINUS));
break;
case PERCENT_NONE:
extents = lp->extents;
break;
}
if (lp->percent != PERCENT_NONE) {
log_verbose("Converted %" PRIu32 "%%%s into %" PRIu32 " extents.", lp->extents, get_percent_string(lp->percent), extents);
lp->extents = extents;
if (lp->sign == SIGN_NONE && (lp->percent != PERCENT_LV && lp->percent != PERCENT_ORIGIN))
lp->approx_alloc = 1;
/* FIXME Adjust for parallel areas here before processing relative allocations */
}
if (lp->sign == SIGN_PLUS) {
if (lp->extents >= (MAX_EXTENT_COUNT - lv->le_count)) {
log_error("Unable to extend %s by %u extents, exceeds limit (%u).",
@ -4213,7 +4224,7 @@ static struct logical_volume *_lvresize_volume(struct cmd_context *cmd,
lp->stripes, lp->stripe_size,
lp->mirrors, first_seg(lv)->region_size,
lp->extents - lv->le_count, NULL,
pvh, alloc, 0))
pvh, alloc, lp->approx_alloc))
return_NULL;
if (lock_lv) {

View File

@ -484,6 +484,7 @@ struct lvresize_params {
uint64_t poolmetadatasize;
sign_t poolmetadatasign;
uint32_t poolmetadataextents;
int approx_alloc;
percent_type_t percent;
enum {

View File

@ -223,14 +223,17 @@ is specified.
.TP
.IR \fB\-l ", " \fB\-\-extents " " LogicalExtentsNumber [ % { VG | PVS | FREE | ORIGIN }]
Gives the number of logical extents to allocate for the new
logical volume.
logical volume. The total number of physical extents allocated will be
greater than this, for example, if the volume is mirrored.
The number can also be expressed as a percentage of the total space
in the Volume Group with the suffix \fI%VG\fR, as a percentage of the
remaining free space in the Volume Group with the suffix \fI%FREE\fR, as a
percentage of the remaining free space for the specified
PhysicalVolume(s) with the suffix \fI%PVS\fR, or (for a snapshot) as a
percentage of the total space in the Origin Logical Volume with the
suffix \fI%ORIGIN\fR.
suffix \fI%ORIGIN\fR. When expressed as a percentage, the number is treated
as an approximate upper limit for the total number of physical extents
to be allocated (including extents used by any mirrors, for example).
.TP
.IR \fB\-L ", " \fB\-\-size " " LogicalVolumeSize [ bBsSkKmMgGtTpPeE ]
Gives the size to allocate for the new logical volume.

View File

@ -45,6 +45,8 @@ Proceed with size extension without prompting.
Extend or set the logical volume size in units of logical extents.
With the '\fI+\fP' sign the value is added to the actual size
of the logical volume and without it, the value is taken as an absolute one.
The total number of physical extents allocated will be
greater than this, for example, if the volume is mirrored.
The number can also be expressed as a percentage of the total space
in the Volume Group with the suffix \fI%VG\fP, relative to the existing
size of the Logical Volume with the suffix \fI%LV\fP, of the remaining
@ -53,6 +55,11 @@ 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 upward.
N.B. In a future release, when expressed as a percentage with PVS, VG or FREE,
the number will be treated as an approximate upper limit for the total number
of physical extents to be allocated (including extents used by any mirrors, for
example). The code may currently allocate more space than you might otherwise
expect.
.TP
.IR \fB\-L ", " \fB\-\-size " [" + ] LogicalVolumeSize [ bBsSkKmMgGtTpPeE ]
Extend or set the logical volume size in units of megabytes.

View File

@ -51,6 +51,8 @@ Reduce or set the logical volume size in units of logical extents.
With the \fI-\fP sign the value will be subtracted from
the logical volume's actual size and without it the value will be taken
as an absolute size.
The total number of physical extents freed will be greater than this logical
value if, for example, the volume is mirrored.
The number can also be expressed as a percentage of the total space
in the Volume Group with the suffix \fI%VG\fP, relative to the existing
size of the Logical Volume with the suffix \fI%LV\fP, as a percentage of the
@ -59,6 +61,10 @@ 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 subtraction is rounded downward, for the absolute
size it is rounded upward.
N.B. In a future release, when expressed as a percentage with VG or FREE, the
number will be treated as an approximate total number of physical extents to be
freed (including extents used by any mirrors, for example). The code may
currently release more space than you might otherwise expect.
.TP
.IR \fB\-L ", " \fB\-\-size " [" \- ] LogicalVolumeSize [ bBsSkKmMgGtTpPeE ]
Reduce or set the logical volume size in units of megabytes.

View File

@ -49,6 +49,8 @@ Resize underlying filesystem together with the logical volume using
Change or set the logical volume size in units of logical extents.
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.
The total number of physical extents affected will be
greater than this if, for example, the volume is mirrored.
The number can also be expressed as a percentage of the total space
in the Volume Group with the suffix \fI%VG\fP, relative to the existing
size of the Logical Volume with the suffix \fI%LV\fP, as a percentage of
@ -58,6 +60,11 @@ 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 subtraction otherwise
it is rounded upward.
N.B. In a future release, when expressed as a percentage with PVS, VG or FREE,
the number will be treated as an approximate total number of physical extents
to be allocated or freed (including extents used by any mirrors, for example).
The code may currently allocate or remove more space than you might otherwise
expect.
.TP
.IR \fB\-L ", " \fB\-\-size " [" + | - ] LogicalVolumeSize [ bBsSkKmMgGtTpPeE ]
Change or set the logical volume size in units of megabytes.

View File

@ -400,6 +400,7 @@ static int _update_extents_params(struct volume_group *vg,
}
if (lcp->percent) {
/* FIXME Don't do the adjustment for parallel allocation with PERCENT_ORIGIN! */
lp->approx_alloc = 1;
log_verbose("Converted %" PRIu32 "%%%s into %" PRIu32 " extents.", lp->extents, get_percent_string(lcp->percent), extents);
lp->extents = extents;