QStorageInfo/Linux: fix getting information on unmounted btrfs subvols
Amends 1cd6c6c69e9813c791f8bebb6c0c9214ce765060. Btrfs can have subvolumes and each one of them is assigned a device ID when the filesystem is loaded into the kernel. But subvolumes don't all have to be a mountpoint of their own: if we insist on matching device IDs, as initRootPath() was doing, we'd fail at finding the mount point. Fixes: QTBUG-121140 Change-Id: I76ffba14ece04f24b43efffd17ab39f503000dd7 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Ahmad Samir <a.samirh78@gmail.com> (cherry picked from commit 987abb92538f8657d861611b1ced4e7eaa660adf) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
90a723b7cd
commit
f3782300d2
@ -10,6 +10,8 @@
|
||||
#include <private/qcore_unix_p.h>
|
||||
#include <private/qtools_p.h>
|
||||
|
||||
#include <q20memory.h>
|
||||
|
||||
#include <linux/mount.h>
|
||||
#include <sys/statfs.h>
|
||||
|
||||
@ -199,15 +201,31 @@ quint64 QStorageInfoPrivate::initRootPath()
|
||||
// # mount | tail -2
|
||||
// tmpfs on /tmp/foo/bar type tmpfs (rw,relatime,inode64)
|
||||
// tmpfs on /tmp/foo type tmpfs (rw,relatime,inode64)
|
||||
// But just in case there's a mount --move, we ensure the device ID does
|
||||
// match.
|
||||
//
|
||||
// We try to match the device ID in case there's a mount --move.
|
||||
// We can't *rely* on it because some filesystems like btrfs will assign
|
||||
// device IDs to subvolumes that aren't listed in /proc/self/mountinfo.
|
||||
|
||||
const QString oldRootPath = std::exchange(rootPath, QString());
|
||||
const dev_t rootPathDevId = deviceIdForPath(oldRootPath);
|
||||
MountInfo *best = nullptr;
|
||||
for (auto it = infos.rbegin(); it != infos.rend(); ++it) {
|
||||
if (rootPathDevId != it->stDev || !isParentOf(it->mountPoint, oldRootPath))
|
||||
if (!isParentOf(it->mountPoint, oldRootPath))
|
||||
continue;
|
||||
auto stDev = it->stDev;
|
||||
setFromMountInfo(std::move(*it));
|
||||
if (rootPathDevId == it->stDev) {
|
||||
// device ID matches; this is definitely the best option
|
||||
best = q20::to_address(it);
|
||||
break;
|
||||
}
|
||||
if (!best) {
|
||||
// if we can't find a device ID match, this parent path is probably
|
||||
// the correct one
|
||||
best = q20::to_address(it);
|
||||
}
|
||||
}
|
||||
if (best) {
|
||||
auto stDev = best->stDev;
|
||||
setFromMountInfo(std::move(*best));
|
||||
return stDev;
|
||||
}
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user