summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qstorageinfo_unix.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2016-06-20 17:05:08 -0700
committerThiago Macieira <thiago.macieira@intel.com>2016-07-06 03:59:50 +0000
commitb6345a515be9b8649738e812290f03e848f64378 (patch)
treee9dbcef5b81f887ed9b83cf0b1a3117f98435257 /src/corelib/io/qstorageinfo_unix.cpp
parent5fcac27359e66295c8cb15608b89599057c46425 (diff)
QStorageInfo: update the algorithm for ignored filesystems on Unix
Use the criterion that GNU coreutils' df uses: if the total size of the filesystem is zero, then it's pseudo. After all, if it contains files in a zero-sized volume, it has to be pseudo; if it contains nothing, then it's not very useful anyway. This would have caught most Linux pseudo-fs anyway, but the mount point check beforehand allows us to skip quite a few statfs() syscalls. The new algorithm also solves the following cases which had been mistakenly interpreted: * fuse and ZFS (source devices don't usually start with /) * pseudo-fs that were mounted from a device starting with / (the source device is usually ignored by the OS) This change is not testable automatically. Manual testing shows it still reports the same entries it used to on Linux, plus now shows FUSE (sshfs) mounts. Task-number: QTBUG-54235 Change-Id: Ib57b52598e2f452985e9fffd1459f06dcefcc5c6 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src/corelib/io/qstorageinfo_unix.cpp')
-rw-r--r--src/corelib/io/qstorageinfo_unix.cpp44
1 files changed, 30 insertions, 14 deletions
diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp
index 0daf041954..ae5c42ffd1 100644
--- a/src/corelib/io/qstorageinfo_unix.cpp
+++ b/src/corelib/io/qstorageinfo_unix.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com>
+** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -153,29 +154,41 @@ static bool isParentOf(const String &parent, const QString &dirName)
parent.size() == 1);
}
-static bool isPseudoFs(const QStorageIterator &it)
-{
+static bool shouldIncludeFs(const QStorageIterator &it)
+{
+ /*
+ * This function implements a heuristic algorithm to determine whether a
+ * given mount should be reported to the user. Our objective is to list
+ * only entries that the end-user would find useful.
+ *
+ * We therefore ignore:
+ * - mounted in /dev, /proc, /sys: special mounts
+ * (this will catch /sys/fs/cgroup, /proc/sys/fs/binfmt_misc, /dev/pts,
+ * some of which are tmpfs on Linux)
+ * - mounted in /var/run or /var/lock: most likely pseudofs
+ * (on earlier systemd versions, /var/run was a bind-mount of /run, so
+ * everything would be unnecessarily duplicated)
+ * - filesystem type is "rootfs": artifact of the root-pivot on some Linux
+ * initrd
+ * - if the filesystem total size is zero, it's a pseudo-fs (not checked here).
+ */
+
QString mountDir = it.rootPath();
if (isParentOf(QLatin1String("/dev"), mountDir)
|| isParentOf(QLatin1String("/proc"), mountDir)
|| isParentOf(QLatin1String("/sys"), mountDir)
|| isParentOf(QLatin1String("/var/run"), mountDir)
|| isParentOf(QLatin1String("/var/lock"), mountDir)) {
- return true;
+ return false;
}
- QByteArray type = it.fileSystemType();
- if (type == "tmpfs")
+#ifdef Q_OS_LINUX
+ if (it.fileSystemType() == "rootfs")
return false;
-#if defined(Q_OS_LINUX)
- if (type == "rootfs" || type == "rpc_pipefs")
- return true;
#endif
- if (!it.device().startsWith('/'))
- return true;
-
- return false;
+ // size checking in mountedVolumes()
+ return true;
}
#if defined(Q_OS_BSD4)
@@ -557,11 +570,14 @@ QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes()
QList<QStorageInfo> volumes;
while (it.next()) {
- if (isPseudoFs(it))
+ if (!shouldIncludeFs(it))
continue;
const QString mountDir = it.rootPath();
- volumes.append(QStorageInfo(mountDir));
+ QStorageInfo info(mountDir);
+ if (info.bytesTotal() == 0)
+ continue;
+ volumes.append(info);
}
return volumes;