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



commit b1dc9e69e39a61a678534e3d83c4b94a89a695e6
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Sat Feb 15 01:26:32 2014 +0000

    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)

 include/FileSystem.h   |    1 +
 include/GParted_Core.h |    1 +
 include/Utils.h        |    1 +
 include/lvm2_pv.h      |    1 +
 src/GParted_Core.cc    |   66 +++++++++++++++++++++++++++++++++++------------
 src/btrfs.cc           |    2 +
 src/exfat.cc           |    4 +-
 src/ext2.cc            |    2 +
 src/f2fs.cc            |    2 +
 src/fat16.cc           |    4 ++-
 src/hfs.cc             |    3 +-
 src/hfsplus.cc         |    3 +-
 src/jfs.cc             |    4 ++-
 src/linux_swap.cc      |    3 +-
 src/lvm2_pv.cc         |    7 +++++
 src/nilfs2.cc          |    2 +
 src/ntfs.cc            |    2 +
 src/reiser4.cc         |    4 ++-
 src/reiserfs.cc        |    4 ++-
 src/ufs.cc             |    4 +-
 src/xfs.cc             |    4 ++-
 21 files changed, 95 insertions(+), 29 deletions(-)
---
diff --git a/include/FileSystem.h b/include/FileSystem.h
index 8fbfd8e..e79fcd7 100644
--- a/include/FileSystem.h
+++ b/include/FileSystem.h
@@ -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; };
diff --git a/include/GParted_Core.h b/include/GParted_Core.h
index aa13daf..2431bcc 100644
--- a/include/GParted_Core.h
+++ b/include/GParted_Core.h
@@ -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
diff --git a/include/Utils.h b/include/Utils.h
index 8e7cf35..a0a5dd9 100644
--- a/include/Utils.h
+++ b/include/Utils.h
@@ -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 ;
diff --git a/include/lvm2_pv.h b/include/lvm2_pv.h
index 4d8bd86..cdb18db 100644
--- a/include/lvm2_pv.h
+++ b/include/lvm2_pv.h
@@ -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 ) ;
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index a59aee2..5af510b 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -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++ )
diff --git a/src/btrfs.cc b/src/btrfs.cc
index b1058e6..788a484 100644
--- a/src/btrfs.cc
+++ b/src/btrfs.cc
@@ -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 ;
diff --git a/src/exfat.cc b/src/exfat.cc
index fc8050e..f444fed 100644
--- a/src/exfat.cc
+++ b/src/exfat.cc
@@ -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 ;
diff --git a/src/ext2.cc b/src/ext2.cc
index 505bcb3..40dd985 100644
--- a/src/ext2.cc
+++ b/src/ext2.cc
@@ -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
diff --git a/src/f2fs.cc b/src/f2fs.cc
index 2649252..61a5131 100644
--- a/src/f2fs.cc
+++ b/src/f2fs.cc
@@ -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 ;
diff --git a/src/fat16.cc b/src/fat16.cc
index 8a9f4cc..d8527f6 100644
--- a/src/fat16.cc
+++ b/src/fat16.cc
@@ -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() )
        {
diff --git a/src/hfs.cc b/src/hfs.cc
index 4e6503a..0e4d13a 100644
--- a/src/hfs.cc
+++ b/src/hfs.cc
@@ -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 ;
diff --git a/src/hfsplus.cc b/src/hfsplus.cc
index 6299d50..bdeed34 100644
--- a/src/hfsplus.cc
+++ b/src/hfsplus.cc
@@ -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 ;
diff --git a/src/jfs.cc b/src/jfs.cc
index c8f826b..8207b83 100644
--- a/src/jfs.cc
+++ b/src/jfs.cc
@@ -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 ;
        }
diff --git a/src/linux_swap.cc b/src/linux_swap.cc
index 18f547c..d674848 100644
--- a/src/linux_swap.cc
+++ b/src/linux_swap.cc
@@ -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 ;
 
diff --git a/src/lvm2_pv.cc b/src/lvm2_pv.cc
index f548d65..47a872c 100644
--- a/src/lvm2_pv.cc
+++ b/src/lvm2_pv.cc
@@ -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 ;
diff --git a/src/nilfs2.cc b/src/nilfs2.cc
index 880bee2..1acfc71 100644
--- a/src/nilfs2.cc
+++ b/src/nilfs2.cc
@@ -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 ;
diff --git a/src/ntfs.cc b/src/ntfs.cc
index 61da501..1cccd23 100644
--- a/src/ntfs.cc
+++ b/src/ntfs.cc
@@ -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 ;
diff --git a/src/reiser4.cc b/src/reiser4.cc
index 73c7c3a..5453464 100644
--- a/src/reiser4.cc
+++ b/src/reiser4.cc
@@ -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 ;
diff --git a/src/reiserfs.cc b/src/reiserfs.cc
index fc89a08..a563bf4 100644
--- a/src/reiserfs.cc
+++ b/src/reiserfs.cc
@@ -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 ;
diff --git a/src/ufs.cc b/src/ufs.cc
index e8936bc..0f25735 100644
--- a/src/ufs.cc
+++ b/src/ufs.cc
@@ -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 ;
diff --git a/src/xfs.cc b/src/xfs.cc
index a92ba99..8268a43 100644
--- a/src/xfs.cc
+++ b/src/xfs.cc
@@ -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 ;


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