diff --git a/include/BCache_Info.h b/include/BCache_Info.h index 5265a547..6d24313b 100644 --- a/include/BCache_Info.h +++ b/include/BCache_Info.h @@ -36,6 +36,11 @@ class BCache_Info { public: static bool is_active(const Glib::ustring& device_path, const Glib::ustring& partition_path); + static Glib::ustring get_bcache_device(const Glib::ustring& device_path, const Glib::ustring& partition_path); + +private: + static Glib::ustring get_sysfs_bcache_path(const Glib::ustring& device_path, + const Glib::ustring& partition_path); }; diff --git a/src/BCache_Info.cc b/src/BCache_Info.cc index ff9bd105..129a5178 100644 --- a/src/BCache_Info.cc +++ b/src/BCache_Info.cc @@ -17,6 +17,8 @@ #include "BCache_Info.h" +#include // GNU version of basename() +#include #include #include @@ -29,22 +31,45 @@ namespace GParted // otherwise. Equivalent to does the directory /sys/block/DEV[/PTN]/bcache exist? bool BCache_Info::is_active(const Glib::ustring& device_path, const Glib::ustring& partition_path) { - Glib::ustring bcache_path; + return file_test(get_sysfs_bcache_path(device_path, partition_path), Glib::FILE_TEST_IS_DIR); +} + + +// Return the bcache device name for a registered bcache backing device (active +// component), or an empty string. +// E.g.: ("/dev/sdb", "/dev/sdb1") -> "/dev/bcache0" +Glib::ustring BCache_Info::get_bcache_device(const Glib::ustring& device_path, const Glib::ustring& partition_path) +{ + Glib::ustring sysfs_path = get_sysfs_bcache_path(device_path, partition_path) + "/dev"; + + char buf[128]; // Large enough for link target + // "../../../../../../../../../../virtual/block/bcache0". + ssize_t len = readlink(sysfs_path.c_str(), buf, sizeof(buf)-1); + if (len < 0) + return Glib::ustring(""); + buf[len] = '\0'; + + return "/dev/" + Glib::ustring(basename(buf)); +} + + +// Private methods + +Glib::ustring BCache_Info::get_sysfs_bcache_path(const Glib::ustring& device_path, const Glib::ustring& partition_path) +{ Glib::ustring dev_name = device_path.substr(5); // Remove leading "/dev/". if (device_path == partition_path) { // Whole drive - bcache_path = "/sys/block/" + dev_name + "/bcache"; + return "/sys/block/" + dev_name + "/bcache"; } else { // Partition on drive Glib::ustring ptn_name = partition_path.substr(5); // Remove leading "/dev/". - bcache_path = "/sys/block/" + dev_name + "/" + ptn_name + "/bcache"; + return "/sys/block/" + dev_name + "/" + ptn_name + "/bcache"; } - - return file_test(bcache_path, Glib::FILE_TEST_IS_DIR); } diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc index 7dae661d..f28de6bf 100644 --- a/src/GParted_Core.cc +++ b/src/GParted_Core.cc @@ -1491,6 +1491,13 @@ void GParted_Core::set_mountpoints( Partition & partition ) partition.add_mountpoint(array_path_2); } } + else if (partition.fstype == FS_BCACHE) + { + const Glib::ustring bcache_path = BCache_Info::get_bcache_device(partition.device_path, + partition.get_path()); + if (! bcache_path.empty()) + partition.add_mountpoint(bcache_path); + } else if (partition.fstype == FS_LUKS) { LUKS_Mapping mapping = LUKS_Info::get_cache_entry( partition.get_path() );