Replace readSectors/writeSectors backend functions.
New alternatives use QByteArray to store data and use bytes, not sectors.
This commit is contained in:
parent
6c7c636572
commit
72dfbe480a
|
@ -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) {
|
||||
|
|
|
@ -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:
|
||||
};
|
||||
|
|
|
@ -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 (...) {
|
||||
}
|
||||
|
|
|
@ -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
|
||||
;
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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.");
|
||||
|
|
|
@ -94,7 +94,7 @@ protected:
|
|||
virtual ~Operation();
|
||||
|
||||
Q_SIGNALS:
|
||||
int progress(int);
|
||||
void progress(int);
|
||||
void jobStarted(Job*, Operation*);
|
||||
void jobFinished(Job*, Operation*);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue