summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2023-09-22 13:36:12 -0700
committerThiago Macieira <thiago.macieira@intel.com>2023-10-16 08:41:21 -0700
commitc82ed8b2795cbf6d82dfe3857fec7c16688137a4 (patch)
tree6e0fde832a6acbae54457eb48d6748ea4de43828
parent3f2b54f0a1749eb8a52e99dbba6af4839e36cb90 (diff)
QStorageInfo/Linux: avoid parsing /proc/self/mountinfo N+1 times
Mine has 41 lines, of which 22 are returned by parseMountInfo with filtering. That meant the file was parsed once to get the listing, then 22 times more to create a QStorageInfo for each entry. Now QStorageInfo::mountedVolumes() opens the file and parses it only once. Pick-to: 6.6 Change-Id: I9d43e5b91eb142d6945cfffd178752ef6c2122f2 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
-rw-r--r--src/corelib/io/qstorageinfo.cpp5
-rw-r--r--src/corelib/io/qstorageinfo.h1
-rw-r--r--src/corelib/io/qstorageinfo_linux.cpp8
-rw-r--r--src/corelib/io/qstorageinfo_linux_p.h11
-rw-r--r--src/corelib/io/qstorageinfo_p.h37
5 files changed, 37 insertions, 25 deletions
diff --git a/src/corelib/io/qstorageinfo.cpp b/src/corelib/io/qstorageinfo.cpp
index 2a12c2cd85..4f206bc907 100644
--- a/src/corelib/io/qstorageinfo.cpp
+++ b/src/corelib/io/qstorageinfo.cpp
@@ -37,6 +37,11 @@ QT_IMPL_METATYPE_EXTERN(QStorageInfo)
\snippet code/src_corelib_io_qstorageinfo.cpp 2
*/
+QStorageInfo::QStorageInfo(QStorageInfoPrivate &dd)
+ : d(&dd)
+{
+}
+
/*!
Constructs an empty QStorageInfo object.
diff --git a/src/corelib/io/qstorageinfo.h b/src/corelib/io/qstorageinfo.h
index d25eee1840..45869519bc 100644
--- a/src/corelib/io/qstorageinfo.h
+++ b/src/corelib/io/qstorageinfo.h
@@ -56,6 +56,7 @@ public:
static QStorageInfo root();
private:
+ explicit QStorageInfo(QStorageInfoPrivate &dd);
friend class QStorageInfoPrivate;
friend inline bool operator==(const QStorageInfo &first, const QStorageInfo &second)
{
diff --git a/src/corelib/io/qstorageinfo_linux.cpp b/src/corelib/io/qstorageinfo_linux.cpp
index 0bf6b9e238..8b53629e25 100644
--- a/src/corelib/io/qstorageinfo_linux.cpp
+++ b/src/corelib/io/qstorageinfo_linux.cpp
@@ -164,12 +164,12 @@ QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes()
QList<QStorageInfo> volumes;
for (MountInfo &info : infos) {
- QStorageInfo storage(info.mountPoint);
- storage.d->device = info.device;
- storage.d->fileSystemType = info.fsType;
- storage.d->subvolume = info.fsRoot;
+ QStorageInfoPrivate d(std::move(info));
+ d.retrieveVolumeInfo();
+ QStorageInfo storage(*new QStorageInfoPrivate(std::move(d)));
if (storage.bytesTotal() == 0 && storage != root())
continue;
+ storage.d->name = retrieveLabel(storage.d->device);
volumes.push_back(storage);
}
return volumes;
diff --git a/src/corelib/io/qstorageinfo_linux_p.h b/src/corelib/io/qstorageinfo_linux_p.h
index 1033d78f73..1a59ee910f 100644
--- a/src/corelib/io/qstorageinfo_linux_p.h
+++ b/src/corelib/io/qstorageinfo_linux_p.h
@@ -29,6 +29,7 @@
QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
+using MountInfo = QStorageInfoPrivate::MountInfo;
static const char MountInfoPath[] = "/proc/self/mountinfo";
@@ -152,16 +153,6 @@ static void tokenizeLine(std::array<QByteArrayView, FieldCount> &fields, QByteAr
}
}
-namespace {
-struct MountInfo {
- QString mountPoint;
- QByteArray fsType;
- QByteArray device;
- QByteArray fsRoot;
- dev_t stDev = 0;
-};
-}
-
// parseMountInfo() is called from:
// - QStorageInfoPrivate::initRootPath(), where a list of all mounted volumes is needed
// - QStorageInfoPrivate::mountedVolumes(), where some filesystem types are ignored
diff --git a/src/corelib/io/qstorageinfo_p.h b/src/corelib/io/qstorageinfo_p.h
index ae4ff02f0b..92bcdaac3d 100644
--- a/src/corelib/io/qstorageinfo_p.h
+++ b/src/corelib/io/qstorageinfo_p.h
@@ -28,10 +28,7 @@ inline Q_LOGGING_CATEGORY(lcStorageInfo, "qt.core.qstorageinfo", QtWarningMsg)
class QStorageInfoPrivate : public QSharedData
{
public:
- inline QStorageInfoPrivate() : QSharedData(),
- bytesTotal(-1), bytesFree(-1), bytesAvailable(-1), blockSize(-1),
- readOnly(false), ready(false), valid(false)
- {}
+ QStorageInfoPrivate() = default;
void initRootPath();
void doStat();
@@ -59,6 +56,24 @@ protected:
void retrieveLabel();
#elif defined(Q_OS_UNIX)
void retrieveVolumeInfo();
+
+# ifdef Q_OS_LINUX
+public:
+ struct MountInfo {
+ QString mountPoint;
+ QByteArray fsType;
+ QByteArray device;
+ QByteArray fsRoot;
+ dev_t stDev = 0;
+ };
+ QStorageInfoPrivate(MountInfo &&info)
+ : rootPath(std::move(info.mountPoint)),
+ device(std::move(info.device)),
+ subvolume(std::move(info.fsRoot)),
+ fileSystemType(std::move(info.fsType))
+ {
+ }
+# endif
#endif
public:
@@ -68,14 +83,14 @@ public:
QByteArray fileSystemType;
QString name;
- qint64 bytesTotal;
- qint64 bytesFree;
- qint64 bytesAvailable;
- ulong blockSize;
+ qint64 bytesTotal = -1;
+ qint64 bytesFree = -1;
+ qint64 bytesAvailable = -1;
+ ulong blockSize = ulong(-1);
- bool readOnly;
- bool ready;
- bool valid;
+ bool readOnly = false;
+ bool ready = false;
+ bool valid = false;
};
// Common helper functions