diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2016-06-20 17:53:42 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2016-09-03 06:41:33 +0000 |
commit | 590ca436032cb828fc882fde9c0e99e0f450a061 (patch) | |
tree | 57deac0f3a730ca71b211f3b30405cfa661da99b /src/corelib | |
parent | 6cabb18bc2c983fc7013273841739a3490b55f55 (diff) |
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>
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/io/qstorageinfo.cpp | 22 | ||||
-rw-r--r-- | src/corelib/io/qstorageinfo.h | 3 | ||||
-rw-r--r-- | src/corelib/io/qstorageinfo_p.h | 1 | ||||
-rw-r--r-- | src/corelib/io/qstorageinfo_unix.cpp | 51 |
4 files changed, 75 insertions, 2 deletions
diff --git a/src/corelib/io/qstorageinfo.cpp b/src/corelib/io/qstorageinfo.cpp index 3773b72606..9885da1af9 100644 --- a/src/corelib/io/qstorageinfo.cpp +++ b/src/corelib/io/qstorageinfo.cpp @@ -260,7 +260,7 @@ QByteArray QStorageInfo::fileSystemType() const 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). - \sa rootPath() + \sa rootPath(), subvolume() */ QByteArray QStorageInfo::device() const { @@ -268,6 +268,26 @@ QByteArray QStorageInfo::device() const } /*! + \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. Not all filesystems support this feature. In this case, the value returned by diff --git a/src/corelib/io/qstorageinfo.h b/src/corelib/io/qstorageinfo.h index 8941c11a16..e2d9747ceb 100644 --- a/src/corelib/io/qstorageinfo.h +++ b/src/corelib/io/qstorageinfo.h @@ -71,6 +71,7 @@ public: QString rootPath() const; QByteArray device() const; + QByteArray subvolume() const; QByteArray fileSystemType() const; QString name() const; QString displayName() const; @@ -100,7 +101,7 @@ inline bool operator==(const QStorageInfo &first, const QStorageInfo &second) { if (first.d == second.d) 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) diff --git a/src/corelib/io/qstorageinfo_p.h b/src/corelib/io/qstorageinfo_p.h index a14fa8480a..ec5bb785e3 100644 --- a/src/corelib/io/qstorageinfo_p.h +++ b/src/corelib/io/qstorageinfo_p.h @@ -85,6 +85,7 @@ protected: public: QString rootPath; QByteArray device; + QByteArray subvolume; QByteArray fileSystemType; QString name; diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index ae5c42ffd1..fcc7b8ca50 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -120,6 +120,7 @@ public: inline QString rootPath() const; inline QByteArray fileSystemType() const; inline QByteArray device() const; + inline QByteArray options() const; private: #if defined(Q_OS_BSD4) QT_STATFSBUF *stat_buf; @@ -133,6 +134,7 @@ private: QByteArray m_rootPath; QByteArray m_fileSystemType; QByteArray m_device; + QByteArray m_options; #elif defined(Q_OS_LINUX) || defined(Q_OS_HURD) FILE *fp; mntent mnt; @@ -228,6 +230,11 @@ inline QByteArray QStorageIterator::device() const return QByteArray(stat_buf[currentIndex].f_mntfromname); } +inline QByteArray QStorageIterator::options() const +{ + return QByteArray(); +} + #elif defined(Q_OS_SOLARIS) static const char pathMounted[] = "/etc/mnttab"; @@ -301,6 +308,7 @@ inline bool QStorageIterator::next() m_device = data.at(0); m_rootPath = data.at(1); m_fileSystemType = data.at(2); + m_options = data.at(3); return true; } @@ -320,6 +328,11 @@ inline QByteArray QStorageIterator::device() const return m_device; } +inline QByteArray QStorageIterator::options() const +{ + return m_options; +} + #elif defined(Q_OS_LINUX) || defined(Q_OS_HURD) static const char pathMounted[] = "/etc/mtab"; @@ -363,6 +376,11 @@ inline QByteArray QStorageIterator::device() const return QByteArray(mnt.mnt_fsname); } +inline QByteArray QStorageIterator::options() const +{ + return QByteArray(mnt.mnt_opts); +} + #elif defined(Q_OS_HAIKU) inline QStorageIterator::QStorageIterator() { @@ -420,6 +438,11 @@ inline QByteArray QStorageIterator::device() const return m_device; } +inline QByteArray QStorageIterator::options() const +{ + return QByteArray(); +} + #else inline QStorageIterator::QStorageIterator() @@ -455,8 +478,35 @@ inline QByteArray QStorageIterator::device() const return QByteArray(); } +inline QByteArray QStorageIterator::options() const +{ + return QByteArray(); +} + #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() { rootPath = QFileInfo(rootPath).canonicalFilePath(); @@ -483,6 +533,7 @@ void QStorageInfoPrivate::initRootPath() rootPath = mountDir; device = it.device(); fileSystemType = fsName; + subvolume = extractSubvolume(it); } } } |