[gparted] Display mount points for multi-device btrfs file systems (#723842)



commit a086e115e5ab2884c972036daed806d53da1f257
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Tue Mar 25 23:03:30 2014 +0000

    Display mount points for multi-device btrfs file systems (#723842)
    
    Linux can only show a single device name in /proc/mounts and /etc/mtab
    for each mounted btrfs, even if it is a multi-device file system.  So
    GParted only shows a mount point for one of the devices in the btrfs, no
    matter how many devices are part of the file system.
    
        # mkfs.btrfs /dev/sdb1 /dev/sdb2
        # btrfs filesystem show /dev/sdb1
        Label: none  uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
                Total devices 2 FS bytes used 156.00KB
                devid    2 size 2.00GB used 512.00MB path /dev/sdb2
                devid    1 size 2.00GB used 240.75MB path /dev/sdb1
        # mount /dev/sdb1 /mnt/1
        # grep btrfs /proc/mounts
        /dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
    
    GParted only shows the mount point for /dev/sdb1 as /mnt/1, but nothing
    for /dev/sdb2.
    
    Make GParted report the same mount point for all devices included in a
    multi-device btrfs file system.
    
    Add btrfs specific get_mount_device() method to report the mounting
    device, if any, for the btrfs file system in the occupying the device in
    question.  Uses the existing cache of btrfs file system device
    membership.  Also extract common code from GParted_Core::
    set_mountpoints() into set_mountpoints_helper().
    
    Bug #723842 - GParted resizes the wrong filesystem (does not pass the
                  devid to btrfs filesystem resize)

 include/GParted_Core.h |    1 +
 include/btrfs.h        |    1 +
 src/GParted_Core.cc    |   42 ++++++++++++++++++++++++++----------------
 src/btrfs.cc           |   17 ++++++++++++-----
 4 files changed, 40 insertions(+), 21 deletions(-)
---
diff --git a/include/GParted_Core.h b/include/GParted_Core.h
index beb11e9..ded7835 100644
--- a/include/GParted_Core.h
+++ b/include/GParted_Core.h
@@ -88,6 +88,7 @@ private:
                                 Byte_Value sector_size,
                                 bool inside_extended ) ;
        void set_mountpoints( std::vector<Partition> & partitions ) ;
+       bool set_mountpoints_helper( Partition & partitions, const Glib::ustring & path ) ;
        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 ) ;
diff --git a/include/btrfs.h b/include/btrfs.h
index f0828ee..693c686 100644
--- a/include/btrfs.h
+++ b/include/btrfs.h
@@ -37,6 +37,7 @@ public:
        bool check_repair( const Partition & partition, OperationDetail & operationdetail ) ;
 
        static void clear_cache() ;
+       static Glib::ustring get_mount_device( const Glib::ustring & path ) ;
 
 private:
        static const std::vector<Glib::ustring> get_cache_entry( const Glib::ustring & path ) ;
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index a2b4ebb..755e9ba 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -1515,7 +1515,6 @@ void GParted_Core::set_mountpoints( std::vector<Partition> & partitions )
                     partitions[ t ] .filesystem != FS_LINUX_SWSUSPEND
                   )
                {
-                       std::map< Glib::ustring, std::vector<Glib::ustring> >::iterator iter_mp ;
                        if ( partitions[ t ] .busy )
                        {
 #ifndef USE_LIBPARTED_DMRAID
@@ -1526,19 +1525,14 @@ void GParted_Core::set_mountpoints( std::vector<Partition> & partitions )
                                if ( dmraid .is_dmraid_device( partitions[ t ] .device_path ) )
                                {
                                        //Try device_name + partition_number
-                                       iter_mp = mount_info .find( partitions[ t ] .device_path + 
Utils::num_to_str( partitions[ t ] .partition_number ) ) ;
-                                       if ( iter_mp != mount_info .end() )
-                                       {
-                                               partitions[ t ] .add_mountpoints( iter_mp ->second ) ;
+                                       Glib::ustring dmraid_path = partitions[ t ] .device_path + 
Utils::num_to_str( partitions[t ] .partition_number ) ;
+                                       if ( set_mountpoints_helper( partitions[ t ], dmraid_path ) )
                                                break ;
-                                       }
+
                                        //Try device_name + p + partition_number
-                                       iter_mp = mount_info .find( partitions[ t ] .device_path + "p" + 
Utils::num_to_str( partitions[ t ] .partition_number ) ) ;
-                                       if ( iter_mp != mount_info .end() )
-                                       {
-                                               partitions[ t ] .add_mountpoints( iter_mp ->second ) ;
+                                       dmraid_path = partitions[ t ] .device_path + "p" + Utils::num_to_str( 
partitions[ t ] .partition_number ) ;
+                                       if ( set_mountpoints_helper( partitions[ t ], dmraid_path ) )
                                                break ;
-                                       }
                                }
                                else
                                {
@@ -1546,12 +1540,9 @@ void GParted_Core::set_mountpoints( std::vector<Partition> & partitions )
                                        //Normal device, not DMRaid device
                                        for ( unsigned int i = 0 ; i < partitions[ t ] .get_paths() .size() ; 
i++ )
                                        {
-                                               iter_mp = mount_info .find( partitions[ t ] .get_paths()[ i ] 
) ;
-                                               if ( iter_mp != mount_info .end() )
-                                               {
-                                                       partitions[ t ] .add_mountpoints( iter_mp ->second ) ;
+                                               Glib::ustring path = partitions[ t ] .get_paths()[ i ] ;
+                                               if ( set_mountpoints_helper( partitions[ t ], path ) )
                                                        break ;
-                                               }
                                        }
 #ifndef USE_LIBPARTED_DMRAID
                                }
@@ -1562,6 +1553,7 @@ void GParted_Core::set_mountpoints( std::vector<Partition> & partitions )
                        }
                        else
                        {
+                               std::map< Glib::ustring, std::vector<Glib::ustring> >::iterator iter_mp ;
                                iter_mp = fstab_info .find( partitions[ t ] .get_path() );
                                if ( iter_mp != fstab_info .end() )
                                        partitions[ t ] .add_mountpoints( iter_mp ->second ) ;
@@ -1578,6 +1570,24 @@ void GParted_Core::set_mountpoints( std::vector<Partition> & partitions )
        }
 }
 
+bool GParted_Core::set_mountpoints_helper( Partition & partition, const Glib::ustring & path )
+{
+       Glib::ustring search_path ;
+       if ( partition .filesystem == FS_BTRFS )
+               search_path = btrfs::get_mount_device( path ) ;
+       else
+               search_path = path ;
+
+       std::map< Glib::ustring, std::vector<Glib::ustring> >::iterator iter_mp = mount_info .find( 
search_path ) ;
+       if ( iter_mp != mount_info .end() )
+       {
+               partition .add_mountpoints( iter_mp ->second ) ;
+               return true ;
+       }
+
+       return false;
+}
+
 //Report whether the partition is busy (mounted/active)
 bool GParted_Core::is_busy( FILESYSTEM fstype, const Glib::ustring & path )
 {
diff --git a/src/btrfs.cc b/src/btrfs.cc
index 0700026..6e8ec4d 100644
--- a/src/btrfs.cc
+++ b/src/btrfs.cc
@@ -141,11 +141,7 @@ bool btrfs::is_busy( const Glib::ustring & path )
        //  member of the file system.  Fixed in linux 3.5 by commit:
        //      Btrfs: implement ->show_devname
        //      
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
-       std::vector<Glib::ustring> entry = get_cache_entry( path ) ;
-       for ( unsigned int i = 0 ; i < entry .size() ; i ++ )
-               if ( GParted_Core::is_dev_mounted( entry[ i ] ) )
-                       return true ;
-       return false ;
+       return ! get_mount_device( path ) .empty() ;
 }
 
 bool btrfs::create( const Partition & new_partition, OperationDetail & operationdetail )
@@ -343,6 +339,17 @@ void btrfs::clear_cache()
        btrfs_device_cache .clear() ;
 }
 
+//Return the device which is mounting the btrfs in this partition.
+//  Return empty string if not found (not mounted).
+Glib::ustring btrfs::get_mount_device( const Glib::ustring & path )
+{
+       std::vector<Glib::ustring> entry = get_cache_entry( path ) ;
+       for ( unsigned int i = 0 ; i < entry .size() ; i ++ )
+               if ( GParted_Core::is_dev_mounted( entry[ i ] ) )
+                       return entry[ i ] ;
+       return "" ;
+}
+
 //Private methods
 
 //Return btrfs device cache entry, incrementally loading cache as required


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