From 536889cde6c5e7308b570d0ddaa1f9277e54140e Mon Sep 17 00:00:00 2001
From: Alaric Senat <dev.asenat@posteo.net>
Date: Mon, 17 Apr 2023 16:08:22 +0200
Subject: [PATCH] DeviceLister: linux: Fix device name inference

The linux partition to device code was flawed in case of filesystems
mapping a single partition directly at the root without naming it
(eg. `/dev/sdc` being a main disk partition, not `/dev/sdc1`).

Fixes #469
---
 src/filesystem/unix/DeviceLister.cpp | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/src/filesystem/unix/DeviceLister.cpp b/src/filesystem/unix/DeviceLister.cpp
index ca5e08db7..09598256d 100644
--- a/src/filesystem/unix/DeviceLister.cpp
+++ b/src/filesystem/unix/DeviceLister.cpp
@@ -206,6 +206,24 @@ DeviceLister::deviceFromDeviceMapper( const std::string& devicePath ) const
     return { dmName, res };
 }
 
+static std::string getDeviceName( const std::string& partitionBlockPath )
+{
+    const auto parentDirectory =
+        utils::file::directoryName( utils::file::parentDirectory( partitionBlockPath ) );
+
+    // Partition subfolder is not mandatory and filesytems can be written on a disk without one
+    // (pretty common with usb sticks for instance). In that case instead of having a partition
+    // absolute path mapped as:
+    //  `/sys/devices/....../block/device/partition/`
+    // we'll end up with a path pointing to the device folder directly, such as:
+    // `/sys/devices/....../block/device/`
+    //
+    // This block ensure we return the proper device folder.
+    if ( parentDirectory == "block" )
+        return utils::file::directoryName( partitionBlockPath );
+    return parentDirectory;
+}
+
 bool DeviceLister::isRemovable( const std::string& partitionPath ) const
 {
     // We have a partition, such as /dev/sda1. We need to find the associated
@@ -232,8 +250,8 @@ bool DeviceLister::isRemovable( const std::string& partitionPath ) const
                   " ", ex.what() );
         return false;
     }
-    auto deviceName = utils::file::directoryName(
-                        utils::file::parentDirectory( partitionBlockPath ) );
+
+    const auto deviceName = getDeviceName( partitionBlockPath );
 
     std::string removableFilePath = "/sys/block/" + deviceName + "/removable";
     std::unique_ptr<FILE, decltype(&fclose)> removableFile(
-- 
GitLab