From 7a12a85b98ccbbf7a59479658dfa35d1254316d1 Mon Sep 17 00:00:00 2001 From: Soramane <61896496+soramanew@users.noreply.github.com> Date: Fri, 15 May 2026 00:41:13 +1000 Subject: [PATCH] fix: dedupe mounts by source device for storage --- plugin/src/Caelestia/Services/storage.cpp | 37 ++++++++++++++++++----- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/plugin/src/Caelestia/Services/storage.cpp b/plugin/src/Caelestia/Services/storage.cpp index 8ba5a7cc..d3e31496 100644 --- a/plugin/src/Caelestia/Services/storage.cpp +++ b/plugin/src/Caelestia/Services/storage.cpp @@ -207,6 +207,18 @@ void Storage::tick() { const qreal prevPercentage = percentage(); QHash byDisk; + // Multiple mounts can share a single backing filesystem (btrfs subvolumes, + // bind mounts, etc.) and each one reports identical bytesTotal/bytesAvailable. + // Dedupe by source device so the filesystem only contributes once per disk. + struct DeviceEntry { + quint64 totalBytes = 0; + quint64 usedBytes = 0; + bool hasRoot = false; + QByteArray device; + }; + + QHash byDevice; + const auto mountedVols = QStorageInfo::mountedVolumes(); for (const QStorageInfo& v : mountedVols) { if (!v.isReady() || !v.isValid() || v.bytesTotal() <= 0) { @@ -216,24 +228,33 @@ void Storage::tick() { continue; } - const QStringList disks = resolveToPhysicalDisks(QString::fromLocal8Bit(v.device())); - if (disks.isEmpty()) { - continue; - } - + const QByteArray device = v.device(); const auto totalBytes = static_cast(v.bytesTotal()); const auto availBytes = static_cast(v.bytesAvailable()); const quint64 usedBytes = totalBytes > availBytes ? totalBytes - availBytes : 0; const bool isRoot = v.rootPath() == QStringLiteral("/"); + DeviceEntry& e = byDevice[device]; + e.device = device; + e.totalBytes = totalBytes; + e.usedBytes = usedBytes; + e.hasRoot = e.hasRoot || isRoot; + } + + for (auto it = byDevice.constBegin(); it != byDevice.constEnd(); ++it) { + const DeviceEntry& e = it.value(); + const QStringList disks = resolveToPhysicalDisks(QString::fromLocal8Bit(e.device)); + if (disks.isEmpty()) { + continue; + } for (const QString& d : disks) { if (d.startsWith(QStringLiteral("zram"))) { continue; } Accum& a = byDisk[d]; - a.usedBytes += usedBytes; - a.totalBytes += totalBytes; - a.hasRoot = a.hasRoot || isRoot; + a.usedBytes += e.usedBytes; + a.totalBytes += e.totalBytes; + a.hasRoot = a.hasRoot || e.hasRoot; } }