diff --git a/HACKING b/HACKING
index 3f2d29fa..28d5cb47 100644
--- a/HACKING
+++ b/HACKING
@@ -24,10 +24,15 @@ partition usage and unallocated space
=====================================
After addressing bug #499202 GParted now also displays unallocated space
-as well as used and unused space for recognised file systems. The
-unallocated space is shown graphically and the numeric figure is shown
-in the Information Dialog if it is greater than zero. Additionally a
-warning is reported if the unallocated space is considered too much.
+as well as used and unused space for recognised file systems. Many file
+systems which actually fill their partition report a small amount of
+intrinsic unallocated space when mounted, but not when unmounted. To
+avoid confusing the user and unnecessarily alarming them don't show
+unallocated space below a threshold, 2 to 5% depending on partition
+size. It is just included in the used figure instead. (This is
+effectively how GParted behaved before bug #499202 was addressed). When
+above the threshold unallocated space is shown graphically, the numeric
+figure is shown in the Information Dialog and a is warning displayed.
See the code and commit messages for more details.
Worked example of partition and file system usage for a newly created
@@ -54,8 +59,14 @@ used = fs_size - fs_free = 407128 - 406808 = 320 = 160.00 KiB
unused = fs_free = 406808 = 198.64 MiB
unallocated = ptn_size - fs_size = 409600 - 407128 = 2472 = 1.21 MiB
+ (Threshold %age for 200 MiB partition is approximately 4.675%)
+threshold = ptn_size * pct = 19150 = 9.35 MiB
+
+ (Unallocated is below threshold so is included in used figure)
+disp_used = used + unallocated = 320 + 2472 = 2792 = 1.36 MiB
+disp_unused = unused = 406808 = 198.64 MiB
+
Figures displayed in the Information dialog:
Size: 200.00 MiB
-Used: 160.00 KiB ( 0% )
-Unused: 198.64 MiB ( 99% )
-Unallocated: 1.21 MiB ( 1% )
+Used: 1.36 MiB ( 1% )
+Unused: 198.64 KiB ( 99% )
diff --git a/include/Partition.h b/include/Partition.h
index 374e73f3..6c663ff6 100644
--- a/include/Partition.h
+++ b/include/Partition.h
@@ -73,8 +73,11 @@ public:
bool busy ) ;
void set_sector_usage( Sector sectors_fs_size, Sector sectors_fs_unused ) ;
- bool significant_unallocated_space() const ;
+ bool sector_usage_known() const ;
Sector estimated_min_size() const ;
+ Sector get_sectors_used() const ;
+ Sector get_sectors_unused() const ;
+ Sector get_sectors_unallocated() const ;
void Set_Unallocated( const Glib::ustring & device_path,
Sector sector_start,
@@ -116,6 +119,7 @@ public:
Sector sectors_used;
Sector sectors_unused;
Sector sectors_unallocated; //Difference between the size of the partition and the file system
+ Sector significant_threshold; //Threshold from intrinsic to significant unallocated sectors
Gdk::Color color;
bool inside_extended;
bool busy;
@@ -131,7 +135,7 @@ public:
private:
void sort_paths_and_remove_duplicates() ;
- Sector get_significant_unallocated_sectors() const ;
+ Sector calc_significant_unallocated_sectors() const ;
static bool compare_paths( const Glib::ustring & A, const Glib::ustring & B ) ;
diff --git a/src/Dialog_Partition_Info.cc b/src/Dialog_Partition_Info.cc
index fdd9a74f..5d4b8a87 100644
--- a/src/Dialog_Partition_Info.cc
+++ b/src/Dialog_Partition_Info.cc
@@ -136,10 +136,10 @@ void Dialog_Partition_Info::init_drawingarea()
unused = 0 ;
unallocated = 400 - BORDER *2 ;
}
- else if ( partition .sectors_used >= 0 && partition .sectors_unused >= 0 )
+ else if ( partition .sector_usage_known() )
{
- used = Utils::round( ( 400 - BORDER *2 ) / ( dlength / partition .sectors_used ) ) ;
- unused = Utils::round( ( 400 - BORDER *2 ) / ( dlength / partition .sectors_unused ) ) ;
+ used = Utils::round( ( 400 - BORDER *2 ) / ( dlength / partition .get_sectors_used() ) ) ;
+ unused = Utils::round( ( 400 - BORDER *2 ) / ( dlength / partition .get_sectors_unused() ) ) ;
unallocated = 400 - BORDER *2 - used - unused ;
}
else
@@ -202,11 +202,14 @@ void Dialog_Partition_Info::Display_Info()
top++, bottom++,
Gtk::FILL ) ;
- if ( partition.sectors_used != -1 )
+ if ( partition .sector_usage_known() )
{
+ Sector used = partition .get_sectors_used() ;
+ Sector unused = partition .get_sectors_unused() ;
+ Sector unallocated = partition .get_sectors_unallocated() ;
//calculate relative diskusage
- int percent_unused = Utils::round( partition .sectors_unused * 100.0 / ptn_sectors ) ;
- int percent_unallocated = Utils::round( partition .sectors_unallocated * 100.0 / ptn_sectors ) ;
+ int percent_unused = Utils::round( unused * 100.0 / ptn_sectors ) ;
+ int percent_unallocated = Utils::round( unallocated * 100.0 / ptn_sectors ) ;
int percent_used = 100 - percent_unallocated - percent_unused ;
//Used
@@ -214,7 +217,7 @@ void Dialog_Partition_Info::Display_Info()
0, 1,
top, bottom,
Gtk::FILL ) ;
- table ->attach( * Utils::mk_label( Utils::format_size( partition .sectors_used, partition .sector_size ), true, Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false, true ),
+ table ->attach( * Utils::mk_label( Utils::format_size( used, partition .sector_size ), true, Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false, true ),
1, 2,
top, bottom,
Gtk::FILL ) ;
@@ -228,7 +231,7 @@ void Dialog_Partition_Info::Display_Info()
0, 1,
top, bottom,
Gtk::FILL ) ;
- table ->attach( * Utils::mk_label( Utils::format_size( partition .sectors_unused, partition .sector_size ), true, Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false, true ),
+ table ->attach( * Utils::mk_label( Utils::format_size( unused, partition .sector_size ), true, Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false, true ),
1, 2,
top, bottom,
Gtk::FILL ) ;
@@ -238,13 +241,13 @@ void Dialog_Partition_Info::Display_Info()
Gtk::FILL ) ;
//unallocated
- if ( partition .sectors_unallocated > 0 )
+ if ( unallocated > 0 )
{
table ->attach( * Utils::mk_label( "" + Glib::ustring( _("Unallocated:") ) + "" ),
0, 1,
top, bottom,
Gtk::FILL ) ;
- table ->attach( * Utils::mk_label( Utils::format_size( partition .sectors_unallocated, partition .sector_size ), true, Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false, true ),
+ table ->attach( * Utils::mk_label( Utils::format_size( unallocated, partition .sector_size ), true, Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false, true ),
1, 2,
top, bottom,
Gtk::FILL ) ;
diff --git a/src/Dialog_Partition_Resize_Move.cc b/src/Dialog_Partition_Resize_Move.cc
index 85596a64..b88c53ee 100644
--- a/src/Dialog_Partition_Resize_Move.cc
+++ b/src/Dialog_Partition_Resize_Move.cc
@@ -63,7 +63,7 @@ void Dialog_Partition_Resize_Move::Set_Data( const Partition & selected_partitio
void Dialog_Partition_Resize_Move::Resize_Move_Normal( const std::vector & partitions )
{
//little bit of paranoia ;)
- if ( selected_partition .sectors_used == -1 &&
+ if ( ! selected_partition .sector_usage_known() &&
selected_partition .status != STAT_NEW &&
selected_partition .filesystem != FS_LINUX_SWAP )
fs .shrink = GParted::FS::NONE ;
diff --git a/src/DrawingAreaVisualDisk.cc b/src/DrawingAreaVisualDisk.cc
index 9d45fb66..6f58b057 100644
--- a/src/DrawingAreaVisualDisk.cc
+++ b/src/DrawingAreaVisualDisk.cc
@@ -108,20 +108,21 @@ void DrawingAreaVisualDisk::set_static_data( const std::vector & part
{
//Use sum_sectors as the denominator to calculate fraction_used and
// fraction_unallocated in case it doesn't equal partition_length.
- Sector sum_sectors = partitions[ t ] .sectors_used
- + partitions[ t ] .sectors_unused
- + partitions[ t ] .sectors_unallocated ;
- if ( partitions[ t ] .sectors_unallocated > 0 )
+ Sector used = partitions[ t ] .get_sectors_used() ;
+ Sector unused = partitions[ t ] .get_sectors_unused() ;
+ Sector unallocated = partitions[ t ] .get_sectors_unallocated() ;
+ Sector sum_sectors = used + unused + unallocated ;
+ if ( unallocated > 0 )
visual_partitions .back() .fraction_unallocated =
- partitions[ t ] .sectors_unallocated / static_cast( sum_sectors ) ;
+ unallocated / static_cast( sum_sectors ) ;
else
visual_partitions .back() .fraction_unallocated = 0.0 ;
//Calculate fraction used from free space so any hidden overhead is counted as used
- if ( partitions[ t ] .sectors_unused >= 0 )
+ if ( unused >= 0 )
visual_partitions .back() .fraction_used =
1.0 - visual_partitions .back() .fraction_unallocated
- - partitions[ t ] .sectors_unused / static_cast( sum_sectors ) ;
+ - unused / static_cast( sum_sectors ) ;
}
visual_partitions .back() .color = partitions[ t ] .color;
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index a6bc845d..b5b74234 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -604,6 +604,11 @@ bool GParted_Core::snap_to_alignment( const Device & device, Partition & partiti
return false ;
}
+ //FIXME: I think that this if condition should be impossible because Partition::set_sector_usage(),
+ // and ::set_used() and ::Set_Unused() before that, don't allow setting file usage figures to be
+ // larger than the partition size. A btrfs file system spanning muiltiple partitions will have
+ // usage figures larger than any single partition but the figures will won't be set because of
+ // the above reasoning. Confirm condition is impossible and consider removing this code.
if ( partition .get_sector_length() < partition .sectors_used )
{
error = String::ucompose(
@@ -1522,7 +1527,8 @@ void GParted_Core::set_used_sectors( std::vector & partitions )
}
}
- if ( partitions[ t ] .sectors_used == -1 )
+ Sector unallocated ;
+ if ( ! partitions[ t ] .sector_usage_known() )
{
temp = _("Unable to read the contents of this file system!") ;
temp += "\n" ;
@@ -1540,11 +1546,11 @@ void GParted_Core::set_used_sectors( std::vector & partitions )
}
partitions[ t ] .messages .push_back( temp ) ;
}
- else if ( partitions[ t ] .significant_unallocated_space() )
+ else if ( ( unallocated = partitions[ t ] .get_sectors_unallocated() ) > 0 )
{
/* 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 ) ) ;
+ Utils::format_size( unallocated, partitions[ t ] .sector_size ) ) ;
FS fs = get_fs( partitions[ t ] .filesystem ) ;
if ( fs .check != GParted::FS::NONE
&& fs .grow != GParted::FS::NONE )
diff --git a/src/Partition.cc b/src/Partition.cc
index d37d6f58..faf648ca 100644
--- a/src/Partition.cc
+++ b/src/Partition.cc
@@ -45,6 +45,7 @@ void Partition::Reset()
uuid .clear() ;
partition_number = sector_start = sector_end = sectors_used = sectors_unused = -1;
sectors_unallocated = 0 ;
+ significant_threshold = 1 ;
free_space_before = -1 ;
sector_size = 0 ;
color .set( "black" ) ;
@@ -90,9 +91,10 @@ void Partition::set_sector_usage( Sector sectors_fs_size, Sector sectors_fs_unus
&& 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 ;
+ sectors_used = sectors_fs_size - sectors_fs_unused ;
+ sectors_unused = sectors_fs_unused ;
+ sectors_unallocated = length - sectors_fs_size ;
+ significant_threshold = calc_significant_unallocated_sectors() ;
}
else if ( sectors_fs_size == -1 )
{
@@ -106,15 +108,14 @@ void Partition::set_sector_usage( Sector sectors_fs_size, Sector sectors_fs_unus
sectors_used = -1 ;
sectors_unused = -1 ;
}
- sectors_unallocated = 0 ;
+ sectors_unallocated = 0 ;
+ significant_threshold = 1 ;
}
}
-bool Partition::significant_unallocated_space() const
+bool Partition::sector_usage_known() const
{
- if ( get_sector_length() >= 0 && sectors_unallocated > 0 )
- return sectors_unallocated >= get_significant_unallocated_sectors() ;
- return false ;
+ return sectors_used >= 0 && sectors_unused >= 0 ;
}
Sector Partition::estimated_min_size() const
@@ -122,11 +123,45 @@ 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() ) ;
+ if ( sectors_used >= 0 )
+ return sectors_used + std::min( sectors_unallocated, significant_threshold ) ;
return -1 ;
}
+//Return user displayable used sectors.
+// Only add unallocated sectors up to the significant threshold to
+// account for any intrinsic unallocated sectors in the file system.
+// Above the threshold just return the used sectors figure.
+Sector Partition::get_sectors_used() const
+{
+ if ( sectors_used >= 0 )
+ {
+ if ( sectors_unallocated < significant_threshold )
+ return sectors_used + sectors_unallocated ;
+ else
+ return sectors_used ;
+ }
+ return -1 ;
+}
+
+//Return user displayable unused sectors.
+Sector Partition::get_sectors_unused() const
+{
+ return sectors_unused ;
+}
+
+//Return user displayable unallocated sectors.
+// Return zero below the significant unallocated sectors threshold, as
+// the figure has been added to the displayable used sectors. Above the
+// threshold just return the unallocated sectors figure.
+Sector Partition::get_sectors_unallocated() const
+{
+ if ( sectors_unallocated < significant_threshold )
+ return 0 ;
+ else
+ return sectors_unallocated ;
+}
+
void Partition::Set_Unallocated( const Glib::ustring & device_path,
Sector sector_start,
Sector sector_end,
@@ -297,19 +332,21 @@ bool Partition::compare_paths( const Glib::ustring & A, const Glib::ustring & B
// 5% , ptn size <= 100 MiB
// linear scaling from 5% down to 2%, 100 MiB < ptn size <= 1 GiB
// 2% , 1 GiB < ptn size
-Sector Partition::get_significant_unallocated_sectors() const
+Sector Partition::calc_significant_unallocated_sectors() const
{
const double HIGHER_UNALLOCATED_FRACTION = 0.05 ;
const double LOWER_UNALLOCATED_FRACTION = 0.02 ;
Sector length = get_sector_length() ;
Byte_Value byte_len = length * sector_size ;
+ Sector significant ;
+
if ( byte_len <= 0 )
{
- return 0 ;
+ significant = 1;
}
else if ( byte_len <= 100 * MEBIBYTE )
{
- return Utils::round( length * HIGHER_UNALLOCATED_FRACTION ) ;
+ significant = Utils::round( length * HIGHER_UNALLOCATED_FRACTION ) ;
}
else if ( byte_len <= 1 * GIBIBYTE )
{
@@ -317,12 +354,15 @@ Sector Partition::get_significant_unallocated_sectors() const
( byte_len - 100 * MEBIBYTE ) * ( HIGHER_UNALLOCATED_FRACTION - LOWER_UNALLOCATED_FRACTION ) /
( 1 * GIBIBYTE - 100 * MEBIBYTE ) +
LOWER_UNALLOCATED_FRACTION ;
- return Utils::round( length * fraction ) ;
+ significant = Utils::round( length * fraction ) ;
}
else
{
- return Utils::round( length * LOWER_UNALLOCATED_FRACTION ) ;
+ significant = Utils::round( length * LOWER_UNALLOCATED_FRACTION ) ;
}
+ if ( significant <= 1 )
+ significant = 1;
+ return significant ;
}
Partition::~Partition()
diff --git a/src/TreeView_Detail.cc b/src/TreeView_Detail.cc
index 8ca97359..a47bc7bf 100644
--- a/src/TreeView_Detail.cc
+++ b/src/TreeView_Detail.cc
@@ -190,12 +190,14 @@ void TreeView_Detail::create_row( const Gtk::TreeRow & treerow, const Partition
treerow[ treeview_detail_columns .size ] = Utils::format_size( partition .get_sector_length(), partition .sector_size ) ;
//used
+ Sector used = partition .get_sectors_used() ;
treerow[ treeview_detail_columns .used ] =
- partition .sectors_used == -1 ? "---" : Utils::format_size( partition .sectors_used, partition .sector_size ) ;
+ used == -1 ? "---" : Utils::format_size( used, partition .sector_size ) ;
//unused
+ Sector unused = partition .get_sectors_unused() ;
treerow[ treeview_detail_columns .unused ] =
- partition .sectors_unused == -1 ? "---" : Utils::format_size( partition .sectors_unused, partition .sector_size ) ;
+ unused == -1 ? "---" : Utils::format_size( unused, partition .sector_size ) ;
//flags
treerow[ treeview_detail_columns .flags ] =
diff --git a/src/Win_GParted.cc b/src/Win_GParted.cc
index 8c3be42a..d339e96c 100644
--- a/src/Win_GParted.cc
+++ b/src/Win_GParted.cc
@@ -969,7 +969,7 @@ void Win_GParted::set_valid_operations()
{
Byte_Value required_size ;
if ( copied_partition .filesystem == GParted::FS_XFS )
- required_size = copied_partition .sectors_used * copied_partition .sector_size;
+ required_size = copied_partition .estimated_min_size() * copied_partition .sector_size;
else
required_size = copied_partition .get_byte_length() ;