[lvm-devel] master - allocation: improve approx alloc with resize
Alasdair Kergon
agk at fedoraproject.org
Mon Feb 24 22:51:12 UTC 2014
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=b359b86f88642888116d54d4204d367664fbdcf5
Commit: b359b86f88642888116d54d4204d367664fbdcf5
Parent: 80831438220f0ee8b88d2c8c25fab131bf619f5b
Author: Alasdair G Kergon <agk at redhat.com>
AuthorDate: Mon Feb 24 22:48:23 2014 +0000
Committer: Alasdair G Kergon <agk at redhat.com>
CommitterDate: Mon Feb 24 22:48:23 2014 +0000
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.
---
lib/metadata/lv_manip.c | 33 ++++++++++++++++++++++-----------
lib/metadata/metadata-exported.h | 1 +
man/lvcreate.8.in | 7 +++++--
man/lvextend.8.in | 7 +++++++
man/lvreduce.8.in | 6 ++++++
man/lvresize.8.in | 7 +++++++
tools/lvcreate.c | 1 +
7 files changed, 49 insertions(+), 13 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 92e65ae..c4b644c 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -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) {
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 3e57113..87e6046 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -484,6 +484,7 @@ struct lvresize_params {
uint64_t poolmetadatasize;
sign_t poolmetadatasign;
uint32_t poolmetadataextents;
+ int approx_alloc;
percent_type_t percent;
enum {
diff --git a/man/lvcreate.8.in b/man/lvcreate.8.in
index 682ff3a..c449eb1 100644
--- a/man/lvcreate.8.in
+++ b/man/lvcreate.8.in
@@ -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.
diff --git a/man/lvextend.8.in b/man/lvextend.8.in
index c51a9dc..d9bc0c8 100644
--- a/man/lvextend.8.in
+++ b/man/lvextend.8.in
@@ -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.
diff --git a/man/lvreduce.8.in b/man/lvreduce.8.in
index 2c38f5b..2b0f3f8 100644
--- a/man/lvreduce.8.in
+++ b/man/lvreduce.8.in
@@ -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.
diff --git a/man/lvresize.8.in b/man/lvresize.8.in
index 3606762..14fc7ba 100644
--- a/man/lvresize.8.in
+++ b/man/lvresize.8.in
@@ -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.
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 19df387..7d9d22e 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -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;
More information about the lvm-devel
mailing list