Include intrinsic unallocated space for resizing purposes (#499202)

A number of file systems report intrinsic unallocated space even when
they are created filling the partition.  As reported using their own
specific tools, they are: jfs, lvm2 pv and ntfs.  Therefore when
resizing a partition estimate its minimum size to be used sectors plus
any unallocated sectors up to the significant amount.

Bug #499202 - gparted does not see the difference if partition size
              differs from filesystem size
This commit is contained in:
Mike Fleetwood 2012-06-02 20:02:09 +01:00 committed by Curtis Gedak
parent 7fc16a1b69
commit 3737224028
4 changed files with 32 additions and 10 deletions

View file

@ -74,6 +74,7 @@ public:
void set_sector_usage( Sector sectors_fs_size, Sector sectors_fs_unused ) ;
bool significant_unallocated_space() const ;
Sector estimated_min_size() const ;
void Set_Unallocated( const Glib::ustring & device_path,
Sector sector_start,
@ -130,6 +131,7 @@ public:
private:
void sort_paths_and_remove_duplicates() ;
Sector get_significant_unallocated_sectors() const ;
static bool compare_paths( const Glib::ustring & A, const Glib::ustring & B ) ;

View file

@ -56,9 +56,9 @@ void Dialog_Partition_Copy::Set_Data( const Partition & selected_partition, cons
frame_resizer_base ->set_x_start( Utils::round(MIN_SPACE_BEFORE_MB / MB_PER_PIXEL) ) ;
int x_end = Utils::round( (MIN_SPACE_BEFORE_MB + COPIED_LENGTH_MB) / ( TOTAL_MB/500.00 ) ) ; //> 500 px only possible with xfs...
frame_resizer_base ->set_x_end( x_end > 500 ? 500 : x_end ) ;
Sector min_resize = copied_partition .estimated_min_size() ;
frame_resizer_base ->set_used(
Utils::round( Utils::sector_to_unit(
copied_partition .sectors_used, copied_partition .sector_size, UNIT_MIB ) / (TOTAL_MB/500.00) ) ) ;
Utils::round( Utils::sector_to_unit( min_resize, copied_partition .sector_size, UNIT_MIB ) / (TOTAL_MB/500.00) ) ) ;
if ( fs .grow )
if ( ! fs .MAX || fs .MAX > ((TOTAL_MB - MIN_SPACE_BEFORE_MB) * MEBIBYTE) )
@ -70,7 +70,7 @@ void Dialog_Partition_Copy::Set_Data( const Partition & selected_partition, cons
//TODO: Since BUF is the cylinder size of the current device, the cylinder size of the copied device could differ for small disks
if ( fs .filesystem == GParted::FS_XFS ) //bit hackisch, but most effective, since it's a unique situation
fs .MIN = ( copied_partition .sectors_used + (BUF * 2) ) * copied_partition .sector_size;
fs .MIN = ( min_resize + (BUF * 2) ) * copied_partition .sector_size;
else
fs .MIN = COPIED_LENGTH_MB * MEBIBYTE ;

View file

@ -148,14 +148,15 @@ void Dialog_Partition_Resize_Move::Resize_Move_Normal( const std::vector<Partiti
frame_resizer_base ->set_x_start( Utils::round( previous / ( total_length / 500.00 ) ) ) ;
frame_resizer_base ->set_x_end(
Utils::round( selected_partition .get_sector_length() / ( total_length / 500.00 ) ) + frame_resizer_base ->get_x_start() ) ;
frame_resizer_base ->set_used( Utils::round( selected_partition.sectors_used / ( total_length / 500.00 ) ) ) ;
Sector min_resize = selected_partition .estimated_min_size() ;
frame_resizer_base ->set_used( Utils::round( min_resize / ( total_length / 500.00 ) ) ) ;
//set MIN
if ( fs .shrink )
{
//since some file systems have lower limits we need to check for this
if ( selected_partition .sectors_used > (fs .MIN / selected_partition .sector_size) )
fs .MIN = selected_partition .sectors_used * selected_partition .sector_size ;
if ( min_resize > (fs .MIN / selected_partition .sector_size) )
fs .MIN = min_resize * selected_partition .sector_size ;
//ensure that minimum size is at least one mebibyte
if ( ! fs .MIN || fs .MIN < MEBIBYTE )

View file

@ -21,7 +21,7 @@
namespace GParted
{
#define SIGNIFICANT_UNALLOCATED_PERCENTAGE 5.0
#define SIGNIFICANT_UNALLOCATED_FRACTION 0.05
Partition::Partition()
{
@ -114,12 +114,21 @@ void Partition::set_sector_usage( Sector sectors_fs_size, Sector sectors_fs_unus
bool Partition::significant_unallocated_space() const
{
Sector length = get_sector_length() ;
if ( sectors_unallocated > 0 && length > 0 )
return ( sectors_unallocated * 100.0 / length > SIGNIFICANT_UNALLOCATED_PERCENTAGE ) ;
if ( get_sector_length() >= 0 && sectors_unallocated > 0 )
return sectors_unallocated >= get_significant_unallocated_sectors() ;
return false ;
}
Sector Partition::estimated_min_size() const
{
//Add unallocated sectors up to the significant threshold, to
// account for any intrinsic unallocated sectors in the
// file systems minimum partition size.
if ( sectors_used > 0 )
return sectors_used + std::min( sectors_unallocated, get_significant_unallocated_sectors() ) ;
return -1 ;
}
void Partition::Set_Unallocated( const Glib::ustring & device_path,
Sector sector_start,
Sector sector_end,
@ -283,6 +292,16 @@ bool Partition::compare_paths( const Glib::ustring & A, const Glib::ustring & B
return A .length() < B .length() ;
}
//Return threshold of sectors which is considered above the intrinsic
// level for a file system which "fills" the partition.
Sector Partition::get_significant_unallocated_sectors() const
{
Sector length = get_sector_length() ;
if ( length >= 0 )
return Utils::round( length * SIGNIFICANT_UNALLOCATED_FRACTION ) ;
return 0 ;
}
Partition::~Partition()
{
}