File indexing completed on 2024-05-05 05:48:47

0001 /*
0002     SPDX-FileCopyrightText: 2008-2010 Volker Lanz <vl@fidra.de>
0003     SPDX-FileCopyrightText: 2013-2018 Andrius Štikonas <andrius@stikonas.eu>
0004     SPDX-FileCopyrightText: 2019 Yuri Chornoivan <yurchor@ukr.net>
0005     SPDX-FileCopyrightText: 2020 Arnaud Ferraris <arnaud.ferraris@collabora.com>
0006     SPDX-FileCopyrightText: 2020 Gaël PORTAY <gael.portay@collabora.com>
0007 
0008     SPDX-License-Identifier: GPL-3.0-or-later
0009 */
0010 
0011 #include "fs/reiserfs.h"
0012 
0013 #include "util/externalcommand.h"
0014 #include "util/capacity.h"
0015 
0016 #include <QRegularExpression>
0017 #include <QString>
0018 #include <QStringList>
0019 #include <QUuid>
0020 
0021 namespace FS
0022 {
0023 FileSystem::CommandSupportType reiserfs::m_GetUsed = FileSystem::cmdSupportNone;
0024 FileSystem::CommandSupportType reiserfs::m_GetLabel = FileSystem::cmdSupportNone;
0025 FileSystem::CommandSupportType reiserfs::m_Create = FileSystem::cmdSupportNone;
0026 FileSystem::CommandSupportType reiserfs::m_Grow = FileSystem::cmdSupportNone;
0027 FileSystem::CommandSupportType reiserfs::m_Shrink = FileSystem::cmdSupportNone;
0028 FileSystem::CommandSupportType reiserfs::m_Move = FileSystem::cmdSupportNone;
0029 FileSystem::CommandSupportType reiserfs::m_Check = FileSystem::cmdSupportNone;
0030 FileSystem::CommandSupportType reiserfs::m_Copy = FileSystem::cmdSupportNone;
0031 FileSystem::CommandSupportType reiserfs::m_Backup = FileSystem::cmdSupportNone;
0032 FileSystem::CommandSupportType reiserfs::m_SetLabel = FileSystem::cmdSupportNone;
0033 FileSystem::CommandSupportType reiserfs::m_UpdateUUID = FileSystem::cmdSupportNone;
0034 FileSystem::CommandSupportType reiserfs::m_GetUUID = FileSystem::cmdSupportNone;
0035 
0036 reiserfs::reiserfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
0037     FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::ReiserFS)
0038 {
0039 }
0040 
0041 void reiserfs::init()
0042 {
0043     m_GetLabel = cmdSupportCore;
0044     m_GetUsed = findExternal(QStringLiteral("debugreiserfs"), {}, 16) ? cmdSupportFileSystem : cmdSupportNone;
0045     m_SetLabel = findExternal(QStringLiteral("reiserfstune")) ? cmdSupportFileSystem : cmdSupportNone;
0046     m_Create = findExternal(QStringLiteral("mkfs.reiserfs")) ? cmdSupportFileSystem : cmdSupportNone;
0047     m_Check = findExternal(QStringLiteral("fsck.reiserfs")) ? cmdSupportFileSystem : cmdSupportNone;
0048     m_Move = m_Copy = (m_Check != cmdSupportNone) ? cmdSupportCore : cmdSupportNone;
0049     m_Grow = findExternal(QStringLiteral("resize_reiserfs"), {}, 16) ? cmdSupportFileSystem : cmdSupportNone;
0050     m_Shrink = (m_GetUsed != cmdSupportNone && m_Grow != cmdSupportNone) ? cmdSupportFileSystem : cmdSupportNone;
0051     m_Backup = cmdSupportCore;
0052     m_UpdateUUID = findExternal(QStringLiteral("reiserfstune")) ? cmdSupportFileSystem : cmdSupportNone;
0053     m_GetUUID = cmdSupportCore;
0054 }
0055 
0056 bool reiserfs::supportToolFound() const
0057 {
0058     return
0059         m_GetUsed != cmdSupportNone &&
0060         m_GetLabel != cmdSupportNone &&
0061         m_SetLabel != cmdSupportNone &&
0062         m_Create != cmdSupportNone &&
0063         m_Check != cmdSupportNone &&
0064         m_UpdateUUID != cmdSupportNone &&
0065         m_Grow != cmdSupportNone &&
0066         m_Shrink != cmdSupportNone &&
0067         m_Copy != cmdSupportNone &&
0068         m_Move != cmdSupportNone &&
0069         m_Backup != cmdSupportNone &&
0070         m_GetUUID != cmdSupportNone;
0071 }
0072 
0073 FileSystem::SupportTool reiserfs::supportToolName() const
0074 {
0075     return SupportTool(QStringLiteral("reiserfsprogs"), QUrl(QStringLiteral("https://reiser4.wiki.kernel.org/index.php/Reiserfsprogs")));
0076 }
0077 
0078 qint64 reiserfs::minCapacity() const
0079 {
0080     return 32 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
0081 }
0082 
0083 qint64 reiserfs::maxCapacity() const
0084 {
0085     return 16 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::TiB) - Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
0086 }
0087 
0088 int reiserfs::maxLabelLength() const
0089 {
0090     return 16;
0091 }
0092 
0093 qint64 reiserfs::readUsedCapacity(const QString& deviceNode) const
0094 {
0095     ExternalCommand cmd(QStringLiteral("debugreiserfs"), { deviceNode });
0096 
0097     if (cmd.run(-1) && cmd.exitCode() == 16) {
0098         qint64 blockCount = -1;
0099         QRegularExpression re(QStringLiteral("Count of blocks[^:]+: (\\d+)"));
0100         QRegularExpressionMatch reBlockCount = re.match(cmd.output());
0101 
0102         if (reBlockCount.hasMatch())
0103             blockCount = reBlockCount.captured(1).toLongLong();
0104 
0105         qint64 blockSize = -1;
0106         re.setPattern(QStringLiteral("Blocksize: (\\d+)"));
0107         QRegularExpressionMatch reBlockSize = re.match(cmd.output());
0108 
0109         if (reBlockSize.hasMatch())
0110             blockSize = reBlockSize.captured(1).toLongLong();
0111 
0112         qint64 freeBlocks = -1;
0113         re.setPattern(QStringLiteral("Free blocks[^:]+: (\\d+)"));
0114         QRegularExpressionMatch reFreeBlocks = re.match(cmd.output());
0115 
0116         if (reFreeBlocks.hasMatch())
0117             freeBlocks = reFreeBlocks.captured(1).toLongLong();
0118 
0119         if (blockCount > -1 && blockSize > -1 && freeBlocks > -1)
0120             return (blockCount - freeBlocks) * blockSize;
0121     }
0122 
0123     return -1;
0124 }
0125 
0126 bool reiserfs::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel)
0127 {
0128     ExternalCommand cmd(report, QStringLiteral("reiserfstune"), { QStringLiteral("--label"), newLabel, deviceNode });
0129     return cmd.run(-1) && cmd.exitCode() == 0;
0130 }
0131 
0132 bool reiserfs::check(Report& report, const QString& deviceNode) const
0133 {
0134     ExternalCommand cmd(report, QStringLiteral("fsck.reiserfs"), { QStringLiteral("--fix-fixable"), QStringLiteral("--quiet"), QStringLiteral("--yes"), deviceNode });
0135     return cmd.run(-1) && (cmd.exitCode() == 0 || cmd.exitCode() == 1 || cmd.exitCode() == 256);
0136 }
0137 
0138 bool reiserfs::create(Report& report, const QString& deviceNode)
0139 {
0140     ExternalCommand cmd(report, QStringLiteral("mkfs.reiserfs"), { QStringLiteral("-f"), deviceNode });
0141     return cmd.run(-1) && cmd.exitCode() == 0;
0142 }
0143 
0144 bool reiserfs::resize(Report& report, const QString& deviceNode, qint64 length) const
0145 {
0146     ExternalCommand cmd(report, QStringLiteral("resize_reiserfs"),
0147                         { deviceNode, QStringLiteral("-q"), QStringLiteral("-s"), QString::number(length) });
0148 
0149     bool rval = cmd.write(QByteArrayLiteral("y\n"));
0150 
0151     if (!rval)
0152         return false;
0153 
0154     if (!cmd.start(-1))
0155         return false;
0156 
0157     return cmd.exitCode() == 0 || cmd.exitCode() == 256;
0158 }
0159 
0160 bool reiserfs::resizeOnline(Report& report, const QString& deviceNode, const QString&, qint64 length) const
0161 {
0162     return resize(report, deviceNode, length);
0163 }
0164 
0165 bool reiserfs::updateUUID(Report& report, const QString& deviceNode) const
0166 {
0167     const QString uuid = QUuid::createUuid().toString().remove(QRegularExpression(QStringLiteral("\\{|\\}")));
0168     ExternalCommand cmd(report, QStringLiteral("reiserfstune"), { QStringLiteral("--uuid"), uuid, deviceNode });
0169     return cmd.run(-1) && cmd.exitCode() == 0;
0170 }
0171 }