From a086e115e5ab2884c972036daed806d53da1f257 Mon Sep 17 00:00:00 2001 From: Mike Fleetwood Date: Tue, 25 Mar 2014 23:03:30 +0000 Subject: [PATCH] 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 beb11e99..ded78352 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 & 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 & partitions, PedDisk* lp_disk ) ; void mounted_set_used_sectors( Partition & partition ) ; diff --git a/include/btrfs.h b/include/btrfs.h index f0828ee7..693c6866 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 get_cache_entry( const Glib::ustring & path ) ; diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc index a2b4ebb5..755e9baa 100644 --- a/src/GParted_Core.cc +++ b/src/GParted_Core.cc @@ -1515,7 +1515,6 @@ void GParted_Core::set_mountpoints( std::vector & partitions ) partitions[ t ] .filesystem != FS_LINUX_SWSUSPEND ) { - std::map< Glib::ustring, std::vector >::iterator iter_mp ; if ( partitions[ t ] .busy ) { #ifndef USE_LIBPARTED_DMRAID @@ -1526,19 +1525,14 @@ void GParted_Core::set_mountpoints( std::vector & 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 & 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 & partitions ) } else { + std::map< Glib::ustring, std::vector >::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 & 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 >::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 0700026a..6e8ec4d0 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 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 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