Make partition busy detection method selectable per file system (#723842)

GParted's primary inbuilt busy detection method is "is the partition
mounted?".  A custom method is used for LVM2 PV because its not a
mounted file system.

Make busy detection selectable per file system type.

    .fs.busy = FS::NONE  (default)
        No busy detection.

    .fs.busy = FS::GPARTED
        Use internal GParted method which checks if the partition is
        mounted.

    .fs.busy = FS:EXTERNAL
        Call the file system type's member function is_busy().

LVM2 PV busy detection changes from a special case to just electing to
call the lvm2_pv::is_busy() method.  Linux Software RAID remains a
special case because it's only recognised, but not otherwise supported.

Bug #723842 - GParted resizes the wrong filesystem (does not pass the
              devid to btrfs filesystem resize)
This commit is contained in:
Mike Fleetwood 2014-02-15 01:26:32 +00:00 committed by Curtis Gedak
parent b1c64fdf0d
commit b1dc9e69e3
21 changed files with 95 additions and 29 deletions

View File

@ -38,6 +38,7 @@ public:
static const Glib::ustring get_generic_text( CUSTOM_TEXT ttype, int index = 0 ) ;
virtual FS get_filesystem_support() = 0 ;
virtual bool is_busy( const Glib::ustring & path ) { return false ; } ;
virtual void set_used_sectors( Partition & partition ) {};
virtual void read_label( Partition & partition ) {};
virtual bool write_label( const Partition & partition, OperationDetail & operationdetail ) { return false; };

View File

@ -86,6 +86,7 @@ private:
Byte_Value sector_size,
bool inside_extended ) ;
void set_mountpoints( std::vector<Partition> & partitions ) ;
bool is_busy( FILESYSTEM fstype, const Glib::ustring & path ) ;
void set_used_sectors( std::vector<Partition> & partitions, PedDisk* lp_disk ) ;
void mounted_set_used_sectors( Partition & partition ) ;
#ifdef HAVE_LIBPARTED_FS_RESIZE

View File

@ -124,6 +124,7 @@ struct FS
};
FILESYSTEM filesystem ;
Support busy ; //How to determine if partition/file system is busy
Support read ; //Can and how to read sector usage while inactive
Support read_label ;
Support write_label ;

View File

@ -28,6 +28,7 @@ class lvm2_pv : public FileSystem
public:
const Glib::ustring get_custom_text( CUSTOM_TEXT ttype, int index = 0 ) ;
FS get_filesystem_support() ;
bool is_busy( const Glib::ustring & path ) ;
void set_used_sectors( Partition & partition ) ;
bool create( const Partition & new_partition, OperationDetail & operationdetail ) ;
bool resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition = false ) ;

View File

@ -1010,7 +1010,6 @@ void GParted_Core::set_device_partitions( Device & device, PedDevice* lp_device,
#ifndef USE_LIBPARTED_DMRAID
DMRaid dmraid ; //Use cache of dmraid device information
#endif
LVM2_PV_Info lvm2_pv_info ;
//clear partitions
device .partitions .clear() ;
@ -1037,26 +1036,17 @@ void GParted_Core::set_device_partitions( Device & device, PedDevice* lp_device,
if ( dmraid .is_dmraid_device( device .get_path() ) )
{
//Try device_name + partition_number
iter_mp = mount_info .find( device .get_path() + Utils::num_to_str( lp_partition ->num ) ) ;
if ( iter_mp != mount_info .end() )
partition_is_busy = true ;
Glib::ustring dmraid_path = device .get_path() + Utils::num_to_str( lp_partition ->num ) ;
partition_is_busy = is_busy( filesystem, dmraid_path ) ;
//Try device_name + p + partition_number
iter_mp = mount_info .find( device .get_path() + "p" + Utils::num_to_str( lp_partition ->num ) ) ;
if ( iter_mp != mount_info .end() )
partition_is_busy = true ;
dmraid_path = device .get_path() + "p" + Utils::num_to_str( lp_partition ->num ) ;
partition_is_busy |= is_busy( filesystem, dmraid_path ) ;
}
else
#endif
{
//Determine if partition is busy:
// 1st search GParted internal mounted partitions map;
// 2nd custom checks for none file system partitions.
iter_mp = mount_info .find( partition_path ) ;
if ( iter_mp != mount_info .end() )
partition_is_busy = true ;
partition_is_busy |= ( filesystem == FS_LVM2_PV && lvm2_pv_info .has_active_lvs( partition_path ) )
|| ( filesystem == FS_LINUX_SWRAID && Utils::swraid_member_is_active( partition_path ) ) ;
partition_is_busy = is_busy( filesystem, partition_path ) ;
}
partition_temp .Set( device .get_path(),
@ -1564,7 +1554,49 @@ void GParted_Core::set_mountpoints( std::vector<Partition> & partitions )
}
}
}
//Report whether the partition is busy (mounted/active)
bool GParted_Core::is_busy( FILESYSTEM fstype, const Glib::ustring & path )
{
FileSystem * p_filesystem = NULL ;
bool busy = false ;
if ( fstype != FS_UNKNOWN &&
fstype != FS_BITLOCKER &&
fstype != FS_LUKS &&
fstype != FS_LINUX_SWRAID &&
fstype != FS_LINUX_SWSUSPEND
)
{
switch ( get_fs( fstype ) .busy )
{
case FS::GPARTED:
//Search GParted internal mounted partitions map
iter_mp = mount_info .find( path ) ;
if ( iter_mp != mount_info .end() )
busy = true ;
break ;
case FS::EXTERNAL:
//Call file system specific method
p_filesystem = get_filesystem_object( fstype ) ;
if ( p_filesystem )
busy = p_filesystem -> is_busy( path ) ;
break;
default:
break ;
}
}
else
{
//Custom checks for recognised but other not-supported file system types
busy = ( fstype == FS_LINUX_SWRAID && Utils::swraid_member_is_active( path ) ) ;
}
return busy ;
}
void GParted_Core::set_used_sectors( std::vector<Partition> & partitions, PedDisk* lp_disk )
{
for ( unsigned int t = 0 ; t < partitions .size() ; t++ )

View File

@ -31,6 +31,8 @@ FS btrfs::get_filesystem_support()
FS fs ;
fs .filesystem = GParted::FS_BTRFS ;
fs .busy = FS::GPARTED ;
if ( ! Glib::find_program_in_path( "mkfs.btrfs" ) .empty() )
{
fs .create = GParted::FS::EXTERNAL ;

View File

@ -23,9 +23,9 @@ namespace GParted
FS exfat::get_filesystem_support()
{
FS fs ;
fs .filesystem = FS_EXFAT ;
fs .busy = FS::GPARTED ;
fs .copy = FS::GPARTED ;
fs .move = FS::GPARTED ;
fs .online_read = FS::GPARTED ;

View File

@ -25,6 +25,8 @@ FS ext2::get_filesystem_support()
FS fs ;
fs .filesystem = specific_type;
fs .busy = FS::GPARTED ;
//Only enable any functionality if the relevant mkfs.extX command is
// found to ensure that the version of e2fsprogs is new enough to
// support ext4. Applying to ext2/3 too is OK as relevant mkfs.ext2/3

View File

@ -26,6 +26,8 @@ FS f2fs::get_filesystem_support()
fs .filesystem = FS_F2FS ;
fs .busy = FS::GPARTED ;
if ( ! Glib::find_program_in_path( "mkfs.f2fs" ) .empty() )
{
fs .create = GParted::FS::EXTERNAL ;

View File

@ -61,10 +61,12 @@ FS fat16::get_filesystem_support()
{
FS fs ;
fs .filesystem = specific_type ;
// hack to disable silly mtools warnings
setenv( "MTOOLS_SKIP_CHECK", "1", 0 );
fs .busy = FS::GPARTED ;
//find out if we can create fat file systems
if ( ! Glib::find_program_in_path( "mkfs.fat" ) .empty() )
{

View File

@ -24,9 +24,10 @@ namespace GParted
FS hfs::get_filesystem_support()
{
FS fs ;
fs .filesystem = GParted::FS_HFS ;
fs .busy = FS::GPARTED ;
#ifdef HAVE_LIBPARTED_FS_RESIZE
fs .read = GParted::FS::LIBPARTED ;
fs .shrink = GParted::FS::LIBPARTED ;

View File

@ -24,9 +24,10 @@ namespace GParted
FS hfsplus::get_filesystem_support()
{
FS fs ;
fs .filesystem = GParted::FS_HFSPLUS ;
fs .busy = FS::GPARTED ;
#ifdef HAVE_LIBPARTED_FS_RESIZE
fs .read = GParted::FS::LIBPARTED ;
fs .shrink = GParted::FS::LIBPARTED ;

View File

@ -25,7 +25,9 @@ FS jfs::get_filesystem_support()
{
FS fs ;
fs .filesystem = GParted::FS_JFS ;
fs .busy = FS::GPARTED ;
if ( ! Glib::find_program_in_path( "jfs_debugfs" ) .empty() ) {
fs .read = GParted::FS::EXTERNAL ;
}

View File

@ -43,7 +43,8 @@ FS linux_swap::get_filesystem_support()
{
FS fs ;
fs .filesystem = GParted::FS_LINUX_SWAP ;
fs .busy = FS::GPARTED ;
fs .read = FS::EXTERNAL ;
fs .online_read = FS::EXTERNAL ;

View File

@ -52,6 +52,7 @@ FS lvm2_pv::get_filesystem_support()
LVM2_PV_Info lvm2_pv_info ;
if ( lvm2_pv_info .is_lvm2_pv_supported() )
{
fs .busy = FS::EXTERNAL ;
fs .read = FS::EXTERNAL ;
fs .create = FS::EXTERNAL ;
fs .grow = FS::EXTERNAL ;
@ -72,6 +73,12 @@ FS lvm2_pv::get_filesystem_support()
return fs ;
}
bool lvm2_pv::is_busy( const Glib::ustring & path )
{
LVM2_PV_Info lvm2_pv_info ;
return lvm2_pv_info .has_active_lvs( path ) ;
}
void lvm2_pv::set_used_sectors( Partition & partition )
{
LVM2_PV_Info lvm2_pv_info ;

View File

@ -25,6 +25,8 @@ FS nilfs2::get_filesystem_support()
FS fs ;
fs .filesystem = GParted::FS_NILFS2 ;
fs .busy = FS::GPARTED ;
if ( ! Glib::find_program_in_path( "mkfs.nilfs2" ) .empty() )
{
fs .create = GParted::FS::EXTERNAL ;

View File

@ -59,6 +59,8 @@ FS ntfs::get_filesystem_support()
FS fs ;
fs .filesystem = GParted::FS_NTFS ;
fs .busy = FS::GPARTED ;
if ( ! Glib::find_program_in_path( "ntfsresize" ) .empty() )
{
fs .read = GParted::FS::EXTERNAL ;

View File

@ -25,7 +25,9 @@ FS reiser4::get_filesystem_support()
{
FS fs ;
fs .filesystem = GParted::FS_REISER4 ;
fs .busy = FS::GPARTED ;
if ( ! Glib::find_program_in_path( "debugfs.reiser4" ) .empty() )
{
fs .read = GParted::FS::EXTERNAL ;

View File

@ -25,7 +25,9 @@ FS reiserfs::get_filesystem_support()
{
FS fs ;
fs .filesystem = GParted::FS_REISERFS ;
fs .busy = FS::GPARTED ;
if ( ! Glib::find_program_in_path( "debugreiserfs" ) .empty() )
{
fs .read = GParted::FS::EXTERNAL ;

View File

@ -24,9 +24,9 @@ namespace GParted
FS ufs::get_filesystem_support()
{
FS fs ;
fs .filesystem = GParted::FS_UFS ;
fs .busy = FS::GPARTED ;
fs .copy = GParted::FS::GPARTED ;
fs .move = GParted::FS::GPARTED ;
fs .online_read = FS::GPARTED ;

View File

@ -25,7 +25,9 @@ FS xfs::get_filesystem_support()
{
FS fs ;
fs .filesystem = GParted::FS_XFS ;
fs .busy = FS::GPARTED ;
if ( ! Glib::find_program_in_path( "xfs_db" ) .empty() )
{
fs .read = GParted::FS::EXTERNAL ;