diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2023-09-22 14:02:03 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2023-10-21 15:21:27 -0700 |
commit | 4107e4d8ca835b8d7d632589f12effea76b19d96 (patch) | |
tree | 39477988a0406a60f9fe43473f8d5a795c7a88b3 /src/corelib/io | |
parent | 3e330a79ec8d273630660eefae42995018421c0c (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')
-rw-r--r-- | src/corelib/io/qstorageinfo_linux.cpp | 44 |
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; |