Add support for creating file systems with label.

Some file systems such as UDF or F2FS only support writing labels when creating
them.

At the moment this only works in new partition dialog and not in the partition
properties dialog.
This commit is contained in:
Andrius Štikonas 2017-08-18 14:45:15 +03:00
parent 684a1ce073
commit 6a78a74515
7 changed files with 93 additions and 30 deletions

View File

@ -173,6 +173,21 @@ bool FileSystem::create(Report& report, const QString& deviceNode)
return true;
}
/** Creates a new FileSystem with a specified Label
@param report Report to write status information to
@param deviceNode the device node for the Partition to create the FileSystem on
@param label the new label for the FileSystem
@return true if successful
*/
bool FileSystem::createWithLabel(Report& report, const QString& deviceNode, const QString& label)
{
Q_UNUSED(report)
Q_UNUSED(deviceNode)
Q_UNUSED(label)
return true;
}
/** Scans a new FileSystem and load file system specific class variables.
* @param deviceNode the device node for the Partition to create the FileSystem on
*/

View File

@ -113,6 +113,7 @@ public:
virtual qint64 readUsedCapacity(const QString& deviceNode) const;
virtual QString readLabel(const QString& deviceNode) const;
virtual bool create(Report& report, const QString& deviceNode);
virtual bool createWithLabel(Report& report, const QString& deviceNode, const QString& label);
virtual bool resize(Report& report, const QString& deviceNode, qint64 newLength) const;
virtual bool resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 newLength) const;
virtual bool move(Report& report, const QString& deviceNode, qint64 newStartSector) const;
@ -135,6 +136,9 @@ public:
virtual CommandSupportType supportCreate() const {
return cmdSupportNone; /**< @return CommandSupportType for creating */
}
virtual CommandSupportType supportCreateWithLabel() const {
return cmdSupportNone; /**< @return CommandSupportType for creating */
}
virtual CommandSupportType supportGrow() const {
return cmdSupportNone; /**< @return CommandSupportType for growing */
}

View File

@ -78,31 +78,9 @@ qint64 udf::maxLabelLength() const
bool udf::create(Report& report, const QString& deviceNode)
{
// mkudffs from udftools prior to 1.1 does not check for partition limits and crashes
if ( length() > MAX_UDF_BLOCKS ) {
report.line() << xi18nc("@info:status", "Partition is too large");
int blkSize = blockSize(report, deviceNode);
if (blkSize == -1)
return false;
}
if ( length() < MIN_UDF_BLOCKS ) {
report.line() << xi18nc("@info:status", "Partition is too small");
return false;
}
// mkudffs from udftools prior to 1.1 is not able to detect logical (sector) size
// and UDF block size must match logical sector size of underlying media
int fd = open(deviceNode.toLocal8Bit().data(), O_RDONLY);
if ( fd < 0 ) {
report.line() << xi18nc("@info:status", "Cannot open device node");
return false;
}
int blksize;
int ret = ioctl(fd, BLKSSZGET, &blksize);
close(fd);
if ( ret != 0 ) {
report.line() << xi18nc("@info:status", "Cannot read logical (sector) size of device node");
return false;
}
ExternalCommand cmd(report, QStringLiteral("mkudffs"), {
QStringLiteral("--utf8"),
@ -110,7 +88,7 @@ bool udf::create(Report& report, const QString& deviceNode)
// For now format as UDF revision 2.01 for hard disk media type
QStringLiteral("--media-type=hd"),
QStringLiteral("--udfrev=0x201"),
QStringLiteral("--blocksize=") + QString::number(blksize),
QStringLiteral("--blocksize=") + QString::number(blkSize),
// TODO: Pass label as udf::create() parameter
// QStringLiteral("--lvid=") + label,
// QStringLiteral("--vid=") + shortlabel,
@ -118,4 +96,56 @@ bool udf::create(Report& report, const QString& deviceNode)
});
return cmd.run(-1) && cmd.exitCode() == 0;
}
bool udf::createWithLabel(Report& report, const QString& deviceNode, const QString& label)
{
int blkSize = blockSize(report, deviceNode);
if (blkSize == -1)
return false;
ExternalCommand cmd(report, QStringLiteral("mkudffs"), {
QStringLiteral("--utf8"),
// TODO: Add GUI option for choosing different optical disks and UDF revision
// For now format as UDF revision 2.01 for hard disk media type
QStringLiteral("--media-type=hd"),
QStringLiteral("--udfrev=0x201"),
QStringLiteral("--blocksize=") + QString::number(blkSize),
// TODO: Pass label as udf::create() parameter
QStringLiteral("--lvid=") + label,
// QStringLiteral("--vid=") + shortlabel,
deviceNode
});
return cmd.run(-1) && cmd.exitCode() == 0;
}
int udf::blockSize(Report& report, const QString& deviceNode)
{
// mkudffs from udftools prior to 1.1 does not check for partition limits and crashes
if ( length() > MAX_UDF_BLOCKS ) {
report.line() << xi18nc("@info:status", "Partition is too large");
return -1;
}
if ( length() < MIN_UDF_BLOCKS ) {
report.line() << xi18nc("@info:status", "Partition is too small");
return -1;
}
// mkudffs from udftools prior to 1.1 is not able to detect logical (sector) size
// and UDF block size must match logical sector size of underlying media
int fd = open(deviceNode.toLocal8Bit().data(), O_RDONLY);
if ( fd < 0 ) {
report.line() << xi18nc("@info:status", "Cannot open device node");
return -1;
}
int blksize;
int ret = ioctl(fd, BLKSSZGET, &blksize);
close(fd);
if ( ret != 0 ) {
report.line() << xi18nc("@info:status", "Cannot read logical (sector) size of device node");
return -1;
}
return blksize;
}
}

View File

@ -43,6 +43,7 @@ public:
void init() override;
bool create(Report& report, const QString& deviceNode) override;
bool createWithLabel(Report& report, const QString& deviceNode, const QString& label) override;
CommandSupportType supportGetLabel() const override {
return cmdSupportCore;
@ -50,6 +51,9 @@ public:
CommandSupportType supportCreate() const override {
return m_Create;
}
CommandSupportType supportCreateWithLabel() const override {
return m_Create;
}
CommandSupportType supportMove() const override {
return cmdSupportCore;
}
@ -71,6 +75,9 @@ public:
public:
static CommandSupportType m_Create;
private:
int blockSize(Report& report, const QString& deviceNode);
};
}

View File

@ -35,10 +35,11 @@
/** Creates a new CreateFileSystemJob
@param p the Partition the FileSystem to create is on
*/
CreateFileSystemJob::CreateFileSystemJob(Device& d, Partition& p) :
CreateFileSystemJob::CreateFileSystemJob(Device& d, Partition& p, const QString& label) :
Job(),
m_Device(d),
m_Partition(p)
m_Partition(p),
m_Label(label)
{
}
@ -51,8 +52,13 @@ bool CreateFileSystemJob::run(Report& parent)
if (partition().fileSystem().type() == FileSystem::Unformatted)
return true;
bool createResult;
if (partition().fileSystem().supportCreate() == FileSystem::cmdSupportFileSystem) {
if (partition().fileSystem().create(*report, partition().deviceNode())) {
if (partition().fileSystem().supportCreateWithLabel() == FileSystem::cmdSupportFileSystem)
createResult = partition().fileSystem().createWithLabel(*report, partition().deviceNode(), m_Label);
else
createResult = partition().fileSystem().create(*report, partition().deviceNode());
if (createResult) {
if (device().type() == Device::Disk_Device) {
CoreBackendDevice* backendDevice = CoreBackendManager::self()->backend()->openDevice(device().deviceNode());

View File

@ -33,7 +33,7 @@ class QString;
class CreateFileSystemJob : public Job
{
public:
CreateFileSystemJob(Device& d, Partition& p);
CreateFileSystemJob(Device& d, Partition& p, const QString& label = {});
public:
bool run(Report& parent) override;
@ -57,6 +57,7 @@ protected:
private:
Device& m_Device;
Partition& m_Partition;
const QString& m_Label;
};
#endif

View File

@ -62,7 +62,7 @@ NewOperation::NewOperation(Device& d, Partition* p) :
// label. The operation stack will merge these operations with this one here
// and if the jobs don't exist things will break.
m_CreateFileSystemJob = new CreateFileSystemJob(targetDevice(), newPartition());
m_CreateFileSystemJob = new CreateFileSystemJob(targetDevice(), newPartition(), fs.label());
addJob(createFileSystemJob());
if (fs.type() == FileSystem::Lvm2_PV) {