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; 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. /** Scans a new FileSystem and load file system specific class variables.
* @param deviceNode the device node for the Partition to create the FileSystem on * @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 qint64 readUsedCapacity(const QString& deviceNode) const;
virtual QString readLabel(const QString& deviceNode) const; virtual QString readLabel(const QString& deviceNode) const;
virtual bool create(Report& report, const QString& deviceNode); 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 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 resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 newLength) const;
virtual bool move(Report& report, const QString& deviceNode, qint64 newStartSector) const; virtual bool move(Report& report, const QString& deviceNode, qint64 newStartSector) const;
@ -135,6 +136,9 @@ public:
virtual CommandSupportType supportCreate() const { virtual CommandSupportType supportCreate() const {
return cmdSupportNone; /**< @return CommandSupportType for creating */ return cmdSupportNone; /**< @return CommandSupportType for creating */
} }
virtual CommandSupportType supportCreateWithLabel() const {
return cmdSupportNone; /**< @return CommandSupportType for creating */
}
virtual CommandSupportType supportGrow() const { virtual CommandSupportType supportGrow() const {
return cmdSupportNone; /**< @return CommandSupportType for growing */ return cmdSupportNone; /**< @return CommandSupportType for growing */
} }

View File

@ -78,31 +78,9 @@ qint64 udf::maxLabelLength() const
bool udf::create(Report& report, const QString& deviceNode) bool udf::create(Report& report, const QString& deviceNode)
{ {
// mkudffs from udftools prior to 1.1 does not check for partition limits and crashes int blkSize = blockSize(report, deviceNode);
if ( length() > MAX_UDF_BLOCKS ) { if (blkSize == -1)
report.line() << xi18nc("@info:status", "Partition is too large");
return false; 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"), { ExternalCommand cmd(report, QStringLiteral("mkudffs"), {
QStringLiteral("--utf8"), 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 // For now format as UDF revision 2.01 for hard disk media type
QStringLiteral("--media-type=hd"), QStringLiteral("--media-type=hd"),
QStringLiteral("--udfrev=0x201"), QStringLiteral("--udfrev=0x201"),
QStringLiteral("--blocksize=") + QString::number(blksize), QStringLiteral("--blocksize=") + QString::number(blkSize),
// TODO: Pass label as udf::create() parameter // TODO: Pass label as udf::create() parameter
// QStringLiteral("--lvid=") + label, // QStringLiteral("--lvid=") + label,
// QStringLiteral("--vid=") + shortlabel, // QStringLiteral("--vid=") + shortlabel,
@ -118,4 +96,56 @@ bool udf::create(Report& report, const QString& deviceNode)
}); });
return cmd.run(-1) && cmd.exitCode() == 0; 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; void init() override;
bool create(Report& report, const QString& deviceNode) override; bool create(Report& report, const QString& deviceNode) override;
bool createWithLabel(Report& report, const QString& deviceNode, const QString& label) override;
CommandSupportType supportGetLabel() const override { CommandSupportType supportGetLabel() const override {
return cmdSupportCore; return cmdSupportCore;
@ -50,6 +51,9 @@ public:
CommandSupportType supportCreate() const override { CommandSupportType supportCreate() const override {
return m_Create; return m_Create;
} }
CommandSupportType supportCreateWithLabel() const override {
return m_Create;
}
CommandSupportType supportMove() const override { CommandSupportType supportMove() const override {
return cmdSupportCore; return cmdSupportCore;
} }
@ -71,6 +75,9 @@ public:
public: public:
static CommandSupportType m_Create; static CommandSupportType m_Create;
private:
int blockSize(Report& report, const QString& deviceNode);
}; };
} }

View File

@ -35,10 +35,11 @@
/** Creates a new CreateFileSystemJob /** Creates a new CreateFileSystemJob
@param p the Partition the FileSystem to create is on @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(), Job(),
m_Device(d), 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) if (partition().fileSystem().type() == FileSystem::Unformatted)
return true; return true;
bool createResult;
if (partition().fileSystem().supportCreate() == FileSystem::cmdSupportFileSystem) { 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) { if (device().type() == Device::Disk_Device) {
CoreBackendDevice* backendDevice = CoreBackendManager::self()->backend()->openDevice(device().deviceNode()); CoreBackendDevice* backendDevice = CoreBackendManager::self()->backend()->openDevice(device().deviceNode());

View File

@ -33,7 +33,7 @@ class QString;
class CreateFileSystemJob : public Job class CreateFileSystemJob : public Job
{ {
public: public:
CreateFileSystemJob(Device& d, Partition& p); CreateFileSystemJob(Device& d, Partition& p, const QString& label = {});
public: public:
bool run(Report& parent) override; bool run(Report& parent) override;
@ -57,6 +57,7 @@ protected:
private: private:
Device& m_Device; Device& m_Device;
Partition& m_Partition; Partition& m_Partition;
const QString& m_Label;
}; };
#endif #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 // label. The operation stack will merge these operations with this one here
// and if the jobs don't exist things will break. // 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()); addJob(createFileSystemJob());
if (fs.type() == FileSystem::Lvm2_PV) { if (fs.type() == FileSystem::Lvm2_PV) {