mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
Fix possible overflow of size if %FREE or %VG is used.
https://bugzilla.redhat.com/show_bug.cgi?id=737087
This commit is contained in:
parent
89880365fc
commit
b18e1fd50e
@ -1,5 +1,6 @@
|
||||
Version 2.02.89 -
|
||||
==================================
|
||||
Fix possible overflow of size if %FREE or %VG is used.
|
||||
Fix vgchange activation of snapshot with virtual origin.
|
||||
Activate virtual snapshot origin exclusively (only on local node in cluster).
|
||||
Fix lv_mirror_count to handle mirrored stripes properly.
|
||||
|
40
test/t-lvcreate-large.sh
Executable file
40
test/t-lvcreate-large.sh
Executable file
@ -0,0 +1,40 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2011 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing to use,
|
||||
# modify, copy, or redistribute it subject to the terms and conditions
|
||||
# of the GNU General Public License v.2.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# 'Exercise some lvcreate diagnostics'
|
||||
|
||||
. lib/test
|
||||
|
||||
aux prepare_vg 4
|
||||
|
||||
lvcreate -s -l 100%FREE -n $lv $vg --virtualsize 1024T
|
||||
|
||||
#FIXME this should be 1024T
|
||||
#check lv_field $vg/$lv size "128.00m"
|
||||
|
||||
aux lvmconf 'devices/filter = [ "a/dev\/mapper\/.*$/", "a/dev\/LVMTEST/", "r/.*/" ]'
|
||||
|
||||
pvcreate $DM_DEV_DIR/$vg/$lv
|
||||
vgcreate $vg1 $DM_DEV_DIR/$vg/$lv
|
||||
|
||||
lvcreate -l 100%FREE -n $lv1 $vg1
|
||||
check lv_field $vg1/$lv1 size "1024.00t"
|
||||
lvresize -f -l 72%VG $vg1/$lv1
|
||||
check lv_field $vg1/$lv1 size "737.28t"
|
||||
lvremove -ff $vg1/$lv1
|
||||
|
||||
lvcreate -l 100%VG -n $lv1 $vg1
|
||||
check lv_field $vg1/$lv1 size "1024.00t"
|
||||
lvresize -f -l 72%VG $vg1/$lv1
|
||||
check lv_field $vg1/$lv1 size "737.28t"
|
||||
lvremove -ff $vg1/$lv1
|
||||
|
||||
lvremove -ff $vg/$lv
|
@ -250,17 +250,17 @@ static int _update_extents_params(struct volume_group *vg,
|
||||
|
||||
switch(lcp->percent) {
|
||||
case PERCENT_VG:
|
||||
lp->extents = lp->extents * vg->extent_count / 100;
|
||||
lp->extents = percent_of_extents(lp->extents, vg->extent_count);
|
||||
break;
|
||||
case PERCENT_FREE:
|
||||
lp->extents = lp->extents * vg->free_count / 100;
|
||||
lp->extents = percent_of_extents(lp->extents, vg->free_count);
|
||||
break;
|
||||
case PERCENT_PVS:
|
||||
if (!lcp->pv_count)
|
||||
lp->extents = lp->extents * vg->extent_count / 100;
|
||||
lp->extents = percent_of_extents(lp->extents, vg->extent_count);
|
||||
else {
|
||||
pv_extent_count = pv_list_extents_free(lp->pvh);
|
||||
lp->extents = lp->extents * pv_extent_count / 100;
|
||||
lp->extents = percent_of_extents(lp->extents, pv_extent_count);
|
||||
}
|
||||
break;
|
||||
case PERCENT_LV:
|
||||
@ -278,7 +278,7 @@ static int _update_extents_params(struct volume_group *vg,
|
||||
log_error(INTERNAL_ERROR "Couldn't find origin volume.");
|
||||
return 0;
|
||||
}
|
||||
lp->extents = lp->extents * origin->le_count / 100;
|
||||
lp->extents = percent_of_extents(lp->extents, origin->le_count);
|
||||
break;
|
||||
case PERCENT_NONE:
|
||||
break;
|
||||
|
@ -433,27 +433,27 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
|
||||
|
||||
switch(lp->percent) {
|
||||
case PERCENT_VG:
|
||||
lp->extents = lp->extents * vg->extent_count / 100;
|
||||
lp->extents = percent_of_extents(lp->extents, vg->extent_count);
|
||||
break;
|
||||
case PERCENT_FREE:
|
||||
lp->extents = lp->extents * vg->free_count / 100;
|
||||
lp->extents = percent_of_extents(lp->extents, vg->free_count);
|
||||
break;
|
||||
case PERCENT_LV:
|
||||
lp->extents = lp->extents * lv->le_count / 100;
|
||||
lp->extents = percent_of_extents(lp->extents, lv->le_count);
|
||||
break;
|
||||
case PERCENT_PVS:
|
||||
if (lp->argc) {
|
||||
pv_extent_count = pv_list_extents_free(pvh);
|
||||
lp->extents = lp->extents * pv_extent_count / 100;
|
||||
lp->extents = percent_of_extents(lp->extents, pv_extent_count);
|
||||
} else
|
||||
lp->extents = lp->extents * vg->extent_count / 100;
|
||||
lp->extents = percent_of_extents(lp->extents, vg->extent_count);
|
||||
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 = lp->extents * origin_from_cow(lv)->le_count / 100;
|
||||
lp->extents = percent_of_extents(lp->extents, origin_from_cow(lv)->le_count);
|
||||
break;
|
||||
case PERCENT_NONE:
|
||||
break;
|
||||
|
@ -1623,3 +1623,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 (uint32_t)((uint64_t)percents * (uint64_t)count / 100);
|
||||
}
|
||||
|
@ -181,4 +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);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user