From 98f3c36ed2b459c10b117fb6e6c41c3211fcd10a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 28 May 2024 23:46:05 -0300 Subject: [PATCH] QStorageInfo/Linux: re-work the mountedVolumes() check for mounted-overs Commit ddc39eb3a46d699c23d39f0e914978199eb98cc6 ("QStorageInfo/Linux: fix mountedVolumes() for paths mounted over") added a clever check that did stat() on the path to figure out if it was the device that we'd just found on /proc/self/mountinfo. But if the same device was mounted on top again, we may have got the wrong answer. More importantly, since kernel 6.9, btrfs subvolume mounts no longer report the subvolume's block ID in /proc/self/mountinfo, which would lead us to conclude every single subvolume has been mounted-over. So let's revert back to string-matching later lines to see if any is a parent path. https://lore.kernel.org/linux-btrfs/2548140.Uh0CODmnKu@tjmaciei-mobl5/T/ Fixes: QTBUG-125721 Change-Id: If3345151ddf84c43a4f1fffd17d3d59fef4446dd Reviewed-by: Ahmad Samir (cherry picked from commit ad968d3602eec2b1f34a9c80606e59c5a2c76a2a) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/io/qstorageinfo_linux.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qstorageinfo_linux.cpp b/src/corelib/io/qstorageinfo_linux.cpp index c5cc9c60520..a08e53daa16 100644 --- a/src/corelib/io/qstorageinfo_linux.cpp +++ b/src/corelib/io/qstorageinfo_linux.cpp @@ -276,14 +276,21 @@ QList QStorageInfoPrivate::mountedVolumes() }; QList volumes; - for (MountInfo &info : infos) { + volumes.reserve(infos.size()); + for (auto it = infos.begin(); it != infos.end(); ++it) { + MountInfo &info = *it; + // Scan the later lines to see if any is a parent to this + auto isParent = [&info](const MountInfo &maybeParent) { + return isParentOf(maybeParent.mountPoint, info.mountPoint); + }; + if (std::find_if(it + 1, infos.end(), isParent) != infos.end()) + continue; + const auto infoStDev = info.stDev; QStorageInfoPrivate d(std::move(info)); d.retrieveVolumeInfo(); if (d.bytesTotal <= 0 && d.rootPath != u'/') continue; - if (infoStDev != deviceIdForPath(d.rootPath)) - continue; // probably something mounted over this mountpoint d.name = labelForDevice(d, infoStDev); volumes.emplace_back(QStorageInfo(*new QStorageInfoPrivate(std::move(d)))); }