[system/kio-snapshot] /: List root volume among non-snapshot subvolumes

Bharadwaj Raju <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 556717cd90a1bc79661c7b88de12fb368c58b793 by Bharadwaj Raju.
Committed on 29/07/2026 at 03:36.
Pushed by bharadwaj-raju into branch 'master'.

List root volume among non-snapshot subvolumes

M  +28   -5    autotests/test_snapshot_worker.cpp
M  +17   -0    common/btrfssnapshots.cpp

https://invent.kde.org/system/kio-snapshot/-/commit/556717cd90a1bc79661c7b88de12fb368c58b793

diff --git a/autotests/test_snapshot_worker.cpp b/autotests/test_snapshot_worker.cpp
index 8e9f22f..3329ac6 100644
--- a/autotests/test_snapshot_worker.cpp
+++ b/autotests/test_snapshot_worker.cpp
@@ -69,6 +69,23 @@ private Q_SLOTS:
         QVERIFY(listJob->exec());
     };
 
+    void testRoot()
+    {
+        QUrl url;
+        url.setScheme("snapshot"_L1);
+        url.setHost(m_fsUuid);
+        url.setPath("/5"_L1);
+        KIO::ListJob *listJob = KIO::listDir(url, KIO::HideProgressInfo);
+        connect(listJob, &KIO::ListJob::entries, this, &TestSnapshotWorker::slotRootSnapshotEntries);
+        bool ok = listJob->exec();
+        if (!ok) {
+            qDebug() << url;
+            qDebug() << listJob->errorText();
+            qDebug() << listJob->errorString();
+        }
+        QVERIFY(ok);
+    }
+
 protected Q_SLOTS:
     void slotAllSubvolumesEntries(KIO::Job *, const KIO::UDSEntryList &entries)
     {
@@ -76,22 +93,23 @@ protected Q_SLOTS:
         bool hasSub = false;
         for (const KIO::UDSEntry &entry : std::as_const(entries)) {
             qDebug() << entry;
-            const auto name = entry.stringValue(KIO::UDSEntry::UDS_DISPLAY_NAME);
-            if (name.contains(QDir::cleanPath(m_testMount + "/sub"_L1))) {
+            const auto displayName = entry.stringValue(KIO::UDSEntry::UDS_DISPLAY_NAME);
+            const auto name = entry.stringValue(KIO::UDSEntry::UDS_NAME);
+            if (displayName.contains(QDir::cleanPath(m_testMount + "/sub"_L1))) {
                 hasSub = true;
             }
+            if (name == "subvolume5"_L1) {
+                hasRoot = true;
+            }
         }
         QVERIFY(hasSub);
-        QEXPECT_FAIL("", "TODO get BtrfsSnapshots::getNonSnapshotSubvolumes to return root volume", Continue);
         QVERIFY(hasRoot);
-        QEXPECT_FAIL("", "TODO get BtrfsSnapshots::getNonSnapshotSubvolumes to return root volume", Continue);
         QCOMPARE(entries.size(), 2);
     }
 
     void slotGetSubSnapshotsUrl(KIO::Job *, const KIO::UDSEntryList &entries)
     {
         for (const KIO::UDSEntry &entry : std::as_const(entries)) {
-            qDebug() << "aaa" << entry;
             const auto name = entry.stringValue(KIO::UDSEntry::UDS_DISPLAY_NAME);
             if (name.contains(QDir::cleanPath(m_testMount + "/sub"_L1))) {
                 m_subSnapshotsUrl = QUrl(entry.stringValue(KIO::UDSEntry::UDS_URL));
@@ -108,6 +126,11 @@ protected Q_SLOTS:
     {
         QCOMPARE(entries.size(), 6);
     }
+
+    void slotRootSnapshotEntries(KIO::Job *, const KIO::UDSEntryList &entries)
+    {
+        QCOMPARE(entries.size(), 6);
+    }
 };
 
 QTEST_GUILESS_MAIN(TestSnapshotWorker)
diff --git a/common/btrfssnapshots.cpp b/common/btrfssnapshots.cpp
index 2db9e91..2918098 100644
--- a/common/btrfssnapshots.cpp
+++ b/common/btrfssnapshots.cpp
@@ -47,6 +47,11 @@ std::optional<qulonglong> BtrfsSnapshots::getSubvolumeForPath(const QString &pat
         free(iter_path);
     }
 
+    if (path == fsRoot) {
+        // we did not find a subvolume mounted at fs root, so fs root must be volume 5 (FS_TREE)
+        return 5;
+    }
+
     return std::nullopt;
 }
 
@@ -71,6 +76,11 @@ std::optional<QString> BtrfsSnapshots::getPathForSubvolume(qulonglong subvolume,
         free(iter_path);
     }
 
+    if (subvolume == 5 && getSubvolumeForPath(fsRoot, fsRoot) == 5) {
+        // 5 is the FS_TREE volume
+        return fsRoot;
+    }
+
     return std::nullopt;
 }
 
@@ -179,5 +189,12 @@ QMap<qulonglong, QString> BtrfsSnapshots::getNonSnapshotSubvolumes(const QString
         free(iter_path);
     }
 
+    struct btrfs_util_subvolume_info root_info;
+    btrfs_err = btrfs_util_subvolume_get_info(CSTR(fsRoot), 0, &root_info);
+    if (btrfs_err != 0) {
+        return subvolumes;
+    }
+    subvolumes[static_cast<qulonglong>(root_info.id)] = fsRoot;
+
     return subvolumes;
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.