2005-04-20 00:52:35 +04:00
/*
* Copyright ( C ) 2003 Sistina Software , Inc . All rights reserved .
2007-08-21 00:55:30 +04:00
* Copyright ( C ) 2004 - 2006 Red Hat , Inc . All rights reserved .
2005-04-20 00:52:35 +04:00
*
* This file is part of LVM2 .
*
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
2007-08-21 00:55:30 +04:00
* of the GNU Lesser General Public License v .2 .1 .
2005-04-20 00:52:35 +04:00
*
2007-08-21 00:55:30 +04:00
* You should have received a copy of the GNU Lesser General Public License
2005-04-20 00:52:35 +04:00
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
# include "lib.h"
# include "metadata.h"
# include "pv_alloc.h"
2005-05-03 21:28:23 +04:00
# include "toolcontext.h"
2007-08-31 00:30:41 +04:00
# include "locking.h"
2011-04-13 01:59:01 +04:00
# include "defaults.h"
2005-04-20 00:52:35 +04:00
2005-10-17 03:03:59 +04:00
static struct pv_segment * _alloc_pv_segment ( struct dm_pool * mem ,
2005-04-20 00:52:35 +04:00
struct physical_volume * pv ,
2005-05-03 21:28:23 +04:00
uint32_t pe , uint32_t len ,
struct lv_segment * lvseg ,
uint32_t lv_area )
2005-04-20 00:52:35 +04:00
{
struct pv_segment * peg ;
2005-10-17 03:03:59 +04:00
if ( ! ( peg = dm_pool_zalloc ( mem , sizeof ( * peg ) ) ) ) {
2005-04-20 00:52:35 +04:00
log_error ( " pv_segment allocation failed " ) ;
return NULL ;
}
peg - > pv = pv ;
peg - > pe = pe ;
peg - > len = len ;
2005-05-03 21:28:23 +04:00
peg - > lvseg = lvseg ;
peg - > lv_area = lv_area ;
2005-04-20 00:52:35 +04:00
2008-11-04 01:14:30 +03:00
dm_list_init ( & peg - > list ) ;
2005-04-20 00:52:35 +04:00
return peg ;
}
2005-10-17 03:03:59 +04:00
int alloc_pv_segment_whole_pv ( struct dm_pool * mem , struct physical_volume * pv )
2005-04-20 00:52:35 +04:00
{
2005-05-03 21:28:23 +04:00
struct pv_segment * peg ;
if ( ! pv - > pe_count )
return 1 ;
2005-04-20 00:52:35 +04:00
/* FIXME Cope with holes in PVs */
2008-01-30 16:19:47 +03:00
if ( ! ( peg = _alloc_pv_segment ( mem , pv , 0 , pv - > pe_count , NULL , 0 ) ) )
return_0 ;
2005-04-20 00:52:35 +04:00
2008-11-04 01:14:30 +03:00
dm_list_add ( & pv - > segments , & peg - > list ) ;
2005-04-20 00:52:35 +04:00
2005-05-03 21:28:23 +04:00
return 1 ;
2005-04-20 00:52:35 +04:00
}
2008-11-04 01:14:30 +03:00
int peg_dup ( struct dm_pool * mem , struct dm_list * peg_new , struct dm_list * peg_old )
2005-04-20 00:52:35 +04:00
{
struct pv_segment * peg , * pego ;
2008-11-04 01:14:30 +03:00
dm_list_init ( peg_new ) ;
2005-04-20 00:52:35 +04:00
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( pego , peg_old ) {
2005-04-20 00:52:35 +04:00
if ( ! ( peg = _alloc_pv_segment ( mem , pego - > pv , pego - > pe ,
2005-05-03 21:28:23 +04:00
pego - > len , pego - > lvseg ,
2008-01-30 16:19:47 +03:00
pego - > lv_area ) ) )
return_0 ;
2008-11-04 01:14:30 +03:00
dm_list_add ( peg_new , & peg - > list ) ;
2005-04-20 00:52:35 +04:00
}
return 1 ;
}
2010-03-31 21:21:40 +04:00
/* Find segment at a given physical extent in a PV */
static struct pv_segment * find_peg_by_pe ( const struct physical_volume * pv ,
uint32_t pe )
{
struct pv_segment * pvseg ;
/* search backwards to optimise mostly used last segment split */
dm_list_iterate_back_items ( pvseg , & pv - > segments )
if ( pe > = pvseg - > pe & & pe < pvseg - > pe + pvseg - > len )
return pvseg ;
return NULL ;
}
2005-05-03 21:28:23 +04:00
/*
* Split peg at given extent .
2010-03-31 21:22:26 +04:00
* Second part is always not allocated to a LV and returned .
2005-05-03 21:28:23 +04:00
*/
2010-03-31 21:23:18 +04:00
static struct pv_segment * _pv_split_segment ( struct dm_pool * mem ,
struct physical_volume * pv ,
2010-03-31 21:22:26 +04:00
struct pv_segment * peg ,
uint32_t pe )
2005-05-03 21:28:23 +04:00
{
struct pv_segment * peg_new ;
2010-03-31 21:23:18 +04:00
if ( ! ( peg_new = _alloc_pv_segment ( mem , peg - > pv , pe ,
2005-05-03 21:28:23 +04:00
peg - > len + peg - > pe - pe ,
2008-01-30 16:19:47 +03:00
NULL , 0 ) ) )
2010-03-31 21:22:26 +04:00
return_NULL ;
2005-05-03 21:28:23 +04:00
peg - > len = peg - > len - peg_new - > len ;
2008-11-04 01:14:30 +03:00
dm_list_add_h ( & peg - > list , & peg_new - > list ) ;
2005-05-03 21:28:23 +04:00
2005-07-12 23:40:59 +04:00
if ( peg - > lvseg ) {
peg - > pv - > pe_alloc_count - = peg_new - > len ;
peg - > lvseg - > lv - > vg - > free_count + = peg_new - > len ;
}
2010-03-31 21:22:26 +04:00
return peg_new ;
2005-05-03 21:28:23 +04:00
}
/*
* Ensure there is a PV segment boundary at the given extent .
*/
2010-03-31 21:23:18 +04:00
int pv_split_segment ( struct dm_pool * mem ,
struct physical_volume * pv , uint32_t pe ,
2010-03-31 21:22:26 +04:00
struct pv_segment * * pvseg_allocated )
2005-05-03 21:28:23 +04:00
{
2010-03-31 21:22:26 +04:00
struct pv_segment * pvseg , * pvseg_new = NULL ;
2005-05-03 21:28:23 +04:00
if ( pe = = pv - > pe_count )
2010-03-31 21:22:26 +04:00
goto out ;
2005-05-03 21:28:23 +04:00
2010-03-31 21:22:26 +04:00
if ( ! ( pvseg = find_peg_by_pe ( pv , pe ) ) ) {
2005-05-03 21:28:23 +04:00
log_error ( " Segment with extent % " PRIu32 " in PV %s not found " ,
2007-10-12 18:29:32 +04:00
pe , pv_dev_name ( pv ) ) ;
2005-05-03 21:28:23 +04:00
return 0 ;
}
/* This is a peg start already */
2010-03-31 21:22:26 +04:00
if ( pe = = pvseg - > pe ) {
pvseg_new = pvseg ;
goto out ;
}
2005-05-03 21:28:23 +04:00
2010-03-31 21:23:18 +04:00
if ( ! ( pvseg_new = _pv_split_segment ( mem , pv , pvseg , pe ) ) )
2008-01-30 16:19:47 +03:00
return_0 ;
2010-03-31 21:22:26 +04:00
out :
if ( pvseg_allocated )
* pvseg_allocated = pvseg_new ;
2005-05-03 21:28:23 +04:00
return 1 ;
}
2005-05-11 19:04:06 +04:00
static struct pv_segment null_pv_segment = {
2006-05-10 01:23:51 +04:00
. pv = NULL ,
. pe = 0 ,
2005-05-11 19:04:06 +04:00
} ;
2005-05-03 21:28:23 +04:00
struct pv_segment * assign_peg_to_lvseg ( struct physical_volume * pv ,
uint32_t pe , uint32_t area_len ,
struct lv_segment * seg ,
uint32_t area_num )
{
2010-03-31 21:22:26 +04:00
struct pv_segment * peg = NULL ;
2005-05-03 21:28:23 +04:00
2005-05-11 19:04:06 +04:00
/* Missing format1 PV */
if ( ! pv )
return & null_pv_segment ;
2010-03-31 21:23:18 +04:00
if ( ! pv_split_segment ( seg - > lv - > vg - > vgmem , pv , pe , & peg ) | |
! pv_split_segment ( seg - > lv - > vg - > vgmem , pv , pe + area_len , NULL ) )
2008-01-30 16:19:47 +03:00
return_NULL ;
2005-05-03 21:28:23 +04:00
2010-03-31 21:22:26 +04:00
if ( ! peg ) {
2005-05-03 21:28:23 +04:00
log_error ( " Missing PV segment on %s at %u. " ,
2007-10-12 18:29:32 +04:00
pv_dev_name ( pv ) , pe ) ;
2005-05-03 21:28:23 +04:00
return NULL ;
}
peg - > lvseg = seg ;
peg - > lv_area = area_num ;
2005-06-14 21:54:48 +04:00
peg - > pv - > pe_alloc_count + = area_len ;
peg - > lvseg - > lv - > vg - > free_count - = area_len ;
2005-05-03 21:28:23 +04:00
return peg ;
}
2012-06-27 23:07:04 +04:00
int discard_pv_segment ( struct pv_segment * peg , uint32_t discard_area_reduction )
2005-05-03 21:28:23 +04:00
{
2011-04-13 22:26:39 +04:00
uint64_t discard_offset_sectors ;
2011-04-13 01:59:01 +04:00
uint64_t pe_start = peg - > pv - > pe_start ;
2012-09-19 15:48:56 +04:00
char uuid [ 64 ] __attribute__ ( ( aligned ( 8 ) ) ) ;
2011-04-13 01:59:01 +04:00
2005-07-12 23:40:59 +04:00
if ( ! peg - > lvseg ) {
2012-06-27 23:07:04 +04:00
log_error ( " discard_pv_segment with unallocated segment: "
2007-10-12 18:29:32 +04:00
" %s PE % " PRIu32 , pv_dev_name ( peg - > pv ) , peg - > pe ) ;
2005-07-12 23:40:59 +04:00
return 0 ;
}
2005-06-01 20:51:55 +04:00
2011-04-13 01:59:01 +04:00
/*
* Only issue discards if enabled in lvm . conf and both
* the device and kernel ( > = 2.6 .35 ) supports discards .
*/
2013-03-05 20:00:43 +04:00
if ( ! find_config_tree_bool ( peg - > pv - > fmt - > cmd , devices_issue_discards_CFG ) )
2012-09-19 15:48:56 +04:00
return 1 ;
/* Missing PV? */
if ( is_missing_pv ( peg - > pv ) | | ! peg - > pv - > dev ) {
if ( ! id_write_format ( & peg - > pv - > id , uuid , sizeof ( uuid ) ) )
return_0 ;
log_verbose ( " Skipping discard on missing device with uuid %s. " , uuid ) ;
return 1 ;
}
if ( ! dev_discard_max_bytes ( peg - > pv - > fmt - > cmd - > sysfs_dir , peg - > pv - > dev ) | |
2012-06-27 23:07:04 +04:00
! dev_discard_granularity ( peg - > pv - > fmt - > cmd - > sysfs_dir , peg - > pv - > dev ) )
return 1 ;
discard_offset_sectors = ( peg - > pe + peg - > lvseg - > area_len - discard_area_reduction ) *
( uint64_t ) peg - > pv - > vg - > extent_size + pe_start ;
if ( ! discard_offset_sectors ) {
/*
* pe_start = 0 and the PV ' s first extent contains the label .
* Must skip past the first extent .
*/
discard_offset_sectors = peg - > pv - > vg - > extent_size ;
discard_area_reduction - - ;
}
2013-01-08 02:30:29 +04:00
log_debug_alloc ( " Discarding % " PRIu32 " extents offset % " PRIu64 " sectors on %s. " ,
discard_area_reduction , discard_offset_sectors , dev_name ( peg - > pv - > dev ) ) ;
2012-06-27 23:07:04 +04:00
if ( discard_area_reduction & &
! dev_discard_blocks ( peg - > pv - > dev , discard_offset_sectors < < SECTOR_SHIFT ,
discard_area_reduction * ( uint64_t ) peg - > pv - > vg - > extent_size * SECTOR_SIZE ) )
return_0 ;
return 1 ;
}
int release_pv_segment ( struct pv_segment * peg , uint32_t area_reduction )
{
if ( ! peg - > lvseg ) {
log_error ( " release_pv_segment with unallocated segment: "
" %s PE % " PRIu32 , pv_dev_name ( peg - > pv ) , peg - > pe ) ;
return 0 ;
2011-04-13 01:59:01 +04:00
}
2005-06-14 21:54:48 +04:00
if ( peg - > lvseg - > area_len = = area_reduction ) {
2005-07-12 23:40:59 +04:00
peg - > pv - > pe_alloc_count - = area_reduction ;
peg - > lvseg - > lv - > vg - > free_count + = area_reduction ;
2005-05-03 21:28:23 +04:00
peg - > lvseg = NULL ;
peg - > lv_area = 0 ;
/* FIXME merge free space */
return 1 ;
}
2010-03-31 21:23:18 +04:00
if ( ! pv_split_segment ( peg - > lvseg - > lv - > vg - > vgmem ,
peg - > pv , peg - > pe + peg - > lvseg - > area_len -
area_reduction , NULL ) )
2008-01-30 16:19:47 +03:00
return_0 ;
2005-05-03 21:28:23 +04:00
return 1 ;
}
/*
* Only for use by lv_segment merging routines .
*/
void merge_pv_segments ( struct pv_segment * peg1 , struct pv_segment * peg2 )
{
peg1 - > len + = peg2 - > len ;
2008-11-04 01:14:30 +03:00
dm_list_del ( & peg2 - > list ) ;
2005-05-03 21:28:23 +04:00
}
2007-09-21 01:39:08 +04:00
/*
* Calculate the overlap , in extents , between a struct pv_segment and
* a struct pe_range .
*/
2007-09-25 01:30:00 +04:00
static uint32_t _overlap_pe ( const struct pv_segment * pvseg ,
const struct pe_range * per )
2007-09-21 01:39:08 +04:00
{
uint32_t start ;
uint32_t end ;
start = max ( pvseg - > pe , per - > start ) ;
end = min ( pvseg - > pe + pvseg - > len , per - > start + per - > count ) ;
if ( end < start )
return 0 ;
else
return end - start ;
}
/*
* Returns : number of free PEs in a struct pv_list
*/
2008-11-04 01:14:30 +03:00
uint32_t pv_list_extents_free ( const struct dm_list * pvh )
2007-09-21 01:39:08 +04:00
{
struct pv_list * pvl ;
struct pe_range * per ;
uint32_t extents = 0 ;
struct pv_segment * pvseg ;
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( pvl , pvh ) {
dm_list_iterate_items ( per , pvl - > pe_ranges ) {
dm_list_iterate_items ( pvseg , & pvl - > pv - > segments ) {
2008-03-26 19:48:10 +03:00
if ( ! pvseg_is_allocated ( pvseg ) )
2007-09-21 01:39:08 +04:00
extents + = _overlap_pe ( pvseg , per ) ;
}
}
}
return extents ;
}
2005-05-03 21:28:23 +04:00
/*
* Check all pv_segments in VG for consistency
*/
int check_pv_segments ( struct volume_group * vg )
{
struct physical_volume * pv ;
struct pv_list * pvl ;
struct pv_segment * peg ;
unsigned s , segno ;
2005-06-01 20:51:55 +04:00
uint32_t start_pe , alloced ;
uint32_t pv_count = 0 , free_count = 0 , extent_count = 0 ;
2005-05-03 21:28:23 +04:00
int ret = 1 ;
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( pvl , & vg - > pvs ) {
2005-05-03 21:28:23 +04:00
pv = pvl - > pv ;
segno = 0 ;
start_pe = 0 ;
2005-06-01 20:51:55 +04:00
alloced = 0 ;
pv_count + + ;
2005-05-03 21:28:23 +04:00
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( peg , & pv - > segments ) {
2005-05-03 21:28:23 +04:00
s = peg - > lv_area ;
/* FIXME Remove this next line eventually */
2013-01-08 02:30:29 +04:00
log_debug_alloc ( " %s %u: %6u %6u: %s(%u:%u) " ,
pv_dev_name ( pv ) , segno + + , peg - > pe , peg - > len ,
peg - > lvseg ? peg - > lvseg - > lv - > name : " NULL " ,
peg - > lvseg ? peg - > lvseg - > le : 0 , s ) ;
2005-05-03 21:28:23 +04:00
/* FIXME Add details here on failure instead */
if ( start_pe ! = peg - > pe ) {
2005-06-01 20:51:55 +04:00
log_error ( " Gap in pvsegs: %u, %u " ,
2005-05-03 21:28:23 +04:00
start_pe , peg - > pe ) ;
ret = 0 ;
}
if ( peg - > lvseg ) {
2005-06-01 20:51:55 +04:00
if ( seg_type ( peg - > lvseg , s ) ! = AREA_PV ) {
log_error ( " Wrong lvseg area type " ) ;
2005-05-03 21:28:23 +04:00
ret = 0 ;
}
2005-06-01 20:51:55 +04:00
if ( seg_pvseg ( peg - > lvseg , s ) ! = peg ) {
log_error ( " Inconsistent pvseg pointers " ) ;
2005-05-03 21:28:23 +04:00
ret = 0 ;
}
if ( peg - > lvseg - > area_len ! = peg - > len ) {
2005-06-01 20:51:55 +04:00
log_error ( " Inconsistent length: %u %u " ,
2005-05-03 21:28:23 +04:00
peg - > len ,
peg - > lvseg - > area_len ) ;
ret = 0 ;
}
2005-06-01 20:51:55 +04:00
alloced + = peg - > len ;
2005-05-03 21:28:23 +04:00
}
start_pe + = peg - > len ;
}
2005-06-01 20:51:55 +04:00
if ( start_pe ! = pv - > pe_count ) {
log_error ( " PV segment pe_count mismatch: %u != %u " ,
start_pe , pv - > pe_count ) ;
ret = 0 ;
}
if ( alloced ! = pv - > pe_alloc_count ) {
log_error ( " PV segment pe_alloc_count mismatch: "
" %u != %u " , alloced , pv - > pe_alloc_count ) ;
ret = 0 ;
}
extent_count + = start_pe ;
free_count + = ( start_pe - alloced ) ;
}
if ( pv_count ! = vg - > pv_count ) {
log_error ( " PV segment VG pv_count mismatch: %u != %u " ,
pv_count , vg - > pv_count ) ;
ret = 0 ;
}
if ( free_count ! = vg - > free_count ) {
log_error ( " PV segment VG free_count mismatch: %u != %u " ,
free_count , vg - > free_count ) ;
ret = 0 ;
}
if ( extent_count ! = vg - > extent_count ) {
log_error ( " PV segment VG extent_count mismatch: %u != %u " ,
extent_count , vg - > extent_count ) ;
ret = 0 ;
2005-05-03 21:28:23 +04:00
}
return ret ;
}
2005-10-31 05:37:29 +03:00
2011-02-21 15:27:26 +03:00
static int _reduce_pv ( struct physical_volume * pv , struct volume_group * vg ,
uint32_t old_pe_count , uint32_t new_pe_count )
2005-10-31 05:37:29 +03:00
{
struct pv_segment * peg , * pegt ;
if ( new_pe_count < pv - > pe_alloc_count ) {
log_error ( " %s: cannot resize to % " PRIu32 " extents "
" as % " PRIu32 " are allocated. " ,
2007-10-12 18:29:32 +04:00
pv_dev_name ( pv ) , new_pe_count ,
2005-10-31 05:37:29 +03:00
pv - > pe_alloc_count ) ;
return 0 ;
}
/* Check PEs to be removed are not already allocated */
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( peg , & pv - > segments ) {
2005-10-31 05:37:29 +03:00
if ( peg - > pe + peg - > len < = new_pe_count )
continue ;
if ( peg - > lvseg ) {
log_error ( " %s: cannot resize to % " PRIu32 " extents as "
" later ones are allocated. " ,
2007-10-12 18:29:32 +04:00
pv_dev_name ( pv ) , new_pe_count ) ;
2005-10-31 05:37:29 +03:00
return 0 ;
}
}
2010-03-31 21:23:18 +04:00
if ( ! pv_split_segment ( vg - > vgmem , pv , new_pe_count , NULL ) )
2008-01-30 16:19:47 +03:00
return_0 ;
2005-10-31 05:37:29 +03:00
2008-11-04 01:14:30 +03:00
dm_list_iterate_items_safe ( peg , pegt , & pv - > segments ) {
2005-10-31 05:37:29 +03:00
if ( peg - > pe + peg - > len > new_pe_count )
2008-11-04 01:14:30 +03:00
dm_list_del ( & peg - > list ) ;
2005-10-31 05:37:29 +03:00
}
pv - > pe_count = new_pe_count ;
vg - > extent_count - = ( old_pe_count - new_pe_count ) ;
vg - > free_count - = ( old_pe_count - new_pe_count ) ;
return 1 ;
}
static int _extend_pv ( struct physical_volume * pv , struct volume_group * vg ,
2011-02-21 15:27:26 +03:00
uint32_t old_pe_count , uint32_t new_pe_count )
2005-10-31 05:37:29 +03:00
{
struct pv_segment * peg ;
if ( ( uint64_t ) new_pe_count * pv - > pe_size > pv - > size ) {
log_error ( " %s: cannot resize to % " PRIu32 " extents as there "
2007-10-12 18:29:32 +04:00
" is only room for % " PRIu64 " . " , pv_dev_name ( pv ) ,
2005-10-31 05:37:29 +03:00
new_pe_count , pv - > size / pv - > pe_size ) ;
return 0 ;
}
2012-03-02 01:49:32 +04:00
if ( ! ( peg = _alloc_pv_segment ( pv - > fmt - > cmd - > mem , pv ,
old_pe_count ,
new_pe_count - old_pe_count ,
NULL , 0 ) ) )
return_0 ;
2008-11-04 01:14:30 +03:00
dm_list_add ( & pv - > segments , & peg - > list ) ;
2005-10-31 05:37:29 +03:00
pv - > pe_count = new_pe_count ;
vg - > extent_count + = ( new_pe_count - old_pe_count ) ;
vg - > free_count + = ( new_pe_count - old_pe_count ) ;
return 1 ;
}
/*
* Resize a PV in a VG , adding or removing segments as needed .
* New size must fit within pv - > size .
*/
int pv_resize ( struct physical_volume * pv ,
struct volume_group * vg ,
2011-02-21 15:27:26 +03:00
uint64_t size )
2005-10-31 05:37:29 +03:00
{
2011-02-21 15:27:26 +03:00
uint32_t old_pe_count , new_pe_count = 0 ;
if ( size < pv_min_size ( ) ) {
2011-02-21 16:09:27 +03:00
log_error ( " Size must exceed minimum of % " PRIu64 " sectors on PV %s. " ,
2011-02-21 15:27:26 +03:00
pv_min_size ( ) , pv_dev_name ( pv ) ) ;
return 0 ;
2005-10-31 05:37:29 +03:00
}
2011-02-21 15:27:26 +03:00
if ( size < pv_pe_start ( pv ) ) {
log_error ( " Size must exceed physical extent start "
" of % " PRIu64 " sectors on PV %s. " ,
pv_pe_start ( pv ) , pv_dev_name ( pv ) ) ;
}
2005-10-31 05:37:29 +03:00
2011-02-21 15:27:26 +03:00
old_pe_count = pv - > pe_count ;
if ( ! pv - > fmt - > ops - > pv_resize ( pv - > fmt , pv , vg , size ) ) {
log_error ( " Format specific resize of PV %s failed. " ,
pv_dev_name ( pv ) ) ;
return 0 ;
}
/* pv->pe_count is 0 now! We need to recalculate! */
/* If there's a VG, calculate new PE count value. */
if ( vg ) {
/* FIXME: Maybe PE calculation should go into pv->fmt->resize?
( like it is for pv - > fmt - > setup ) */
if ( ! ( new_pe_count = pv_size ( pv ) / vg - > extent_size ) ) {
log_error ( " Size must leave space for at least one physical "
" extent of % " PRIu32 " sectors on PV %s. " ,
pv_pe_size ( pv ) , pv_dev_name ( pv ) ) ;
return 0 ;
}
2011-03-30 00:19:03 +04:00
if ( new_pe_count = = old_pe_count ) {
2011-02-21 15:27:26 +03:00
pv - > pe_count = old_pe_count ;
log_verbose ( " No change to size of physical volume %s. " ,
pv_dev_name ( pv ) ) ;
return 1 ;
}
log_verbose ( " Resizing physical volume %s from % " PRIu32
" to % " PRIu32 " extents. " ,
pv_dev_name ( pv ) , pv - > pe_count , new_pe_count ) ;
if ( new_pe_count > old_pe_count )
return _extend_pv ( pv , vg , old_pe_count , new_pe_count ) ;
else
return _reduce_pv ( pv , vg , old_pe_count , new_pe_count ) ;
}
return 1 ;
2005-10-31 05:37:29 +03:00
}