[system/kio-snapshot] /: contextmenu: optimize checking for existence of snapshots (because we don't need the full list)

Bharadwaj Raju <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 43acca30129880eccf0fb31f4330efabe7b1b594 by Bharadwaj Raju.
Committed on 09/08/2026 at 13:59.
Pushed by bharadwaj-raju into branch 'master'.

contextmenu: optimize checking for existence of snapshots (because we don't need the full list)

M  +37   -0    common/btrfssnapshots.cpp
M  +1    -0    common/btrfssnapshots.h
M  +2    -2    contextmenu/snapshotfileitemaction.cpp

https://invent.kde.org/system/kio-snapshot/-/commit/43acca30129880eccf0fb31f4330efabe7b1b594

diff --git a/common/btrfssnapshots.cpp b/common/btrfssnapshots.cpp
index 2918098..78aa97b 100644
--- a/common/btrfssnapshots.cpp
+++ b/common/btrfssnapshots.cpp
@@ -84,6 +84,43 @@ std::optional<QString> BtrfsSnapshots::getPathForSubvolume(qulonglong subvolume,
     return std::nullopt;
 }
 
+bool BtrfsSnapshots::hasSnapshots(const QString &path, const QString &fsRoot)
+{
+    QDir subvolumeRoot;
+    QFileInfo fileInfo(path);
+    if (fileInfo.isDir()) {
+        subvolumeRoot = QDir(path);
+    } else {
+        subvolumeRoot = QDir(QFileInfo(path).absoluteDir());
+    }
+    struct btrfs_util_subvolume_info subvolume_root_info;
+    enum btrfs_util_error btrfs_err;
+    while (!subvolumeRoot.isRoot() && (btrfs_err = btrfs_util_subvolume_get_info(CSTR(subvolumeRoot.absolutePath()), 0, &subvolume_root_info)) != 0) {
+        subvolumeRoot.cdUp();
+    }
+
+    if (btrfs_err != 0) {
+        return false;
+    }
+
+    struct btrfs_util_subvolume_iterator *iter;
+    btrfs_err = btrfs_util_subvolume_iter_create(CSTR(fsRoot), 0, 0, &iter);
+    if (btrfs_err != 0) {
+        return false;
+    }
+
+    struct btrfs_util_subvolume_info iter_info;
+    char *iter_path;
+    while ((btrfs_err = btrfs_util_subvolume_iter_next_info(iter, &iter_path, &iter_info)) == 0) {
+        if (QByteArrayView::fromArray(iter_info.parent_uuid) == QByteArrayView::fromArray(subvolume_root_info.uuid)) {
+            free(iter_path);
+            return true;
+        }
+        free(iter_path);
+    }
+    return false;
+}
+
 QList<BtrfsSnapshots::FileSnapshot> BtrfsSnapshots::getSnapshotsForFile(const QString &path, const QString &fsRoot)
 {
     QList<FileSnapshot> fileSnapshots;
diff --git a/common/btrfssnapshots.h b/common/btrfssnapshots.h
index 7ea4500..d322948 100644
--- a/common/btrfssnapshots.h
+++ b/common/btrfssnapshots.h
@@ -36,6 +36,7 @@ public:
 std::optional<qulonglong> getSubvolumeForPath(const QString &path, const QString &fsRoot = "/"_L1);
 std::optional<QString> getPathForSubvolume(qulonglong subvolume, const QString &fsRoot = "/"_L1);
 QList<SubvolumeSnapshot> getSnapshotsForSubvolume(const QString &path, const QString &fsRoot = "/"_L1);
+bool hasSnapshots(const QString &path, const QString &fsRoot);
 QList<FileSnapshot> getSnapshotsForFile(const QString &path, const QString &fsRoot = "/"_L1);
 QMap<qulonglong, QString> getNonSnapshotSubvolumes(const QString &fsRoot = "/"_L1);
 }
diff --git a/contextmenu/snapshotfileitemaction.cpp b/contextmenu/snapshotfileitemaction.cpp
index 0665c96..47a1d8f 100644
--- a/contextmenu/snapshotfileitemaction.cpp
+++ b/contextmenu/snapshotfileitemaction.cpp
@@ -66,7 +66,7 @@ QList<QAction *> SnapshotFileItemAction::actions(const KFileItemListProperties &
         }
         QString fsUuid = fsVolume->uuid();
 
-        if (!BtrfsSnapshots::getSnapshotsForSubvolume(itemUrl.toLocalFile(), fsRootPath).empty()) {
+        if (BtrfsSnapshots::hasSnapshots(itemUrl.toLocalFile(), fsRootPath)) {
             auto subvolumeIdOpt = BtrfsSnapshots::getSubvolumeForPath(itemUrl.toLocalFile(), fsRootPath);
             if (!subvolumeIdOpt.has_value()) {
                 qCCritical(SNAPSHOT_FILEITEMACTION()) << "found snapshots for dir" << itemUrl.toLocalFile() << "but it did not have a subvolume id";
@@ -94,7 +94,7 @@ QList<QAction *> SnapshotFileItemAction::actions(const KFileItemListProperties &
             return actions;
         }
         QString fsRootPath = fsRoot->filePath();
-        if (!BtrfsSnapshots::getSnapshotsForFile(itemUrl.toLocalFile(), fsRootPath).empty()) {
+        if (BtrfsSnapshots::hasSnapshots(itemUrl.toLocalFile(), fsRootPath)) {
             QAction *action = new QAction(QIcon::fromTheme("view-history"_L1), i18nc("@action:inmenu", "View snapshots…"), parentWidget);
             connect(action, &QAction::triggered, this, [this, item]() {
                 KIO::OpenUrlJob *job = new KIO::OpenUrlJob(QUrl("filesnapshots://%1"_L1.arg(item.localPath())), "inode/directory"_L1, this);
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.