[gparted] Record unallocated space within a partition (#499202)



commit 8093ba2ebd53b1e4ce869d5bf7cb7798238f28d6
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Tue Jan 10 14:13:41 2012 +0000

    Record unallocated space within a partition (#499202)
    
    Currently GParted assumes that a file system fills its containing
    partition.  This is not always true and can occur when resizing is
    performed outside of GParted or a resize operation fails.  GParted
    doesn't display any information about unallocated space to the user
    and in most cases it is simply included in used space.
    
    Add partition unallocated space accounting.  Make GParted record the
    unallocated space for mounted file system and display a warning in the
    Partition Information dialog when too much unallocated space is found.
    
    Partition::set_sector_usage( fs_size, fs_unused ), is the new preferred
    method of recording file system usage because it allows the unallocated
    space in a partition to be calculated.  Partition::Set_Unused() and
    Partition::set_used() are now deprecated.
    
    NOTES:
    
    1)  Set the minimum unallocated space to be 5% before considering it
        significant to avoid false reporting.  Worst case found was a
        mounted xfs file system in a 100MiB partition, which reports as
        ~4.7% unallocated according to file system size from statvfs().
        However, it reports as having no unallocated space using xfs
        specific tools.
    
    2)  Unallocated space is only a graphical representation for the user.
        GParted must still use relevant tools to resize file systems before
        shrinking the data and can't assume all unallocated space exists
        after the file system at the end of the partition.
    
    Bug #499202 - gparted does not see the difference if partition size
                  differs from filesystem size

 include/Partition.h |    6 +++---
 src/GParted_Core.cc |   30 +++++++++++++++++++++++++++++-
 src/Partition.cc    |   50 ++++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 80 insertions(+), 6 deletions(-)
---
diff --git a/include/Partition.h b/include/Partition.h
index 45f6432..4466175 100644
--- a/include/Partition.h
+++ b/include/Partition.h
@@ -51,9 +51,6 @@ enum PartitionAlignment {
 	                       //  Indicator if start and end sectors must remain unchanged
 };
 
-//FIXME: we should make a difference between partition- and file system size. 
-//especially in the core this can make a difference when giving detailed feedback. With new cairosupport in gtkmm
-//it's even possible to make stuff like this visible in the GUI in a nice and clear way
 class Partition
 {
 public:
@@ -77,6 +74,8 @@ public:
 
 	void Set_Unused( Sector sectors_unused ) ;
 	void set_used( Sector sectors_used ) ;
+	void set_sector_usage( Sector sectors_fs_size, Sector sectors_fs_unused ) ;
+	bool significant_unallocated_space() const ;
 
 	void Set_Unallocated( const Glib::ustring & device_path, 
 			      Sector sector_start,
@@ -117,6 +116,7 @@ public:
 	Sector sector_end;
 	Sector sectors_used;
 	Sector sectors_unused;
+	Sector sectors_unallocated;  //Difference between the size of the partition and the file system
 	Gdk::Color color;
 	bool inside_extended;
 	bool busy;
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index 9b9cdaf..e7492b3 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -1486,7 +1486,15 @@ void GParted_Core::set_used_sectors( std::vector<Partition> & partitions )
 					if ( partitions[ t ] .get_mountpoints() .size() > 0  )
 					{
 						if ( statvfs( partitions[ t ] .get_mountpoint() .c_str(), &sfs ) == 0 )
-							partitions[ t ] .Set_Unused( sfs .f_bfree * (sfs .f_bsize / partitions[ t ] .sector_size) ) ;
+						{
+							Sector fs_size = static_cast<Sector>( sfs .f_blocks ) *
+							                 sfs .f_frsize /
+							                 partitions[ t ] .sector_size ;
+							Sector fs_free = static_cast<Sector>( sfs .f_bfree ) *
+							                 sfs .f_bsize /
+							                 partitions[ t ] .sector_size ;
+							partitions[ t ] .set_sector_usage( fs_size, fs_free ) ;
+						}
 						else
 							partitions[ t ] .messages .push_back( 
 								"statvfs (" + 
@@ -1532,6 +1540,26 @@ void GParted_Core::set_used_sectors( std::vector<Partition> & partitions )
 					}
 					partitions[ t ] .messages .push_back( temp ) ;
 				}
+				else if ( partitions[ t ] .significant_unallocated_space() )
+				{
+					/* TO TRANSLATORS: looks like  1.28GiB of unallocated space within the partition. */
+					temp = String::ucompose( _("%1 of unallocated space within the partition."),
+					                         Utils::format_size( partitions[ t ] .sectors_unallocated, partitions[ t ] .sector_size ) ) ;
+					FS fs = get_fs( partitions[ t ] .filesystem ) ;
+					if (    fs .check != GParted::FS::NONE
+					     && fs .grow  != GParted::FS::NONE )
+					{
+						temp += "\n" ;
+						/* TO TRANSLATORS:  To grow the file system to fill the partition, select the partition and choose the menu item:
+						 * means that the user can perform a check of the partition which will
+						 * also grow the file system to fill the partition.
+						 */
+						temp += _("To grow the file system to fill the partition, select the partition and choose the menu item:") ;
+						temp += "\n" ;
+						temp += _("Partition --> Check.") ;
+					}
+					partitions[ t ] .messages .push_back( temp ) ;
+				}
 			}
 			else if ( partitions[ t ] .type == GParted::TYPE_EXTENDED )
 				set_used_sectors( partitions[ t ] .logicals ) ;
diff --git a/src/Partition.cc b/src/Partition.cc
index 620fdee..971a36e 100644
--- a/src/Partition.cc
+++ b/src/Partition.cc
@@ -20,7 +20,9 @@
 
 namespace GParted
 {
-	
+
+#define SIGNIFICANT_UNALLOCATED_PERCENTAGE 5.0
+
 Partition::Partition()
 {
 	Reset() ;
@@ -44,6 +46,7 @@ void Partition::Reset()
 	label .clear() ;
 	uuid .clear() ;
 	partition_number = sector_start = sector_end = sectors_used = sectors_unused = -1;
+	sectors_unallocated = 0 ;
 	free_space_before = -1 ;
 	sector_size = 0 ;
 	color .set( "black" ) ;
@@ -80,24 +83,67 @@ void Partition::Set(	const Glib::ustring & device_path,
 	this ->color .set( Utils::get_color( filesystem ) );
 }
 
+//Deprecated method of setting file system free space, which assumes
+//  the file system fills the partition.
 void Partition::Set_Unused( Sector sectors_unused )
 {
 	if ( sectors_unused <= get_sector_length() )
 	{
 		this ->sectors_unused = sectors_unused ;
 		this ->sectors_used = ( sectors_unused == -1 ) ? -1 : get_sector_length() - sectors_unused ;
+		this ->sectors_unallocated = 0 ;
 	}
 }
-	
+
+//Deprecated method of setting file system used space, which assumes
+//  the file system fills the partition.
 void Partition::set_used( Sector sectors_used ) 
 {
 	if ( sectors_used < get_sector_length() )
 	{
 		this ->sectors_used = sectors_used ;
 		this ->sectors_unused = ( sectors_used == -1 ) ? -1 : get_sector_length() - sectors_used ;
+		this ->sectors_unallocated = 0 ;
 	}
 }
 
+//Preferred method of setting file system size and free space, which also
+//  calculates unallocated space.  Set sectors_fs_size = -1 for unknown.
+void Partition::set_sector_usage( Sector sectors_fs_size, Sector sectors_fs_unused )
+{
+	Sector length = get_sector_length() ;
+	if (    0 <= sectors_fs_size   && sectors_fs_size   <= length
+	     && 0 <= sectors_fs_unused && sectors_fs_unused <= sectors_fs_size
+	   )
+	{
+		sectors_used        = sectors_fs_size - sectors_fs_unused ;
+		sectors_unused      = sectors_fs_unused ;
+		sectors_unallocated = length - sectors_fs_size ;
+	}
+	else if ( sectors_fs_size == -1 )
+	{
+		if ( 0 <= sectors_fs_unused && sectors_fs_unused <= length )
+		{
+			sectors_used   = length - sectors_fs_unused ;
+			sectors_unused = sectors_fs_unused ;
+		}
+		else
+		{
+			 sectors_used = -1 ;
+			 sectors_unused = -1 ;
+		}
+		sectors_unallocated = 0 ;
+	}
+}
+
+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 ) ;
+	return false ;
+}
+
 void Partition::Set_Unallocated( const Glib::ustring & device_path,
 				 Sector sector_start,
 				 Sector sector_end,



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