[gparted] Include intrinsic unallocated space for resizing purposes (#499202)



commit 3737224028cf0de93e5f278c1d1be05e4f137afa
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Sat Jun 2 20:02:09 2012 +0100

    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

 include/Partition.h                 |    2 ++
 src/Dialog_Partition_Copy.cc        |    6 +++---
 src/Dialog_Partition_Resize_Move.cc |    7 ++++---
 src/Partition.cc                    |   27 +++++++++++++++++++++++----
 4 files changed, 32 insertions(+), 10 deletions(-)
---
diff --git a/include/Partition.h b/include/Partition.h
index 0b49855..374e73f 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 ed4179b..d46267e 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 6443090..85596a6 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::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 )
diff --git a/src/Partition.cc b/src/Partition.cc
index 2fd1b6d..c763161 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()
 {
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]