Add a virtual method to the FileSystem base class to allow updating the boot

sector for a file system after it has been moved or copied. Currently, only
NTFS requires such a special treatment, however.

Implement this virtual method for NTFS and update the file system's start
sector in the NTFS boot sector according to
http://thestarman.pcministry.com/asm/mbr/NTFSBR.htm

BUG: 202329

svn path=/trunk/extragear/sysadmin/partitionmanager/; revision=1005978
This commit is contained in:
Volker Lanz 2009-08-02 18:47:17 +00:00
parent 079f24cc6d
commit 0e518a5a9d
6 changed files with 69 additions and 4 deletions

View File

@ -185,6 +185,20 @@ QString FileSystem::readUUID(const QString& deviceNode) const
}
/** Give implementations of FileSystem a chance to update the boot sector after the
file system has been moved or copied.
@param report Report to write status information to
@param deviceNode the device node for the Partition the FileSystem is on
@return true on success
*/
bool FileSystem::updateBootSector(Report& report, const QString& deviceNode) const
{
Q_UNUSED(report);
Q_UNUSED(deviceNode);
return true;
}
/** @return the minimum capacity valid for this FileSystem in bytes */
qint64 FileSystem::minCapacity() const
{

View File

@ -93,6 +93,7 @@ class FileSystem
virtual bool check(Report& report, const QString& deviceNode) const;
virtual bool updateUUID(Report& report, const QString& deviceNode) const;
virtual QString readUUID(const QString& deviceNode) const;
virtual bool updateBootSector(Report& report, const QString& deviceNode) const;
virtual SupportType supportGetUsed() const { return SupportNone; } /**< @return SupportType for getting used capacity */
virtual SupportType supportGetLabel() const { return SupportNone; } /**< @return SupportType for reading label*/

View File

@ -21,12 +21,19 @@
#include "util/externalcommand.h"
#include "util/capacity.h"
#include "util/report.h"
#include "util/globallog.h"
#include <klocale.h>
#include <kdebug.h>
#include <QString>
#include <QStringList>
#include <QFile>
#include <ctime>
#include <uuid/uuid.h>
#include <algorithm>
namespace FS
{
@ -163,4 +170,40 @@ namespace FS
return cmd.waitFor(-1);
}
bool ntfs::updateBootSector(Report& report, const QString& deviceNode) const
{
report.line() << i18nc("@info/plain", "Updating boot sector for NTFS file system on partition <filename>%1</filename>.", deviceNode);
quint32 n = firstSector();
char* s = reinterpret_cast<char*>(&n);
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
std::swap(s[0], s[3]);
std::swap(s[1], s[2]);
#endif
QFile device(deviceNode);
if (!device.open(QFile::ReadWrite | QFile::Unbuffered))
{
log() << i18nc("@info/plain", "Could not open partition <filename>%1</filename> for writing when trying to update the NTFS boot sector.", deviceNode);
return false;
}
if (!device.seek(0x1c))
{
log() << i18nc("@info/plain", "Could not seek to position 0x1c on partition <filename>%1</filename> when trying to update the NTFS boot sector.", deviceNode);
return false;
}
if (device.write(s, 4) != 4)
{
log() << i18nc("@info/plain", "Could not write new start sector to partition <filename>%1</filename> when trying to update the NTFS boot sector.", deviceNode);
return false;
}
log() << i18nc("@info/plain", "Updated NTFS boot sector for partition <filename>%1</filename> successfully.", deviceNode);
return true;
}
}

View File

@ -50,6 +50,7 @@ namespace FS
virtual bool resize(Report& report, const QString& deviceNode, qint64 length) const;
virtual bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel);
virtual bool updateUUID(Report& report, const QString& deviceNode) const;
virtual bool updateBootSector(Report& report, const QString& deviceNode) const;
virtual SupportType supportGetUsed() const { return m_GetUsed; }
virtual SupportType supportGetLabel() const { return m_GetLabel; }

View File

@ -92,6 +92,9 @@ bool CopyFileSystemJob::run(Report& parent)
}
}
if (rval)
rval = targetPartition().fileSystem().updateBootSector(*report, targetPartition().deviceNode());
jobFinished(*report, rval);
return rval;

View File

@ -50,7 +50,7 @@ qint32 MoveFileSystemJob::numSteps() const
bool MoveFileSystemJob::run(Report& parent)
{
bool rval = false;
Report* report = jobStarted(parent);
// A scope for moveSource and moveTarget, so CopyTargetDevice's dtor runs before we
@ -73,14 +73,17 @@ bool MoveFileSystemJob::run(Report& parent)
const qint64 savedLength = partition().fileSystem().length() - 1;
partition().fileSystem().setFirstSector(newStart());
partition().fileSystem().setLastSector(newStart() + savedLength);
}
}
else if (!rollbackCopyBlocks(*report, moveTarget, moveSource))
report->line() << i18nc("@info/plain", "Rollback for file system on partition <filename>%1</filename> failed.", partition().deviceNode());
report->line() << i18nc("@info/plain", "Closing device. This may take a few seconds.");
}
}
if (rval)
rval = partition().fileSystem().updateBootSector(*report, partition().deviceNode());
jobFinished(*report, rval);
return rval;