diff --git a/include/Partition.h b/include/Partition.h index 0b49855a..374e73f3 100644 --- a/include/Partition.h +++ b/include/Partition.h @@ -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 ) ; diff --git a/src/Dialog_Partition_Copy.cc b/src/Dialog_Partition_Copy.cc index ed4179be..d46267e7 100644 --- a/src/Dialog_Partition_Copy.cc +++ b/src/Dialog_Partition_Copy.cc @@ -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 ; diff --git a/src/Dialog_Partition_Resize_Move.cc b/src/Dialog_Partition_Resize_Move.cc index 64430904..85596a64 100644 --- a/src/Dialog_Partition_Resize_Move.cc +++ b/src/Dialog_Partition_Resize_Move.cc @@ -148,14 +148,15 @@ void Dialog_Partition_Resize_Move::Resize_Move_Normal( const std::vectorset_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 ) diff --git a/src/Partition.cc b/src/Partition.cc index 2fd1b6dd..c7631619 100644 --- a/src/Partition.cc +++ b/src/Partition.cc @@ -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() { }