Enhance calculation of significant unallocated space (#499202)

Many file systems report differing percentages of unallocated space over
a range of sizes, as well differing figures using their own specific
tools or using statvfs() system call when mounted.

File systems reporting intrinsic unallocated space using their specific
tools are: jfs, lvm2 pv and ntfs.  LVM2 PV has the largest amount of
unallocated space with its default Physical Extent size of 4 MiB.  For a
100 MiB partition it has 4.0% unallocated space.

File systems reporting intrinsic unallocated space using the statvfs()
system call when mounted are: ext2/3/4, fat16/32, hfs, jfs, nilfs2,
ntfs, reiserfs, and xfs.  Xfs has the worst identified unallocated space
of ~4.7% in a 100 MiB partition.  Ext2/3 exhibit unusual behaviour by
reporting unallocated space of ~4.6% in a 100 MiB partition falling to a
constant percentage of ~1.8% for sizes of 1 GiB and above.

Update the calculation for used to estimate the maximum size of
intrinsic unallocated space.  Limit is now 5% for partitions smaller
than 100 MiB, 2% for partitions larger than 1 GiB and linear scaling of
the percentage between.  Will still get false unallocated space warnings
for mounted xfs file systems and lvm2 pvs smaller than 100 MiB.

Also add a short note and worked example calculation of unallocated
space to the HACKING file.

Bug #499202 - gparted does not see the difference if partition size
              differs from filesystem size
This commit is contained in:
Mike Fleetwood 2012-06-05 19:32:52 +01:00 committed by Curtis Gedak
parent 3737224028
commit b5c80f18a9
2 changed files with 72 additions and 7 deletions

42
HACKING
View file

@ -17,3 +17,45 @@ even when it's only one character. =)
Thanks,
Curtis
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.
See the code and commit messages for more details.
Worked example of partition and file system usage for a newly created
jfs file system in a 200 MiB partition reporting a small amount of
unallocated space:
# sfdisk -s /dev/sda9
204800
# echo dm | jfs_debugfs /dev/sda9 | egrep 'Block Size:|dn_mapsize:|dn_nfree:'
Aggregate Block Size: 4096
[1] dn_mapsize: 0x0000000c6cb [9] dn_agheigth: 0
[2] dn_nfree: 0x0000000c6a3 [10] dn_agwidth: 1
Partition size = 204800 (1K blocks) = 409600 (512 byte sectors)
FS size = 0x0c6cb (4K blocks)
= 50891 (4K blocks) = 407128 (512 byte sectors)
FS free = 0x0c6a3 (4K blocks)
= 50851 (4K blocks) = 406808 (512 byte sectors)
Calculation:
size = ptn_size = 409600 = 200.00 MiB
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
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% )

View file

@ -21,8 +21,6 @@
namespace GParted
{
#define SIGNIFICANT_UNALLOCATED_FRACTION 0.05
Partition::Partition()
{
Reset() ;
@ -293,13 +291,38 @@ bool Partition::compare_paths( const Glib::ustring & A, const Glib::ustring & B
}
//Return threshold of sectors which is considered above the intrinsic
// level for a file system which "fills" the partition.
// level for a file system which "fills" the partition. Calculation
// is:
// %age of partition size , when
// 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 length = get_sector_length() ;
if ( length >= 0 )
return Utils::round( length * SIGNIFICANT_UNALLOCATED_FRACTION ) ;
return 0 ;
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 ;
if ( byte_len <= 0 )
{
return 0 ;
}
else if ( byte_len <= 100 * MEBIBYTE )
{
return Utils::round( length * HIGHER_UNALLOCATED_FRACTION ) ;
}
else if ( byte_len <= 1 * GIBIBYTE )
{
double fraction = ( HIGHER_UNALLOCATED_FRACTION - LOWER_UNALLOCATED_FRACTION ) -
( byte_len - 100 * MEBIBYTE ) * ( HIGHER_UNALLOCATED_FRACTION - LOWER_UNALLOCATED_FRACTION ) /
( 1 * GIBIBYTE - 100 * MEBIBYTE ) +
LOWER_UNALLOCATED_FRACTION ;
return Utils::round( length * fraction ) ;
}
else
{
return Utils::round( length * LOWER_UNALLOCATED_FRACTION ) ;
}
}
Partition::~Partition()