2020-09-28 00:45:21 +01:00
/*
SPDX - FileCopyrightText : 2008 - 2010 Volker Lanz < vl @ fidra . de >
SPDX - FileCopyrightText : 2013 - 2018 Andrius Š tikonas < andrius @ stikonas . eu >
SPDX - FileCopyrightText : 2020 Arnaud Ferraris < arnaud . ferraris @ collabora . com >
SPDX - FileCopyrightText : 2020 Gaël PORTAY < gael . portay @ collabora . com >
SPDX - License - Identifier : GPL - 3.0 - or - later
*/
2015-06-04 01:29:22 +01:00
# include "fs/jfs.h"
# include "util/externalcommand.h"
# include "util/report.h"
# include "util/capacity.h"
2016-05-12 16:37:37 +01:00
# include <QRegularExpression>
2019-06-12 17:41:11 +01:00
# include <QStringList>
2015-06-04 01:29:22 +01:00
# include <QTemporaryDir>
# include <KLocalizedString>
namespace FS
{
2015-07-13 15:16:36 +01:00
FileSystem : : CommandSupportType jfs : : m_GetUsed = FileSystem : : cmdSupportNone ;
FileSystem : : CommandSupportType jfs : : m_GetLabel = FileSystem : : cmdSupportNone ;
FileSystem : : CommandSupportType jfs : : m_Create = FileSystem : : cmdSupportNone ;
FileSystem : : CommandSupportType jfs : : m_Grow = FileSystem : : cmdSupportNone ;
FileSystem : : CommandSupportType jfs : : m_Move = FileSystem : : cmdSupportNone ;
FileSystem : : CommandSupportType jfs : : m_Check = FileSystem : : cmdSupportNone ;
FileSystem : : CommandSupportType jfs : : m_Copy = FileSystem : : cmdSupportNone ;
FileSystem : : CommandSupportType jfs : : m_Backup = FileSystem : : cmdSupportNone ;
FileSystem : : CommandSupportType jfs : : m_SetLabel = FileSystem : : cmdSupportNone ;
2020-03-21 13:18:13 +00:00
jfs : : jfs ( qint64 firstsector , qint64 lastsector , qint64 sectorsused , const QString & label , const QVariantMap & features ) :
2020-01-12 11:54:14 +00:00
FileSystem ( firstsector , lastsector , sectorsused , label , features , FileSystem : : Type : : Jfs )
2015-07-13 15:16:36 +01:00
{
}
void jfs : : init ( )
{
m_GetUsed = findExternal ( QStringLiteral ( " jfs_debugfs " ) ) ? cmdSupportFileSystem : cmdSupportNone ;
m_GetLabel = cmdSupportCore ;
2016-04-21 22:48:05 +01:00
m_SetLabel = findExternal ( QStringLiteral ( " jfs_tune " ) , { QStringLiteral ( " -V " ) } ) ? cmdSupportFileSystem : cmdSupportNone ;
m_Create = findExternal ( QStringLiteral ( " mkfs.jfs " ) , { QStringLiteral ( " -V " ) } ) ? cmdSupportFileSystem : cmdSupportNone ;
m_Grow = m_Check = findExternal ( QStringLiteral ( " fsck.jfs " ) , { QStringLiteral ( " -V " ) } ) ? cmdSupportFileSystem : cmdSupportNone ;
2015-07-13 15:16:36 +01:00
m_Copy = m_Move = ( m_Check ! = cmdSupportNone ) ? cmdSupportCore : cmdSupportNone ;
m_Backup = cmdSupportCore ;
}
bool jfs : : supportToolFound ( ) const
{
return
m_GetUsed ! = cmdSupportNone & &
m_GetLabel ! = cmdSupportNone & &
m_SetLabel ! = cmdSupportNone & &
m_Create ! = cmdSupportNone & &
m_Check ! = cmdSupportNone & &
// m_UpdateUUID != cmdSupportNone &&
m_Grow ! = cmdSupportNone & &
// m_Shrink != cmdSupportNone &&
m_Copy ! = cmdSupportNone & &
m_Move ! = cmdSupportNone & &
m_Backup ! = cmdSupportNone ;
// m_GetUUID != cmdSupportNone;
}
FileSystem : : SupportTool jfs : : supportToolName ( ) const
{
return SupportTool ( QStringLiteral ( " jfsutils " ) , QUrl ( QStringLiteral ( " http://jfs.sourceforge.net/ " ) ) ) ;
}
qint64 jfs : : minCapacity ( ) const
{
2018-04-09 15:14:34 +01:00
return 16 * Capacity : : unitFactor ( Capacity : : Unit : : Byte , Capacity : : Unit : : MiB ) ;
2015-07-13 15:16:36 +01:00
}
qint64 jfs : : maxCapacity ( ) const
{
2018-04-09 15:14:34 +01:00
return 16 * Capacity : : unitFactor ( Capacity : : Unit : : Byte , Capacity : : Unit : : TiB ) ;
2015-07-13 15:16:36 +01:00
}
2017-09-11 16:52:20 +01:00
int jfs : : maxLabelLength ( ) const
2015-07-13 15:16:36 +01:00
{
return 11 ;
}
qint64 jfs : : readUsedCapacity ( const QString & deviceNode ) const
{
ExternalCommand cmd ( QStringLiteral ( " jfs_debugfs " ) , QStringList ( ) < < deviceNode ) ;
2018-07-21 21:19:31 +01:00
if ( cmd . write ( QByteArrayLiteral ( " dm " ) ) & & cmd . start ( ) ) {
2015-07-13 15:16:36 +01:00
qint64 blockSize = - 1 ;
2016-05-12 16:37:37 +01:00
QRegularExpression re ( QStringLiteral ( " Block Size: ( \\ d+) " )) ;
QRegularExpressionMatch reBlockSize = re . match ( cmd . output ( ) ) ;
2015-07-13 15:16:36 +01:00
2016-05-12 16:37:37 +01:00
if ( reBlockSize . hasMatch ( ) )
blockSize = reBlockSize . captured ( 1 ) . toLongLong ( ) ;
2015-07-13 15:16:36 +01:00
qint64 nBlocks = - 1 ;
2016-05-12 16:37:37 +01:00
re . setPattern ( QStringLiteral ( " dn_mapsize: \\ s+0x( \\ x+) " ) ) ;
QRegularExpressionMatch renBlocks = re . match ( cmd . output ( ) ) ;
2015-07-13 15:16:36 +01:00
bool ok = false ;
2016-05-12 16:37:37 +01:00
if ( renBlocks . hasMatch ( ) ) {
nBlocks = renBlocks . captured ( 1 ) . toLongLong ( & ok , 16 ) ;
2015-07-13 15:16:36 +01:00
if ( ! ok )
nBlocks = - 1 ;
}
qint64 nFree = - 1 ;
2016-05-12 16:37:37 +01:00
re . setPattern ( QStringLiteral ( " dn_nfree: \\ s+0x( \\ x+) " ) ) ;
QRegularExpressionMatch renFree = re . match ( cmd . output ( ) ) ;
2015-07-13 15:16:36 +01:00
2016-05-12 16:37:37 +01:00
if ( renFree . hasMatch ( ) ) {
nFree = renFree . captured ( 1 ) . toLongLong ( & ok , 16 ) ;
2015-07-13 15:16:36 +01:00
if ( ! ok )
nFree = - 1 ;
}
if ( nBlocks > - 1 & & blockSize > - 1 & & nFree > - 1 )
return ( nBlocks - nFree ) * blockSize ;
}
return - 1 ;
}
bool jfs : : writeLabel ( Report & report , const QString & deviceNode , const QString & newLabel )
{
2016-04-21 22:48:05 +01:00
ExternalCommand cmd ( report , QStringLiteral ( " jfs_tune " ) , { QStringLiteral ( " -L " ) , newLabel , deviceNode } ) ;
2015-07-13 15:16:36 +01:00
return cmd . run ( - 1 ) & & cmd . exitCode ( ) = = 0 ;
}
2017-04-09 17:49:55 +01:00
bool jfs : : writeLabelOnline ( Report & report , const QString & deviceNode , const QString & mountPoint , const QString & newLabel )
{
Q_UNUSED ( mountPoint )
return writeLabel ( report , deviceNode , newLabel ) ;
}
2015-07-13 15:16:36 +01:00
bool jfs : : check ( Report & report , const QString & deviceNode ) const
{
2016-04-21 22:48:05 +01:00
ExternalCommand cmd ( report , QStringLiteral ( " fsck.jfs " ) , { QStringLiteral ( " -f " ) , deviceNode } ) ;
2015-07-13 15:16:36 +01:00
return cmd . run ( - 1 ) & & ( cmd . exitCode ( ) = = 0 | | cmd . exitCode ( ) = = 1 ) ;
}
2016-09-05 12:10:56 +01:00
bool jfs : : create ( Report & report , const QString & deviceNode )
2015-07-13 15:16:36 +01:00
{
2016-04-21 22:48:05 +01:00
ExternalCommand cmd ( report , QStringLiteral ( " mkfs.jfs " ) , { QStringLiteral ( " -q " ) , deviceNode } ) ;
2015-07-13 15:16:36 +01:00
return cmd . run ( - 1 ) & & cmd . exitCode ( ) = = 0 ;
}
bool jfs : : resize ( Report & report , const QString & deviceNode , qint64 ) const
{
QTemporaryDir tempDir ;
if ( ! tempDir . isValid ( ) ) {
2016-07-17 23:41:00 +01:00
report . line ( ) < < xi18nc ( " @info:progress " , " Resizing JFS file system on partition <filename>%1</filename> failed: Could not create temp dir. " , deviceNode ) ;
2015-07-13 15:16:36 +01:00
return false ;
}
bool rval = false ;
2016-08-08 02:01:35 +01:00
ExternalCommand mountCmd ( report , QStringLiteral ( " mount " ) , { QStringLiteral ( " --verbose " ) , QStringLiteral ( " --type " ) , QStringLiteral ( " jfs " ) , deviceNode , tempDir . path ( ) } ) ;
2015-07-13 15:16:36 +01:00
if ( mountCmd . run ( - 1 ) ) {
2016-08-08 02:01:35 +01:00
ExternalCommand resizeMountCmd ( report , QStringLiteral ( " mount " ) , { QStringLiteral ( " --verbose " ) , QStringLiteral ( " --type " ) , QStringLiteral ( " jfs " ) , QStringLiteral ( " --options " ) , QStringLiteral ( " remount,resize " ) , deviceNode , tempDir . path ( ) } ) ;
2015-07-13 15:16:36 +01:00
2016-08-08 02:01:35 +01:00
if ( resizeMountCmd . run ( - 1 ) & & resizeMountCmd . exitCode ( ) = = 0 )
2015-07-13 15:16:36 +01:00
rval = true ;
else
2016-07-17 23:41:00 +01:00
report . line ( ) < < xi18nc ( " @info:progress " , " Resizing JFS file system on partition <filename>%1</filename> failed: Remount failed. " , deviceNode ) ;
2015-07-13 15:16:36 +01:00
2016-04-21 22:48:05 +01:00
ExternalCommand unmountCmd ( report , QStringLiteral ( " umount " ) , { tempDir . path ( ) } ) ;
2015-07-13 15:16:36 +01:00
if ( ! unmountCmd . run ( - 1 ) )
2016-07-18 12:21:06 +01:00
report . line ( ) < < xi18nc ( " @info:progress " , " <warning>Resizing JFS file system on partition <filename>%1</filename>: Unmount failed.</warning> " , deviceNode ) ;
2015-07-13 15:16:36 +01:00
} else
2016-07-17 23:41:00 +01:00
report . line ( ) < < xi18nc ( " @info:progress " , " Resizing JFS file system on partition <filename>%1</filename> failed: Initial mount failed. " , deviceNode ) ;
2015-07-13 15:16:36 +01:00
return rval ;
}
2016-08-08 02:01:35 +01:00
bool jfs : : resizeOnline ( Report & report , const QString & deviceNode , const QString & mountPoint , qint64 ) const
{
ExternalCommand resizeMountCmd ( report , QStringLiteral ( " mount " ) , { QStringLiteral ( " --verbose " ) , QStringLiteral ( " --type " ) , QStringLiteral ( " jfs " ) , QStringLiteral ( " --options " ) , QStringLiteral ( " remount,resize " ) , deviceNode , mountPoint } ) ;
if ( resizeMountCmd . run ( - 1 ) & & resizeMountCmd . exitCode ( ) = = 0 )
return true ;
report . line ( ) < < xi18nc ( " @info:progress " , " Resizing JFS file system on partition <filename>%1</filename> failed: Remount failed. " , deviceNode ) ;
return false ;
}
2015-06-04 01:29:22 +01:00
}