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;
|
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 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);
|
deviceId = retrieveDeviceId(device, deviceId);
|
||||||
if (!deviceId)
|
if (!deviceId)
|
||||||
return QString();
|
return QString();
|
||||||
|
|
||||||
auto filter = QDir::AllEntries | QDir::System | QDir::Hidden | QDir::NoDotAndDotDot;
|
QDirIterator it = devicesByLabel();
|
||||||
QDirIterator it(QLatin1StringView(pathDiskByLabel), filter);
|
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
QFileInfo fileInfo = it.nextFileInfo();
|
QFileInfo fileInfo = it.nextFileInfo();
|
||||||
QString name = fileInfo.fileName();
|
QString name = fileInfo.fileName();
|
||||||
@ -206,6 +231,17 @@ QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes()
|
|||||||
if (infos.empty())
|
if (infos.empty())
|
||||||
return QList{root()};
|
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;
|
QList<QStorageInfo> volumes;
|
||||||
for (MountInfo &info : infos) {
|
for (MountInfo &info : infos) {
|
||||||
QStorageInfoPrivate d(std::move(info));
|
QStorageInfoPrivate d(std::move(info));
|
||||||
@ -214,7 +250,7 @@ QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes()
|
|||||||
continue;
|
continue;
|
||||||
if (info.stDev != deviceIdForPath(d.rootPath))
|
if (info.stDev != deviceIdForPath(d.rootPath))
|
||||||
continue; // probably something mounted over this mountpoint
|
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))));
|
volumes.emplace_back(QStorageInfo(*new QStorageInfoPrivate(std::move(d))));
|
||||||
}
|
}
|
||||||
return volumes;
|
return volumes;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user