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>
This commit is contained in:
parent
3e330a79ec
commit
4107e4d8ca
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user