diff --git a/src/backend/corebackenddevice.h b/src/backend/corebackenddevice.h index cd8c835..116f46d 100644 --- a/src/backend/corebackenddevice.h +++ b/src/backend/corebackenddevice.h @@ -94,22 +94,21 @@ public: virtual bool createPartitionTable(Report& report, const PartitionTable& ptable) = 0; /** - * Read sectors from an opened device into a buffer. + * Read data from an opened device into a buffer. * @param buffer the buffer to write the read data to - * @param offset offset sector where to start reading on the device - * @param numSectors number of sectors to read + * @param offset offset byte where to start reading on the device + * @param size the number of bytes to read * @return true on success */ - virtual bool readSectors(void* buffer, qint64 offset, qint64 numSectors) = 0; + virtual bool readData(QByteArray& buffer, qint64 offset, qint64 size) = 0; /** - * Write sectors from a buffer to an exclusively opened device. + * Write data from a buffer to an exclusively opened device. * @param buffer the buffer with the data - * @param offset offset sector where to start writing to the device - * @param numSectors number of sectors to write + * @param offset offset byte where to start writing to the device * @return true on success */ - virtual bool writeSectors(void* buffer, qint64 offset, qint64 numSectors) = 0; + virtual bool writeData(QByteArray& buffer, qint64 offset) = 0; protected: void setExclusive(bool b) { diff --git a/src/core/copysource.h b/src/core/copysource.h index 2faa185..d1d9ae6 100644 --- a/src/core/copysource.h +++ b/src/core/copysource.h @@ -41,13 +41,12 @@ protected: public: virtual bool open() = 0; - virtual qint64 sectorSize() const = 0; - virtual bool readSectors(void* buffer, qint64 readOffset, qint64 numSectors) = 0; + virtual bool readData(QByteArray& buffer, qint64 readOffset, qint64 size) = 0; virtual qint64 length() const = 0; virtual bool overlaps(const CopyTarget& target) const = 0; - virtual qint64 firstSector() const = 0; - virtual qint64 lastSector() const = 0; + virtual qint64 firstByte() const = 0; + virtual qint64 lastByte() const = 0; private: }; diff --git a/src/core/copysourcedevice.cpp b/src/core/copysourcedevice.cpp index cb41ccb..fff46ba 100644 --- a/src/core/copysourcedevice.cpp +++ b/src/core/copysourcedevice.cpp @@ -28,14 +28,14 @@ /** Constructs a CopySource on the given Device @param d Device from which to copy - @param firstsector First sector that will be copied - @param lastsector Last sector that will be copied + @param firstbyte the first byte that will be copied + @param lastbyte the last byte that will be copied */ -CopySourceDevice::CopySourceDevice(Device& d, qint64 firstsector, qint64 lastsector) : +CopySourceDevice::CopySourceDevice(Device& d, qint64 firstbyte, qint64 lastbyte) : CopySource(), m_Device(d), - m_FirstSector(firstsector), - m_LastSector(lastsector), + m_FirstByte(firstbyte), + m_LastByte(lastbyte), m_BackendDevice(nullptr) { } @@ -55,36 +55,28 @@ bool CopySourceDevice::open() return m_BackendDevice != nullptr; } -/** Returns the Device's sector size - @return the sector size -*/ -qint64 CopySourceDevice::sectorSize() const -{ - return device().logicalSize(); -} - /** Returns the length of this CopySource @return length of the copy source */ qint64 CopySourceDevice::length() const { - return lastSector() - firstSector() + 1; + return lastByte() - firstByte() + 1; } -/** Reads a given number of sectors from the Device into the given buffer. +/** Reads a given number of bytes from the Device into the given buffer. Note that @p readOffset must be greater or equal than zero. - @param buffer the buffer to store the read sectors in + @param buffer the buffer to store the read bytes in @param readOffset the offset to begin reading - @param numSectors the number of sector to read + @param size the number of bytes to read @return true if successful */ -bool CopySourceDevice::readSectors(void* buffer, qint64 readOffset, qint64 numSectors) +bool CopySourceDevice::readData(QByteArray& buffer, qint64 readOffset, qint64 size) { Q_ASSERT(readOffset >= 0); - return m_BackendDevice->readSectors(buffer, readOffset, numSectors); + return m_BackendDevice->readData(buffer, readOffset, size); } /** Checks if this CopySourceDevice overlaps with the given CopyTarget @@ -100,11 +92,11 @@ bool CopySourceDevice::overlaps(const CopyTarget& target) const return false; // overlapping at the front? - if (firstSector() <= t.firstSector() && lastSector() >= t.firstSector()) + if (firstByte() <= t.firstByte() && lastByte() >= t.firstByte()) return true; // overlapping at the back? - if (firstSector() <= t.lastSector() && lastSector() >= t.lastSector()) + if (firstByte() <= t.lastByte() && lastByte() >= t.lastByte()) return true; } catch (...) { } diff --git a/src/core/copysourcedevice.h b/src/core/copysourcedevice.h index 2352140..ad1be9b 100644 --- a/src/core/copysourcedevice.h +++ b/src/core/copysourcedevice.h @@ -39,21 +39,20 @@ class LIBKPMCORE_EXPORT CopySourceDevice : public CopySource Q_DISABLE_COPY(CopySourceDevice) public: - CopySourceDevice(Device& d, qint64 firstsector, qint64 lastsector); + CopySourceDevice(Device& d, qint64 firstbyte, qint64 lastbyte); ~CopySourceDevice(); public: bool open() override; - qint64 sectorSize() const override; - bool readSectors(void* buffer, qint64 readOffset, qint64 numSectors) override; + bool readData(QByteArray& buffer, qint64 readOffset, qint64 size) override; qint64 length() const override; bool overlaps(const CopyTarget& target) const override; - qint64 firstSector() const override { - return m_FirstSector; /**< @return first sector to copying */ + qint64 firstByte() const override { + return m_FirstByte; /**< @return first byte to copy */ } - qint64 lastSector() const override { - return m_LastSector; /**< @return last sector to copy */ + qint64 lastByte() const override { + return m_LastByte; /**< @return last byte to copy */ } Device& device() { @@ -65,8 +64,8 @@ public: protected: Device& m_Device; - const qint64 m_FirstSector; - const qint64 m_LastSector; + const qint64 m_FirstByte; + const qint64 m_LastByte; CoreBackendDevice* m_BackendDevice ; }; diff --git a/src/core/copysourcefile.cpp b/src/core/copysourcefile.cpp index d8ceff4..936aec0 100644 --- a/src/core/copysourcefile.cpp +++ b/src/core/copysourcefile.cpp @@ -23,12 +23,10 @@ /** Constructs a CopySourceFile from the given @p filename. @param filename filename of the file to copy from - @param sectorsize the sector size to assume for the file, usually the target Device's sector size */ -CopySourceFile::CopySourceFile(const QString& filename, qint64 sectorsize) : +CopySourceFile::CopySourceFile(const QString& filename) : CopySource(), - m_File(filename), - m_SectorSize(sectorsize) + m_File(filename) { } @@ -40,24 +38,25 @@ bool CopySourceFile::open() return file().open(QIODevice::ReadOnly); } -/** Returns the length of the file in sectors. - @return length of the file in sectors. +/** Returns the length of the file in bytes. + @return length of the file in bytes. */ qint64 CopySourceFile::length() const { - return QFileInfo(file()).size() / sectorSize(); + return QFileInfo(file()).size(); } -/** Reads the given number of sectors from the file into the given buffer. - @param buffer buffer to store the sectors read in +/** Reads the given number of bytes from the file into the given buffer. + @param buffer buffer to store the bytes read in @param readOffset offset where to begin reading - @param numSectors number of sectors to read + @param size the number of bytes to read @return true on success */ -bool CopySourceFile::readSectors(void* buffer, qint64 readOffset, qint64 numSectors) +bool CopySourceFile::readData(QByteArray& buffer, qint64 readOffset, qint64 size) { - if (!file().seek(readOffset * sectorSize())) + if (!file().seek(readOffset)) return false; - return file().read(static_cast(buffer), numSectors * sectorSize()) == numSectors * sectorSize(); + buffer = file().read(size); + return !buffer.isEmpty(); } diff --git a/src/core/copysourcefile.h b/src/core/copysourcefile.h index 5baf7d9..bad5894 100644 --- a/src/core/copysourcefile.h +++ b/src/core/copysourcefile.h @@ -36,23 +36,20 @@ class CopyTarget; class CopySourceFile : public CopySource { public: - CopySourceFile(const QString& filename, qint64 sectorsize); + CopySourceFile(const QString& filename); public: bool open() override; - bool readSectors(void* buffer, qint64 readOffset, qint64 numSectors) override; + bool readData(QByteArray& buffer, qint64 readOffset, qint64 size) override; qint64 length() const override; - qint64 sectorSize() const override { - return m_SectorSize; /**< @return the file's sector size */ - } bool overlaps(const CopyTarget&) const override { return false; /**< @return false for file */ } - qint64 firstSector() const override { + qint64 firstByte() const override { return 0; /**< @return 0 for file */ } - qint64 lastSector() const override { + qint64 lastByte() const override { return length(); /**< @return equal to length for file. @see length() */ } @@ -66,7 +63,6 @@ protected: protected: QFile m_File; - qint64 m_SectorSize; }; #endif diff --git a/src/core/copysourceshred.cpp b/src/core/copysourceshred.cpp index 1672f4c..b8d708e 100644 --- a/src/core/copysourceshred.cpp +++ b/src/core/copysourceshred.cpp @@ -20,12 +20,10 @@ /** Constructs a CopySourceShred with the given @p size @param s the size the copy source will (pretend to) have - @param sectorsize the sectorsize the copy source will (pretend to) have */ -CopySourceShred::CopySourceShred(qint64 s, qint64 sectorsize, bool randomShred) : +CopySourceShred::CopySourceShred(qint64 s, bool randomShred) : CopySource(), m_Size(s), - m_SectorSize(sectorsize), m_SourceFile(randomShred ? QStringLiteral("/dev/urandom") : QStringLiteral("/dev/zero")) { } @@ -38,23 +36,24 @@ bool CopySourceShred::open() return sourceFile().open(QIODevice::ReadOnly); } -/** Returns the length of the source in sectors. - @return length of the source in sectors. +/** Returns the length of the source in bytes. + @return length of the source in bytes. */ qint64 CopySourceShred::length() const { - return size() / sectorSize(); + return size(); } -/** Reads the given number of sectors from the source into the given buffer. - @param buffer buffer to store the sectors read in +/** Reads the given number of bytes from the source into the given buffer. + @param buffer buffer to store the data read in @param readOffset offset where to begin reading (unused) - @param numSectors number of sectors to read + @param size the number of bytes to read @return true on success */ -bool CopySourceShred::readSectors(void* buffer, qint64 readOffset, qint64 numSectors) +bool CopySourceShred::readData(QByteArray& buffer, qint64 readOffset, qint64 size) { Q_UNUSED(readOffset); - return sourceFile().read(static_cast(buffer), numSectors * sectorSize()) == numSectors * sectorSize(); + buffer = sourceFile().read(size); + return !buffer.isEmpty(); } diff --git a/src/core/copysourceshred.h b/src/core/copysourceshred.h index e22f21d..df83366 100644 --- a/src/core/copysourceshred.h +++ b/src/core/copysourceshred.h @@ -34,23 +34,20 @@ class CopyTarget; class CopySourceShred : public CopySource { public: - CopySourceShred(qint64 size, qint64 sectorsize, bool randomShred); + CopySourceShred(qint64 size, bool randomShred); public: bool open() override; - bool readSectors(void* buffer, qint64 readOffset, qint64 numSectors) override; + bool readData(QByteArray& buffer, qint64 readOffset, qint64 size) override; qint64 length() const override; - qint64 sectorSize() const override { - return m_SectorSize; /**< @return the file's sector size */ - } bool overlaps(const CopyTarget&) const override { return false; /**< @return false for shred source */ } - qint64 firstSector() const override { + qint64 firstByte() const override { return 0; /**< @return 0 for shred source */ } - qint64 lastSector() const override { + qint64 lastByte() const override { return length(); /**< @return equal to length for shred source. @see length() */ } @@ -67,7 +64,6 @@ protected: private: qint64 m_Size; - qint64 m_SectorSize; QFile m_SourceFile; }; diff --git a/src/core/copytarget.h b/src/core/copytarget.h index 0847bff..e68d715 100644 --- a/src/core/copytarget.h +++ b/src/core/copytarget.h @@ -35,27 +35,26 @@ class CopyTarget Q_DISABLE_COPY(CopyTarget) protected: - CopyTarget() : m_SectorsWritten(0) {} + CopyTarget() : m_BytesWritten(0) {} virtual ~CopyTarget() {} public: virtual bool open() = 0; - virtual qint64 sectorSize() const = 0; - virtual bool writeSectors(void* buffer, qint64 writeOffset, qint64 numSectors) = 0; - virtual qint64 firstSector() const = 0; - virtual qint64 lastSector() const = 0; + virtual bool writeData(QByteArray& buffer, qint64 writeOffset) = 0; + virtual qint64 firstByte() const = 0; + virtual qint64 lastByte() const = 0; - qint64 sectorsWritten() const { - return m_SectorsWritten; + qint64 bytesWritten() const { + return m_BytesWritten; } protected: - void setSectorsWritten(qint64 s) { - m_SectorsWritten = s; + void setBytesWritten(qint64 s) { + m_BytesWritten = s; } private: - qint64 m_SectorsWritten; + qint64 m_BytesWritten; }; #endif diff --git a/src/core/copytargetdevice.cpp b/src/core/copytargetdevice.cpp index 1ca1b38..c6c5c18 100644 --- a/src/core/copytargetdevice.cpp +++ b/src/core/copytargetdevice.cpp @@ -26,15 +26,15 @@ /** Constructs a device to copy to. @param d the Device to copy to - @param firstsector the first sector on the Device to write to - @param lastsector the last sector on the Device to write to + @param firstbyte the first byte on the Device to write to + @param lastbyte the last byte on the Device to write to */ -CopyTargetDevice::CopyTargetDevice(Device& d, qint64 firstsector, qint64 lastsector) : +CopyTargetDevice::CopyTargetDevice(Device& d, qint64 firstbyte, qint64 lastbyte) : CopyTarget(), m_Device(d), m_BackendDevice(nullptr), - m_FirstSector(firstsector), - m_LastSector(lastsector) + m_FirstByte(firstbyte), + m_LastByte(lastbyte) { } @@ -53,28 +53,21 @@ bool CopyTargetDevice::open() return m_BackendDevice != nullptr; } -/** @return the Device's sector size */ -qint64 CopyTargetDevice::sectorSize() const -{ - return device().logicalSize(); -} - -/** Writes the given number of sectors to the Device. +/** Writes the given number of bytes to the Device. Note that @p writeOffset must be greater or equal than zero. @param buffer the data to write @param writeOffset where to start writing on the Device - @param numSectors the number of sectors in @p buffer @return true on success */ -bool CopyTargetDevice::writeSectors(void* buffer, qint64 writeOffset, qint64 numSectors) +bool CopyTargetDevice::writeData(QByteArray& buffer, qint64 writeOffset) { Q_ASSERT(writeOffset >= 0); - bool rval = m_BackendDevice->writeSectors(buffer, writeOffset, numSectors); + bool rval = m_BackendDevice->writeData(buffer, writeOffset); if (rval) - setSectorsWritten(sectorsWritten() + numSectors); + setBytesWritten(bytesWritten() + buffer.size()); return rval; } diff --git a/src/core/copytargetdevice.h b/src/core/copytargetdevice.h index c39cb04..3dd94d7 100644 --- a/src/core/copytargetdevice.h +++ b/src/core/copytargetdevice.h @@ -41,18 +41,17 @@ class LIBKPMCORE_EXPORT CopyTargetDevice : public CopyTarget Q_DISABLE_COPY(CopyTargetDevice) public: - CopyTargetDevice(Device& d, qint64 firstsector, qint64 lastsector); + CopyTargetDevice(Device& d, qint64 firstbyte, qint64 lastbyte); ~CopyTargetDevice(); public: bool open() override; - qint64 sectorSize() const override; - bool writeSectors(void* buffer, qint64 writeOffset, qint64 numSectors) override; - qint64 firstSector() const override { - return m_FirstSector; /**< @return the first sector to write to */ + bool writeData(QByteArray& buffer, qint64 writeOffset) override; + qint64 firstByte() const override { + return m_FirstByte; /**< @return the first byte to write to */ } - qint64 lastSector() const override { - return m_LastSector; /**< @return the last sector to write to */ + qint64 lastByte() const override { + return m_LastByte; /**< @return the last byte to write to */ } Device& device() { @@ -65,8 +64,8 @@ public: protected: Device& m_Device; CoreBackendDevice* m_BackendDevice; - const qint64 m_FirstSector; - const qint64 m_LastSector; + const qint64 m_FirstByte; + const qint64 m_LastByte; }; #endif diff --git a/src/core/copytargetfile.cpp b/src/core/copytargetfile.cpp index 1b016e3..508f9b2 100644 --- a/src/core/copytargetfile.cpp +++ b/src/core/copytargetfile.cpp @@ -19,12 +19,10 @@ /** Constructs a file to write to. @param filename name of the file to write to - @param sectorsize the "sector size" of the file to write to, usually the sector size of the CopySourceDevice */ -CopyTargetFile::CopyTargetFile(const QString& filename, qint64 sectorsize) : +CopyTargetFile::CopyTargetFile(const QString& filename) : CopyTarget(), - m_File(filename), - m_SectorSize(sectorsize) + m_File(filename) { } @@ -36,21 +34,20 @@ bool CopyTargetFile::open() return file().open(QIODevice::WriteOnly | QIODevice::Truncate); } -/** Writes the given number of sectors from the given buffer to the file. +/** Writes the given number of bytes from the given buffer to the file. @param buffer the data to write @param writeOffset where in the file to start writing - @param numSectors the number of sectors to write @return true on success */ -bool CopyTargetFile::writeSectors(void* buffer, qint64 writeOffset, qint64 numSectors) +bool CopyTargetFile::writeData(QByteArray& buffer, qint64 writeOffset) { - if (!file().seek(writeOffset * sectorSize())) + if (!file().seek(writeOffset)) return false; - bool rval = file().write(static_cast(buffer), numSectors * sectorSize()) == numSectors * sectorSize(); + bool rval = file().write(buffer) == buffer.size(); if (rval) - setSectorsWritten(sectorsWritten() + numSectors); + setBytesWritten(bytesWritten() + buffer.size()); return rval; } diff --git a/src/core/copytargetfile.h b/src/core/copytargetfile.h index e2b0f1b..3e3ef3e 100644 --- a/src/core/copytargetfile.h +++ b/src/core/copytargetfile.h @@ -36,20 +36,17 @@ class QString; class CopyTargetFile : public CopyTarget { public: - CopyTargetFile(const QString& filename, qint64 sectorsize); + CopyTargetFile(const QString& filename); public: bool open() override; - bool writeSectors(void* buffer, qint64 writeOffset, qint64 numSectors) override; + bool writeData(QByteArray& buffer, qint64 writeOffset) override; - qint64 sectorSize() const override { - return m_SectorSize; /**< @return the file's sector size */ - } - qint64 firstSector() const override { + qint64 firstByte() const override { return 0; /**< @return always 0 for a file */ } - qint64 lastSector() const override { - return sectorsWritten(); /**< @return the number of sectors written so far */ + qint64 lastByte() const override { + return bytesWritten(); /**< @return the number of bytes written so far */ } protected: @@ -62,7 +59,6 @@ protected: protected: QFile m_File; - qint64 m_SectorSize; }; #endif diff --git a/src/core/partition.h b/src/core/partition.h index 155bfd8..91edd3f 100644 --- a/src/core/partition.h +++ b/src/core/partition.h @@ -131,6 +131,12 @@ public: qint64 lastSector() const { return m_LastSector; /**< @return the Partition's last sector on the Device */ } + qint64 firstByte() const { + return firstSector() * sectorSize(); /**< @return the Partition's first byte on the Device */ + } + qint64 lastByte() const { + return firstByte() + length() * sectorSize() - 1; /**< @return the Partition's last byte on the Device */ + } qint64 sectorsUsed() const; qint64 sectorSize() const { return m_SectorSize; /**< @return the sector size on the Partition's Device */ diff --git a/src/fs/filesystem.h b/src/fs/filesystem.h index 636fb94..b4a7d0e 100644 --- a/src/fs/filesystem.h +++ b/src/fs/filesystem.h @@ -235,6 +235,12 @@ public: qint64 length() const { return lastSector() - firstSector() + 1; /**< @return the FileSystem's length */ } + qint64 firstByte() const { + return firstSector() * sectorSize(); /**< @return the FileSystem's first byte */ + } + qint64 lastByte() const { + return firstByte() + length() * sectorSize() - 1; /**< @return the FileSystem's last byte */ + } void setFirstSector(qint64 s) { m_FirstSector = s; /**< @param s the new first sector */ diff --git a/src/jobs/backupfilesystemjob.cpp b/src/jobs/backupfilesystemjob.cpp index 9d84f84..bf72e2f 100644 --- a/src/jobs/backupfilesystemjob.cpp +++ b/src/jobs/backupfilesystemjob.cpp @@ -56,8 +56,8 @@ bool BackupFileSystemJob::run(Report& parent) if (sourcePartition().fileSystem().supportBackup() == FileSystem::cmdSupportFileSystem) rval = sourcePartition().fileSystem().backup(*report, sourceDevice(), sourcePartition().deviceNode(), fileName()); else if (sourcePartition().fileSystem().supportBackup() == FileSystem::cmdSupportCore) { - CopySourceDevice copySource(sourceDevice(), sourcePartition().fileSystem().firstSector(), sourcePartition().fileSystem().lastSector()); - CopyTargetFile copyTarget(fileName(), sourceDevice().logicalSize()); + CopySourceDevice copySource(sourceDevice(), sourcePartition().fileSystem().firstByte(), sourcePartition().fileSystem().lastByte()); + CopyTargetFile copyTarget(fileName()); if (!copySource.open()) report->line() << xi18nc("@info:progress", "Could not open file system on source partition %1 for backup.", sourcePartition().deviceNode()); diff --git a/src/jobs/copyfilesystemjob.cpp b/src/jobs/copyfilesystemjob.cpp index 2c028f9..b7ea5d6 100644 --- a/src/jobs/copyfilesystemjob.cpp +++ b/src/jobs/copyfilesystemjob.cpp @@ -60,8 +60,8 @@ bool CopyFileSystemJob::run(Report& parent) else if (sourcePartition().fileSystem().supportCopy() == FileSystem::cmdSupportFileSystem) rval = sourcePartition().fileSystem().copy(*report, targetPartition().deviceNode(), sourcePartition().deviceNode()); else if (sourcePartition().fileSystem().supportCopy() == FileSystem::cmdSupportCore) { - CopySourceDevice copySource(sourceDevice(), sourcePartition().fileSystem().firstSector(), sourcePartition().fileSystem().lastSector()); - CopyTargetDevice copyTarget(targetDevice(), targetPartition().fileSystem().firstSector(), targetPartition().fileSystem().lastSector()); + CopySourceDevice copySource(sourceDevice(), sourcePartition().fileSystem().firstByte(), sourcePartition().fileSystem().lastByte()); + CopyTargetDevice copyTarget(targetDevice(), targetPartition().fileSystem().firstByte(), targetPartition().fileSystem().lastByte()); if (!copySource.open()) report->line() << xi18nc("@info:progress", "Could not open file system on source partition %1 for copying.", sourcePartition().deviceNode()); diff --git a/src/jobs/job.cpp b/src/jobs/job.cpp index 75b68a1..26f0318 100644 --- a/src/jobs/job.cpp +++ b/src/jobs/job.cpp @@ -26,7 +26,6 @@ #include "util/report.h" -#include #include #include @@ -39,78 +38,68 @@ Job::Job() : bool Job::copyBlocks(Report& report, CopyTarget& target, CopySource& source) { - /** @todo copyBlocks() assumes that source.sectorSize() == target.sectorSize(). */ - - if (source.sectorSize() != target.sectorSize()) { - report.line() << xi18nc("@info:progress", "The logical sector sizes in the source and target for copying are not the same. This is currently unsupported."); - return false; - } - bool rval = true; - const qint64 blockSize = 16065 * 8; // number of sectors per block to copy + const qint64 blockSize = 10 * 1024 * 1024; // number of bytes per block to copy const qint64 blocksToCopy = source.length() / blockSize; - qint64 readOffset = source.firstSector(); - qint64 writeOffset = target.firstSector(); - qint32 copyDir = 1; + qint64 readOffset = source.firstByte(); + qint64 writeOffset = target.firstByte(); + qint32 copyDirection = 1; - if (target.firstSector() > source.firstSector()) { - readOffset = source.firstSector() + source.length() - blockSize; - writeOffset = target.firstSector() + source.length() - blockSize; - copyDir = -1; + if (target.firstByte() > source.firstByte()) { + readOffset = source.firstByte() + source.length() - blockSize; + writeOffset = target.firstByte() + source.length() - blockSize; + copyDirection = -1; } - report.line() << xi18nc("@info:progress", "Copying %1 blocks (%2 sectors) from %3 to %4, direction: %5.", blocksToCopy, source.length(), readOffset, writeOffset, copyDir); + report.line() << xi18nc("@info:progress", "Copying %1 blocks (%2 bytes) from %3 to %4, direction: %5.", blocksToCopy, source.length(), readOffset, writeOffset, copyDirection); qint64 blocksCopied = 0; - void* buffer = malloc(blockSize * source.sectorSize()); + QByteArray buffer; int percent = 0; QTime t; t.start(); - while (blocksCopied < blocksToCopy) { - if (!(rval = source.readSectors(buffer, readOffset + blockSize * blocksCopied * copyDir, blockSize))) + if (!(rval = source.readData(buffer, readOffset + blockSize * blocksCopied * copyDirection, blockSize))) break; - if (!(rval = target.writeSectors(buffer, writeOffset + blockSize * blocksCopied * copyDir, blockSize))) + if (!(rval = target.writeData(buffer, writeOffset + blockSize * blocksCopied * copyDirection))) break; if (++blocksCopied * 100 / blocksToCopy != percent) { percent = blocksCopied * 100 / blocksToCopy; if (percent % 5 == 0 && t.elapsed() > 1000) { - const qint64 mibsPerSec = (blocksCopied * blockSize * source.sectorSize() / 1024 / 1024) / (t.elapsed() / 1000); + const qint64 mibsPerSec = (blocksCopied * blockSize / 1024 / 1024) / (t.elapsed() / 1000); const qint64 estSecsLeft = (100 - percent) * t.elapsed() / percent / 1000; report.line() << xi18nc("@info:progress", "Copying %1 MiB/second, estimated time left: %2", mibsPerSec, QTime(0, 0).addSecs(estSecsLeft).toString()); } emit progress(percent); } } - const qint64 lastBlock = source.length() % blockSize; // copy the remainder if (rval && lastBlock > 0) { Q_ASSERT(lastBlock < blockSize); - const qint64 lastBlockReadOffset = copyDir > 0 ? readOffset + blockSize * blocksCopied : source.firstSector(); - const qint64 lastBlockWriteOffset = copyDir > 0 ? writeOffset + blockSize * blocksCopied : target.firstSector(); + const qint64 lastBlockReadOffset = copyDirection > 0 ? readOffset + blockSize * blocksCopied : source.firstByte(); + const qint64 lastBlockWriteOffset = copyDirection > 0 ? writeOffset + blockSize * blocksCopied : target.firstByte(); report.line() << xi18nc("@info:progress", "Copying remainder of block size %1 from %2 to %3.", lastBlock, lastBlockReadOffset, lastBlockWriteOffset); - rval = source.readSectors(buffer, lastBlockReadOffset, lastBlock); + rval = source.readData(buffer, lastBlockReadOffset, lastBlock); if (rval) - rval = target.writeSectors(buffer, lastBlockWriteOffset, lastBlock); + rval = target.writeData(buffer, lastBlockWriteOffset); if (rval) emit progress(100); } - free(buffer); - report.line() << xi18ncp("@info:progress argument 2 is a string such as 7 sectors (localized accordingly)", "Copying 1 block (%2) finished.", "Copying %1 blocks (%2) finished.", blocksCopied, i18np("1 sector", "%1 sectors", target.sectorsWritten())); + report.line() << xi18ncp("@info:progress argument 2 is a string such as 7 bytes (localized accordingly)", "Copying 1 block (%2) finished.", "Copying %1 blocks (%2) finished.", blocksCopied, i18np("1 byte", "%1 bytes", target.bytesWritten())); return rval; } @@ -127,31 +116,31 @@ bool Job::rollbackCopyBlocks(Report& report, CopyTarget& origTarget, CopySource& CopyTargetDevice& ctd = dynamic_cast(origTarget); // default: use values as if we were copying from front to back. - qint64 undoSourceFirstSector = origTarget.firstSector(); - qint64 undoSourceLastSector = origTarget.firstSector() + origTarget.sectorsWritten() - 1; + qint64 undoSourceFirstByte = origTarget.firstByte(); + qint64 undoSourceLastByte = origTarget.firstByte() + origTarget.bytesWritten() - 1; - qint64 undoTargetFirstSector = origSource.firstSector(); - qint64 undoTargetLastSector = origSource.firstSector() + origTarget.sectorsWritten() - 1; + qint64 undoTargetFirstByte = origSource.firstByte(); + qint64 undoTargetLastByte = origSource.firstByte() + origTarget.bytesWritten() - 1; - if (origTarget.firstSector() > origSource.firstSector()) { + if (origTarget.firstByte() > origSource.firstByte()) { // we were copying from back to front - undoSourceFirstSector = origTarget.firstSector() + origSource.length() - origTarget.sectorsWritten(); - undoSourceLastSector = origTarget.firstSector() + origSource.length() - 1; + undoSourceFirstByte = origTarget.firstByte() + origSource.length() - origTarget.bytesWritten(); + undoSourceLastByte = origTarget.firstByte() + origSource.length() - 1; - undoTargetFirstSector = origSource.lastSector() - origTarget.sectorsWritten() + 1; - undoTargetLastSector = origSource.lastSector(); + undoTargetFirstByte = origSource.lastByte() - origTarget.bytesWritten() + 1; + undoTargetLastByte = origSource.lastByte(); } - report.line() << xi18nc("@info:progress", "Rollback from: First sector: %1, last sector: %2.", undoSourceFirstSector, undoSourceLastSector); - report.line() << xi18nc("@info:progress", "Rollback to: First sector: %1, last sector: %2.", undoTargetFirstSector, undoTargetLastSector); + report.line() << xi18nc("@info:progress", "Rollback from: First byte: %1, last byte: %2.", undoSourceFirstByte, undoSourceLastByte); + report.line() << xi18nc("@info:progress", "Rollback to: First byte: %1, last byte: %2.", undoTargetFirstByte, undoTargetLastByte); - CopySourceDevice undoSource(ctd.device(), undoSourceFirstSector, undoSourceLastSector); + CopySourceDevice undoSource(ctd.device(), undoSourceFirstByte, undoSourceLastByte); if (!undoSource.open()) { report.line() << xi18nc("@info:progress", "Could not open device %1 to rollback copying.", ctd.device().deviceNode()); return false; } - CopyTargetDevice undoTarget(csd.device(), undoTargetFirstSector, undoTargetLastSector); + CopyTargetDevice undoTarget(csd.device(), undoTargetFirstByte, undoTargetLastByte); if (!undoTarget.open()) { report.line() << xi18nc("@info:progress", "Could not open device %1 to rollback copying.", csd.device().deviceNode()); return false; diff --git a/src/jobs/movefilesystemjob.cpp b/src/jobs/movefilesystemjob.cpp index 5cd50f4..33c4e1a 100644 --- a/src/jobs/movefilesystemjob.cpp +++ b/src/jobs/movefilesystemjob.cpp @@ -55,8 +55,9 @@ bool MoveFileSystemJob::run(Report& parent) // say we're finished: The CopyTargetDevice dtor asks the backend to close the device // and that may take a while. { - CopySourceDevice moveSource(device(), partition().fileSystem().firstSector(), partition().fileSystem().lastSector()); - CopyTargetDevice moveTarget(device(), newStart(), newStart() + partition().fileSystem().length()); + qint64 length = partition().fileSystem().lastByte() - partition().fileSystem().firstByte(); + CopySourceDevice moveSource(device(), partition().fileSystem().firstByte(), partition().fileSystem().lastByte()); + CopyTargetDevice moveTarget(device(), newStart() * device().logicalSize(), newStart() * device().logicalSize() + length); if (!moveSource.open()) report->line() << xi18nc("@info:progress", "Could not open file system on partition %1 for moving.", partition().deviceNode()); diff --git a/src/jobs/restorefilesystemjob.cpp b/src/jobs/restorefilesystemjob.cpp index 1387726..6b77e6d 100644 --- a/src/jobs/restorefilesystemjob.cpp +++ b/src/jobs/restorefilesystemjob.cpp @@ -66,8 +66,8 @@ bool RestoreFileSystemJob::run(Report& parent) // Again, a scope for copyTarget and copySource. See MoveFileSystemJob::run() { // FileSystems are restored to _partitions_, so don't use first and last sector of file system here - CopyTargetDevice copyTarget(targetDevice(), targetPartition().firstSector(), targetPartition().lastSector()); - CopySourceFile copySource(fileName(), copyTarget.sectorSize()); + CopyTargetDevice copyTarget(targetDevice(), targetPartition().firstByte(), targetPartition().lastByte()); + CopySourceFile copySource(fileName()); if (!copySource.open()) report->line() << xi18nc("@info:progress", "Could not open backup file %1 to restore from.", fileName()); diff --git a/src/jobs/shredfilesystemjob.cpp b/src/jobs/shredfilesystemjob.cpp index 66f5b95..c713b5f 100644 --- a/src/jobs/shredfilesystemjob.cpp +++ b/src/jobs/shredfilesystemjob.cpp @@ -64,8 +64,8 @@ bool ShredFileSystemJob::run(Report& parent) // Again, a scope for copyTarget and copySource. See MoveFileSystemJob::run() { - CopyTargetDevice copyTarget(device(), partition().fileSystem().firstSector(), partition().fileSystem().lastSector()); - CopySourceShred copySource(partition().capacity(), copyTarget.sectorSize(), m_RandomShred); + CopyTargetDevice copyTarget(device(), partition().fileSystem().firstByte(), partition().fileSystem().lastByte()); + CopySourceShred copySource(partition().capacity(), m_RandomShred); if (!copySource.open()) report->line() << xi18nc("@info:progress", "Could not open random data source to overwrite file system."); diff --git a/src/ops/operation.h b/src/ops/operation.h index 0f1d7c1..d4dd29f 100644 --- a/src/ops/operation.h +++ b/src/ops/operation.h @@ -94,7 +94,7 @@ protected: virtual ~Operation(); Q_SIGNALS: - int progress(int); + void progress(int); void jobStarted(Job*, Operation*); void jobFinished(Job*, Operation*); diff --git a/src/plugins/dummy/dummydevice.cpp b/src/plugins/dummy/dummydevice.cpp index fb52984..ebd00eb 100644 --- a/src/plugins/dummy/dummydevice.cpp +++ b/src/plugins/dummy/dummydevice.cpp @@ -67,11 +67,11 @@ bool DummyDevice::createPartitionTable(Report& report, const PartitionTable& pta return true; } -bool DummyDevice::readSectors(void* buffer, qint64 offset, qint64 numSectors) +bool DummyDevice::readData(QByteArray& buffer, qint64 offset, qint64 size) { Q_UNUSED(buffer); Q_UNUSED(offset); - Q_UNUSED(numSectors); + Q_UNUSED(size); if (!isExclusive()) return false; @@ -79,11 +79,10 @@ bool DummyDevice::readSectors(void* buffer, qint64 offset, qint64 numSectors) return true; } -bool DummyDevice::writeSectors(void* buffer, qint64 offset, qint64 numSectors) +bool DummyDevice::writeData(QByteArray& buffer, qint64 offset) { Q_UNUSED(buffer); Q_UNUSED(offset); - Q_UNUSED(numSectors); if (!isExclusive()) return false; diff --git a/src/plugins/dummy/dummydevice.h b/src/plugins/dummy/dummydevice.h index bdf8e32..3810fe1 100644 --- a/src/plugins/dummy/dummydevice.h +++ b/src/plugins/dummy/dummydevice.h @@ -45,8 +45,8 @@ public: bool createPartitionTable(Report& report, const PartitionTable& ptable) override; - bool readSectors(void* buffer, qint64 offset, qint64 numSectors) override; - bool writeSectors(void* buffer, qint64 offset, qint64 numSectors) override; + bool readData(QByteArray& buffer, qint64 offset, qint64 size) override; + bool writeData(QByteArray& buffer, qint64 offset) override; }; #endif diff --git a/src/plugins/libparted/libparteddevice.cpp b/src/plugins/libparted/libparteddevice.cpp index f508017..4a3bc30 100644 --- a/src/plugins/libparted/libparteddevice.cpp +++ b/src/plugins/libparted/libparteddevice.cpp @@ -111,18 +111,22 @@ bool LibPartedDevice::createPartitionTable(Report& report, const PartitionTable& return LibPartedPartitionTable::commit(disk); } -bool LibPartedDevice::readSectors(void* buffer, qint64 offset, qint64 numSectors) +bool LibPartedDevice::readData(QByteArray& buffer, qint64 offset, qint64 size) +{ + if (!isExclusive()) + return false; + + void *data = malloc(size); + bool rval = ped_device_read(pedDevice(), data, offset / pedDevice()->sector_size, size / pedDevice()->sector_size); + buffer = QByteArray(static_cast(data), size); + free(data); + return rval; +} + +bool LibPartedDevice::writeData(QByteArray& buffer, qint64 offset) { if (!isExclusive()) return false; - return ped_device_read(pedDevice(), buffer, offset, numSectors); -} - -bool LibPartedDevice::writeSectors(void* buffer, qint64 offset, qint64 numSectors) -{ - if (!isExclusive()) - return false; - - return ped_device_write(pedDevice(), buffer, offset, numSectors); + return ped_device_write(pedDevice(), static_cast(buffer.constData()), offset / pedDevice()->sector_size, buffer.size() / pedDevice()->sector_size); } diff --git a/src/plugins/libparted/libparteddevice.h b/src/plugins/libparted/libparteddevice.h index 5958844..c8d98c0 100644 --- a/src/plugins/libparted/libparteddevice.h +++ b/src/plugins/libparted/libparteddevice.h @@ -47,8 +47,8 @@ public: bool createPartitionTable(Report& report, const PartitionTable& ptable) override; - bool readSectors(void* buffer, qint64 offset, qint64 numSectors) override; - bool writeSectors(void* buffer, qint64 offset, qint64 numSectors) override; + bool readData(QByteArray& buffer, qint64 offset, qint64 size) override; + bool writeData(QByteArray& buffer, qint64 offset) override; protected: PedDevice* pedDevice() {