Replace readSectors/writeSectors backend functions.

New alternatives use QByteArray to store data and use bytes, not sectors.
This commit is contained in:
Andrius Štikonas 2017-10-26 16:20:21 +01:00
parent 6c7c636572
commit 72dfbe480a
26 changed files with 175 additions and 207 deletions

View File

@ -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) {

View File

@ -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:
};

View File

@ -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 (...) {
}

View File

@ -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
;
};

View File

@ -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<char*>(buffer), numSectors * sectorSize()) == numSectors * sectorSize();
buffer = file().read(size);
return !buffer.isEmpty();
}

View File

@ -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

View File

@ -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<char*>(buffer), numSectors * sectorSize()) == numSectors * sectorSize();
buffer = sourceFile().read(size);
return !buffer.isEmpty();
}

View File

@ -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;
};

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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<char*>(buffer), numSectors * sectorSize()) == numSectors * sectorSize();
bool rval = file().write(buffer) == buffer.size();
if (rval)
setSectorsWritten(sectorsWritten() + numSectors);
setBytesWritten(bytesWritten() + buffer.size());
return rval;
}

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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 <filename>%1</filename> for backup.", sourcePartition().deviceNode());

View File

@ -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 <filename>%1</filename> for copying.", sourcePartition().deviceNode());

View File

@ -26,7 +26,6 @@
#include "util/report.h"
#include <QDebug>
#include <QIcon>
#include <QTime>
@ -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<CopyTargetDevice&>(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 <filename>%1</filename> 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 <filename>%1</filename> to rollback copying.", csd.device().deviceNode());
return false;

View File

@ -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 <filename>%1</filename> for moving.", partition().deviceNode());

View File

@ -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 <filename>%1</filename> to restore from.", fileName());

View File

@ -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.");

View File

@ -94,7 +94,7 @@ protected:
virtual ~Operation();
Q_SIGNALS:
int progress(int);
void progress(int);
void jobStarted(Job*, Operation*);
void jobFinished(Job*, Operation*);

View File

@ -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;

View File

@ -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

View File

@ -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<char*>(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<const void *>(buffer.constData()), offset / pedDevice()->sector_size, buffer.size() / pedDevice()->sector_size);
}

View File

@ -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() {