QStorageInfo/Linux: reuse the file descriptor

We need it for the ioctl() to get the label and we already have it open.

Change-Id: If3345151ddf84c43a4f1fffd17d3f7f1312ca185
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
(cherry picked from commit 24b1e52a1a46e9c7801a1bfffb963e56610872a7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Thiago Macieira 2024-05-29 10:14:58 -03:00 committed by Qt Cherry-pick Bot
parent 55eae1b3bb
commit cb38b5026a

View File

@ -165,10 +165,9 @@ static inline auto retrieveLabels()
return result; return result;
} }
static std::optional<QString> retrieveLabelViaIoctl(const QString &path) static std::optional<QString> retrieveLabelViaIoctl(int fd)
{ {
// FS_IOC_GETFSLABEL was introduced in v4.18; previously it was btrfs-specific. // FS_IOC_GETFSLABEL was introduced in v4.18; previously it was btrfs-specific.
int fd = qt_safe_open(QFile::encodeName(path).constData(), QT_OPEN_RDONLY);
if (fd < 0) if (fd < 0)
return std::nullopt; return std::nullopt;
@ -176,15 +175,14 @@ static std::optional<QString> retrieveLabelViaIoctl(const QString &path)
// says) and the return code on success (0) does not indicate the length. // says) and the return code on success (0) does not indicate the length.
char label[FSLABEL_MAX] = {}; char label[FSLABEL_MAX] = {};
int r = ioctl(fd, FS_IOC_GETFSLABEL, &label); int r = ioctl(fd, FS_IOC_GETFSLABEL, &label);
close(fd);
if (r < 0) if (r < 0)
return std::nullopt; return std::nullopt;
return QString::fromUtf8(label); return QString::fromUtf8(label);
} }
static inline QString retrieveLabel(const QStorageInfoPrivate &d, quint64 deviceId) static inline QString retrieveLabel(const QStorageInfoPrivate &d, int fd, quint64 deviceId)
{ {
if (auto label = retrieveLabelViaIoctl(d.rootPath)) if (auto label = retrieveLabelViaIoctl(fd))
return *label; return *label;
deviceId = retrieveDeviceId(d.device, deviceId); deviceId = retrieveDeviceId(d.device, deviceId);
@ -290,7 +288,7 @@ void QStorageInfoPrivate::doStat()
if (best) { if (best) {
auto stDev = best->stDev; auto stDev = best->stDev;
setFromMountInfo(std::move(*best)); setFromMountInfo(std::move(*best));
name = retrieveLabel(*this, stDev); name = retrieveLabel(*this, fd, stDev);
} }
} }
@ -301,11 +299,11 @@ QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes()
return QList{root()}; return QList{root()};
std::optional<decltype(retrieveLabels())> labelMap; std::optional<decltype(retrieveLabels())> labelMap;
auto labelForDevice = [&labelMap](const QStorageInfoPrivate &d, quint64 devid) { auto labelForDevice = [&labelMap](const QStorageInfoPrivate &d, int fd, quint64 devid) {
if (d.fileSystemType == "tmpfs") if (d.fileSystemType == "tmpfs")
return QString(); return QString();
if (auto label = retrieveLabelViaIoctl(d.rootPath)) if (auto label = retrieveLabelViaIoctl(fd))
return *label; return *label;
devid = retrieveDeviceId(d.device, devid); devid = retrieveDeviceId(d.device, devid);
@ -346,7 +344,7 @@ QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes()
d.retrieveVolumeInfo(); d.retrieveVolumeInfo();
if (d.bytesTotal <= 0 && d.rootPath != u'/') if (d.bytesTotal <= 0 && d.rootPath != u'/')
continue; continue;
d.name = labelForDevice(d, infoStDev); d.name = labelForDevice(d, fd, infoStDev);
volumes.emplace_back(QStorageInfo(*new QStorageInfoPrivate(std::move(d)))); volumes.emplace_back(QStorageInfo(*new QStorageInfoPrivate(std::move(d))));
} }
return volumes; return volumes;