Make mounted partition usage method selectable per file system (#683255)

Each file system class can now choose how the size and free space of the
file system is determined when it is mounted.

    .fs.online_read = FS::NONE  (default)
        Do nothing.  Don't get the file system size and free space.

    .fs.online_read = FS::GPARTED
        Use internal GParted method which calls statvfs() system call on
        the mounted file system.

    .fs.online_read = FS::EXTERNAL
        Call the file system's member function set_used_sectors().  This
        is the same function as called when the file system is not
        mounted.   It can determine if the file system is mounted or not
        by testing partition.busy and acting accordingly.

This means that determining the size and free space of active LVM2
Physical Volumes is no longer a special case.  Instead the lvm2_pv class
just elects to have its set_used_sectors() method called for both the
active and deactive cases.

Bug #683255 - ext2: statvfs differs from dumpe2fs (x MB unallocated
              space within the partition)
This commit is contained in:
Mike Fleetwood 2012-09-10 16:41:58 +01:00 committed by Curtis Gedak
parent e6365a79eb
commit 01150758c3
20 changed files with 70 additions and 32 deletions

View File

@ -85,6 +85,7 @@ private:
bool inside_extended ) ;
void set_mountpoints( std::vector<Partition> & partitions ) ;
void set_used_sectors( std::vector<Partition> & partitions ) ;
void mounted_set_used_sectors( Partition & partition ) ;
#ifdef HAVE_LIBPARTED_FS_RESIZE
void LP_set_used_sectors( Partition & partition );
#endif

View File

@ -118,7 +118,7 @@ struct FS
};
FILESYSTEM filesystem ;
Support read ; //can we get the amount of used sectors?
Support read ; //Can and how to read sector usage while inactive
Support read_label ;
Support write_label ;
Support read_uuid ;
@ -130,6 +130,7 @@ struct FS
Support check ; //some checktool available?
Support copy ;
Support remove ;
Support online_read ; //Can and how to read sector usage while active
Byte_Value MIN ;
Byte_Value MAX ;
@ -137,7 +138,7 @@ struct FS
FS()
{
read = read_label = write_label = read_uuid = write_uuid = create = grow = shrink =
move = check = copy = remove = NONE ;
move = check = copy = remove = online_read = NONE ;
MIN = MAX = 0 ;
}
} ;

View File

@ -1496,8 +1496,6 @@ void GParted_Core::set_mountpoints( std::vector<Partition> & partitions )
void GParted_Core::set_used_sectors( std::vector<Partition> & partitions )
{
struct statvfs sfs ;
for ( unsigned int t = 0 ; t < partitions .size() ; t++ )
{
if ( partitions[ t ] .filesystem != GParted::FS_LINUX_SWAP &&
@ -1508,26 +1506,20 @@ void GParted_Core::set_used_sectors( std::vector<Partition> & partitions )
if ( partitions[ t ] .type == GParted::TYPE_PRIMARY ||
partitions[ t ] .type == GParted::TYPE_LOGICAL )
{
if ( partitions[ t ] .busy && partitions[t] .filesystem != GParted::FS_LVM2_PV )
if ( partitions[ t ] .busy )
{
if ( partitions[ t ] .get_mountpoints() .size() > 0 )
switch( get_fs( partitions[ t ] .filesystem ) .online_read )
{
if ( statvfs( partitions[ t ] .get_mountpoint() .c_str(), &sfs ) == 0 )
{
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 (" +
partitions[ t ] .get_mountpoint() +
"): " +
Glib::strerror( errno ) ) ;
case FS::EXTERNAL:
if ( set_proper_filesystem( partitions[ t ] .filesystem ) )
p_filesystem ->set_used_sectors( partitions[ t ] ) ;
break ;
case FS::GPARTED:
mounted_set_used_sectors( partitions[ t ] ) ;
break ;
default:
break ;
}
}
else
@ -1603,6 +1595,24 @@ void GParted_Core::set_used_sectors( std::vector<Partition> & partitions )
}
}
void GParted_Core::mounted_set_used_sectors( Partition & partition )
{
struct statvfs sfs ;
if ( partition .get_mountpoints() .size() > 0 )
{
if ( statvfs( partition .get_mountpoint() .c_str(), &sfs ) == 0 )
{
Sector fs_size = static_cast<Sector>( sfs .f_blocks ) * sfs .f_frsize / partition .sector_size ;
Sector fs_free = static_cast<Sector>( sfs .f_bfree ) * sfs .f_bsize / partition .sector_size ;
partition .set_sector_usage( fs_size, fs_free ) ;
}
else
partition .messages .push_back( "statvfs (" + partition .get_mountpoint() + "): " +
Glib::strerror( errno ) ) ;
}
}
#ifdef HAVE_LIBPARTED_FS_RESIZE
void GParted_Core::LP_set_used_sectors( Partition & partition )
{

View File

@ -98,6 +98,8 @@ FS btrfs::get_filesystem_support()
fs .move = GParted::FS::GPARTED ;
}
fs .online_read = FS::GPARTED ;
fs .MIN = 256 * MEBIBYTE ;
//Linux before version 3.2 fails when resizing btrfs file system

View File

@ -29,6 +29,7 @@ FS exfat::get_filesystem_support()
fs .copy = FS::GPARTED ;
fs .move = FS::GPARTED ;
fs .online_read = FS::GPARTED ;
return fs ;
}

View File

@ -58,7 +58,9 @@ FS ext2::get_filesystem_support()
fs .copy = FS::GPARTED ;
fs .move = FS::GPARTED ;
}
fs .online_read = FS::GPARTED ;
return fs ;
}

View File

@ -59,7 +59,9 @@ FS ext3::get_filesystem_support()
fs .copy = GParted::FS::GPARTED ;
fs .move = GParted::FS::GPARTED ;
}
fs .online_read = FS::GPARTED ;
return fs ;
}

View File

@ -63,6 +63,8 @@ FS ext4::get_filesystem_support()
}
}
fs .online_read = FS::GPARTED ;
return fs ;
}

View File

@ -94,7 +94,8 @@ FS fat16::get_filesystem_support()
#endif
fs .copy = GParted::FS::GPARTED ;
fs .online_read = FS::GPARTED ;
fs .MIN = 16 * MEBIBYTE ;
fs .MAX = (4096 - 1) * MEBIBYTE ; //Maximum seems to be just less than 4096 MiB

View File

@ -82,7 +82,8 @@ FS fat32::get_filesystem_support()
#endif
fs .copy = GParted::FS::GPARTED ;
fs .online_read = FS::GPARTED ;
fs .MIN = 33 * MEBIBYTE ; //Smaller file systems will cause windows scandisk to fail.
return fs ;

View File

@ -44,7 +44,8 @@ FS hfs::get_filesystem_support()
fs .copy = GParted::FS::GPARTED ;
fs .move = GParted::FS::GPARTED ;
fs .online_read = FS::GPARTED ;
fs .MAX = 2048 * MEBIBYTE ;
return fs ;

View File

@ -44,7 +44,8 @@ FS hfsplus::get_filesystem_support()
fs .copy = GParted::FS::GPARTED ;
fs .move = GParted::FS::GPARTED ;
fs .online_read = FS::GPARTED ;
return fs ;
}

View File

@ -60,7 +60,9 @@ FS jfs::get_filesystem_support()
fs .move = GParted::FS::GPARTED ;
fs .copy = GParted::FS::GPARTED ;
}
fs .online_read = FS::GPARTED ;
fs .MIN = 16 * MEBIBYTE ;
return fs ;

View File

@ -60,6 +60,7 @@ FS lvm2_pv::get_filesystem_support()
fs .move = FS::GPARTED ;
fs .check = FS::EXTERNAL ;
fs .remove = FS::EXTERNAL ;
fs .online_read = FS::EXTERNAL ;
}
return fs ;

View File

@ -55,6 +55,7 @@ FS nilfs2::get_filesystem_support()
fs .copy = GParted::FS::GPARTED ;
fs .move = GParted::FS::GPARTED ;
fs .online_read = FS::GPARTED ;
//Minimum FS size is 128M+4K using mkfs.nilfs2 defaults
fs .MIN = 128 * MEBIBYTE + 4 * KIBIBYTE ;

View File

@ -102,7 +102,9 @@ FS ntfs::get_filesystem_support()
if ( fs .check )
fs .move = GParted::FS::GPARTED ;
fs .online_read = FS::GPARTED ;
return fs ;
}

View File

@ -45,7 +45,9 @@ FS reiser4::get_filesystem_support()
fs .copy = GParted::FS::GPARTED ;
fs .move = GParted::FS::GPARTED ;
}
fs .online_read = FS::GPARTED ;
/*
* IT SEEMS RESIZE AND COPY AREN'T IMPLEMENTED YET IN THE TOOLS...
* SEE http://marc.theaimsgroup.com/?t=109883161600003&r=1&w=2 for more information..

View File

@ -61,6 +61,8 @@ FS reiserfs::get_filesystem_support()
fs .move = GParted::FS::GPARTED ;
}
fs .online_read = FS::GPARTED ;
//Actual minimum is at least 18 blocks larger than 32 MiB for the journal offset
fs .MIN = 34 * MEBIBYTE ;

View File

@ -30,7 +30,8 @@ FS ufs::get_filesystem_support()
fs .copy = GParted::FS::GPARTED ;
fs .move = GParted::FS::GPARTED ;
fs .online_read = FS::GPARTED ;
return fs ;
}

View File

@ -68,6 +68,8 @@ FS xfs::get_filesystem_support()
if ( fs .check )
fs .move = GParted::FS::GPARTED ;
fs .online_read = FS::GPARTED ;
fs .MIN = 32 * MEBIBYTE ;//official minsize = 16MB, but the smallest xfs_repair can handle is 32MB...
return fs ;