summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qstorageinfo_linux.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2023-09-22 14:02:03 -0700
committerThiago Macieira <thiago.macieira@intel.com>2023-10-21 15:21:27 -0700
commit4107e4d8ca835b8d7d632589f12effea76b19d96 (patch)
tree39477988a0406a60f9fe43473f8d5a795c7a88b3 /src/corelib/io/qstorageinfo_linux.cpp
parent3e330a79ec8d273630660eefae42995018421c0c (diff)
QStorageInfo/Linux: avoid parsing /dev/disks/by-label for every entry
Instead, create a (flat) map of the entries that we can seek on while creating the list of mountedVolumes(). On my machine, that went down from 14 times to 1. Pick-to: 6.6 Change-Id: I9d43e5b91eb142d6945cfffd17875458541f28f9 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Diffstat (limited to 'src/corelib/io/qstorageinfo_linux.cpp')
-rw-r--r--src/corelib/io/qstorageinfo_linux.cpp44
1 files changed, 40 insertions, 4 deletions
diff --git a/src/corelib/io/qstorageinfo_linux.cpp b/src/corelib/io/qstorageinfo_linux.cpp
index d0102f2884..15bcd978fe 100644
--- a/src/corelib/io/qstorageinfo_linux.cpp
+++ b/src/corelib/io/qstorageinfo_linux.cpp
@@ -91,16 +91,41 @@ static inline quint64 retrieveDeviceId(const QByteArray &device, quint64 deviceI
return st.st_rdev;
}
-static inline QString retrieveLabel(const QByteArray &device, quint64 deviceId)
+static QDirIterator devicesByLabel()
{
static const char pathDiskByLabel[] = "/dev/disk/by-label";
+ static constexpr auto LabelFileFilter =
+ QDir::AllEntries | QDir::System | QDir::Hidden | QDir::NoDotAndDotDot;
+
+ return QDirIterator(QLatin1StringView(pathDiskByLabel), LabelFileFilter);
+}
+
+static inline auto retrieveLabels()
+{
+ struct Entry {
+ QString label;
+ quint64 deviceId;
+ };
+ QList<Entry> result;
+
+ QDirIterator it = devicesByLabel();
+ while (it.hasNext()) {
+ QFileInfo fileInfo = it.nextFileInfo();
+ quint64 deviceId = retrieveDeviceId(QFile::encodeName(fileInfo.filePath()));
+ if (!deviceId)
+ continue;
+ result.emplaceBack(Entry{ decodeFsEncString(fileInfo.fileName()), deviceId });
+ }
+ return result;
+}
+static inline QString retrieveLabel(const QByteArray &device, quint64 deviceId)
+{
deviceId = retrieveDeviceId(device, deviceId);
if (!deviceId)
return QString();
- auto filter = QDir::AllEntries | QDir::System | QDir::Hidden | QDir::NoDotAndDotDot;
- QDirIterator it(QLatin1StringView(pathDiskByLabel), filter);
+ QDirIterator it = devicesByLabel();
while (it.hasNext()) {
QFileInfo fileInfo = it.nextFileInfo();
QString name = fileInfo.fileName();
@@ -206,6 +231,17 @@ QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes()
if (infos.empty())
return QList{root()};
+ auto labelForDevice = [labelMap = retrieveLabels()](const QByteArray &device, quint64 devid) {
+ devid = retrieveDeviceId(device, devid);
+ if (!devid)
+ return QString();
+ for (auto &[deviceLabel, deviceId] : labelMap) {
+ if (devid == deviceId)
+ return deviceLabel;
+ }
+ return QString();
+ };
+
QList<QStorageInfo> volumes;
for (MountInfo &info : infos) {
QStorageInfoPrivate d(std::move(info));
@@ -214,7 +250,7 @@ QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes()
continue;
if (info.stDev != deviceIdForPath(d.rootPath))
continue; // probably something mounted over this mountpoint
- d.name = retrieveLabel(d.device, info.stDev);
+ d.name = labelForDevice(d.device, info.stDev);
volumes.emplace_back(QStorageInfo(*new QStorageInfoPrivate(std::move(d))));
}
return volumes;