QStorageInfo: Add support for obtaining subvolume names
[ChangeLog][QtCore][QStorageInfo] Added QStorageInfo::subvolume(), which returns the name of the subvolume of a volume that was mounted, if one was detected. This is currently implemented only for btrfs on Linux. Change-Id: Ib57b52598e2f452985e9fffd1459f3145d733ce5 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
6cabb18bc2
commit
590ca43603
@ -260,13 +260,33 @@ QByteArray QStorageInfo::fileSystemType() const
|
|||||||
devpath like \c /dev/sda0 for local storages. On Windows, it returns the UNC
|
devpath like \c /dev/sda0 for local storages. On Windows, it returns the UNC
|
||||||
path starting with \c \\\\?\\ for local storages (in other words, the volume GUID).
|
path starting with \c \\\\?\\ for local storages (in other words, the volume GUID).
|
||||||
|
|
||||||
\sa rootPath()
|
\sa rootPath(), subvolume()
|
||||||
*/
|
*/
|
||||||
QByteArray QStorageInfo::device() const
|
QByteArray QStorageInfo::device() const
|
||||||
{
|
{
|
||||||
return d->device;
|
return d->device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.8
|
||||||
|
Returns the subvolume name for this volume.
|
||||||
|
|
||||||
|
Some filesystem types allow multiple subvolumes inside one device, which
|
||||||
|
may be mounted in different paths. If the subvolume could be detected, it
|
||||||
|
is returned here. The format of the subvolume name is specific to each
|
||||||
|
filesystem type.
|
||||||
|
|
||||||
|
If this volume was not mounted from a subvolume of a larger filesystem or
|
||||||
|
if the subvolume could not be detected, this function returns an empty byte
|
||||||
|
array.
|
||||||
|
|
||||||
|
\sa device()
|
||||||
|
*/
|
||||||
|
QByteArray QStorageInfo::subvolume() const
|
||||||
|
{
|
||||||
|
return d->subvolume;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the human-readable name of a filesystem, usually called \c label.
|
Returns the human-readable name of a filesystem, usually called \c label.
|
||||||
|
|
||||||
|
@ -71,6 +71,7 @@ public:
|
|||||||
|
|
||||||
QString rootPath() const;
|
QString rootPath() const;
|
||||||
QByteArray device() const;
|
QByteArray device() const;
|
||||||
|
QByteArray subvolume() const;
|
||||||
QByteArray fileSystemType() const;
|
QByteArray fileSystemType() const;
|
||||||
QString name() const;
|
QString name() const;
|
||||||
QString displayName() const;
|
QString displayName() const;
|
||||||
@ -100,7 +101,7 @@ inline bool operator==(const QStorageInfo &first, const QStorageInfo &second)
|
|||||||
{
|
{
|
||||||
if (first.d == second.d)
|
if (first.d == second.d)
|
||||||
return true;
|
return true;
|
||||||
return first.device() == second.device();
|
return first.device() == second.device() && first.rootPath() == second.rootPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator!=(const QStorageInfo &first, const QStorageInfo &second)
|
inline bool operator!=(const QStorageInfo &first, const QStorageInfo &second)
|
||||||
|
@ -85,6 +85,7 @@ protected:
|
|||||||
public:
|
public:
|
||||||
QString rootPath;
|
QString rootPath;
|
||||||
QByteArray device;
|
QByteArray device;
|
||||||
|
QByteArray subvolume;
|
||||||
QByteArray fileSystemType;
|
QByteArray fileSystemType;
|
||||||
QString name;
|
QString name;
|
||||||
|
|
||||||
|
@ -120,6 +120,7 @@ public:
|
|||||||
inline QString rootPath() const;
|
inline QString rootPath() const;
|
||||||
inline QByteArray fileSystemType() const;
|
inline QByteArray fileSystemType() const;
|
||||||
inline QByteArray device() const;
|
inline QByteArray device() const;
|
||||||
|
inline QByteArray options() const;
|
||||||
private:
|
private:
|
||||||
#if defined(Q_OS_BSD4)
|
#if defined(Q_OS_BSD4)
|
||||||
QT_STATFSBUF *stat_buf;
|
QT_STATFSBUF *stat_buf;
|
||||||
@ -133,6 +134,7 @@ private:
|
|||||||
QByteArray m_rootPath;
|
QByteArray m_rootPath;
|
||||||
QByteArray m_fileSystemType;
|
QByteArray m_fileSystemType;
|
||||||
QByteArray m_device;
|
QByteArray m_device;
|
||||||
|
QByteArray m_options;
|
||||||
#elif defined(Q_OS_LINUX) || defined(Q_OS_HURD)
|
#elif defined(Q_OS_LINUX) || defined(Q_OS_HURD)
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
mntent mnt;
|
mntent mnt;
|
||||||
@ -228,6 +230,11 @@ inline QByteArray QStorageIterator::device() const
|
|||||||
return QByteArray(stat_buf[currentIndex].f_mntfromname);
|
return QByteArray(stat_buf[currentIndex].f_mntfromname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline QByteArray QStorageIterator::options() const
|
||||||
|
{
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
#elif defined(Q_OS_SOLARIS)
|
#elif defined(Q_OS_SOLARIS)
|
||||||
|
|
||||||
static const char pathMounted[] = "/etc/mnttab";
|
static const char pathMounted[] = "/etc/mnttab";
|
||||||
@ -301,6 +308,7 @@ inline bool QStorageIterator::next()
|
|||||||
m_device = data.at(0);
|
m_device = data.at(0);
|
||||||
m_rootPath = data.at(1);
|
m_rootPath = data.at(1);
|
||||||
m_fileSystemType = data.at(2);
|
m_fileSystemType = data.at(2);
|
||||||
|
m_options = data.at(3);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -320,6 +328,11 @@ inline QByteArray QStorageIterator::device() const
|
|||||||
return m_device;
|
return m_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline QByteArray QStorageIterator::options() const
|
||||||
|
{
|
||||||
|
return m_options;
|
||||||
|
}
|
||||||
|
|
||||||
#elif defined(Q_OS_LINUX) || defined(Q_OS_HURD)
|
#elif defined(Q_OS_LINUX) || defined(Q_OS_HURD)
|
||||||
|
|
||||||
static const char pathMounted[] = "/etc/mtab";
|
static const char pathMounted[] = "/etc/mtab";
|
||||||
@ -363,6 +376,11 @@ inline QByteArray QStorageIterator::device() const
|
|||||||
return QByteArray(mnt.mnt_fsname);
|
return QByteArray(mnt.mnt_fsname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline QByteArray QStorageIterator::options() const
|
||||||
|
{
|
||||||
|
return QByteArray(mnt.mnt_opts);
|
||||||
|
}
|
||||||
|
|
||||||
#elif defined(Q_OS_HAIKU)
|
#elif defined(Q_OS_HAIKU)
|
||||||
inline QStorageIterator::QStorageIterator()
|
inline QStorageIterator::QStorageIterator()
|
||||||
{
|
{
|
||||||
@ -420,6 +438,11 @@ inline QByteArray QStorageIterator::device() const
|
|||||||
return m_device;
|
return m_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline QByteArray QStorageIterator::options() const
|
||||||
|
{
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
inline QStorageIterator::QStorageIterator()
|
inline QStorageIterator::QStorageIterator()
|
||||||
@ -455,8 +478,35 @@ inline QByteArray QStorageIterator::device() const
|
|||||||
return QByteArray();
|
return QByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline QByteArray QStorageIterator::options() const
|
||||||
|
{
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static QByteArray extractSubvolume(const QStorageIterator &it)
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
if (it.fileSystemType() == "btrfs") {
|
||||||
|
const QByteArrayList opts = it.options().split(',');
|
||||||
|
QByteArray id;
|
||||||
|
for (const QByteArray &opt : opts) {
|
||||||
|
static const char subvol[] = "subvol=";
|
||||||
|
static const char subvolid[] = "subvolid=";
|
||||||
|
if (opt.startsWith(subvol))
|
||||||
|
return std::move(opt).mid(strlen(subvol));
|
||||||
|
if (opt.startsWith(subvolid))
|
||||||
|
id = std::move(opt).mid(strlen(subvolid));
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we didn't find the subvolume name, return the subvolume ID
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
void QStorageInfoPrivate::initRootPath()
|
void QStorageInfoPrivate::initRootPath()
|
||||||
{
|
{
|
||||||
rootPath = QFileInfo(rootPath).canonicalFilePath();
|
rootPath = QFileInfo(rootPath).canonicalFilePath();
|
||||||
@ -483,6 +533,7 @@ void QStorageInfoPrivate::initRootPath()
|
|||||||
rootPath = mountDir;
|
rootPath = mountDir;
|
||||||
device = it.device();
|
device = it.device();
|
||||||
fileSystemType = fsName;
|
fileSystemType = fsName;
|
||||||
|
subvolume = extractSubvolume(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,11 +48,15 @@ void printVolumes(const QList<QStorageInfo> &volumes, int (*printer)(const char
|
|||||||
if (info.fileSystemType() != fsAndType)
|
if (info.fileSystemType() != fsAndType)
|
||||||
fsAndType += " (" + info.fileSystemType() + ')';
|
fsAndType += " (" + info.fileSystemType() + ')';
|
||||||
|
|
||||||
printf("%-19s R%c ", fsAndType.constData(), info.isReadOnly() ? 'O' : 'W');
|
printer("%-19s R%c ", fsAndType.constData(), info.isReadOnly() ? 'O' : 'W');
|
||||||
if (fsAndType.size() > 19)
|
if (fsAndType.size() > 19)
|
||||||
printf("\n%23s", "");
|
printer("\n%23s", "");
|
||||||
|
|
||||||
printf("%10llu %10llu %5u ", info.bytesTotal() / 1024, info.bytesFree() / 1024, info.blockSize());
|
printer("%10llu %10llu %5u ", info.bytesTotal() / 1024, info.bytesFree() / 1024, info.blockSize());
|
||||||
printf("%-16s %s\n", qPrintable(info.name()), qPrintable(info.rootPath()));
|
if (!info.subvolume().isEmpty())
|
||||||
|
printer("subvol=%-18s ", qPrintable(info.subvolume()));
|
||||||
|
else
|
||||||
|
printer("%-25s ", qPrintable(info.name()));
|
||||||
|
printer("%s\n", qPrintable(info.rootPath()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user