Commit cfa52aed authored by Harald Sitter's avatar Harald Sitter 🌈
Browse files

sftp: fix offset handling on short reads

reads that came back with less data are fairly garbage to handle.

the offset is increased when we make requests with read_begin so the
original offset when we enter readchunks is the offset as if all pending
requests had returned.
async_read reduces that offset when a request cames back short.
since we still want the missing data we make a new request for the
missing data both we and libssh modify the offset as part of that
re-requesting.
after that dance we need to restore the most original offset to restore
that initial condition where the offset is the offset as though all
requests had returned. it remains unchanged because we've re-queued the
missing data

the original code lacked this offset restoring which meant that if we
had a short request in the middle of a file it'd break the offset,
return, the caller would queue more chunks and those chunsk would all
have wrong offsets now: increasing from (missingoffset + missingsize) up
to file.size **duplicating** whatever requests may still be pending at
that time.
parent ebaa00ec
......@@ -2529,6 +2529,7 @@ int SFTPInternal::GetRequest::readChunks(QByteArray &data)
{
int totalRead = 0;
ssize_t bytesread = 0;
const uint64_t initialOffset = m_file->offset;
while (!m_pendingRequests.isEmpty()) {
SFTPInternal::GetRequest::Request &request = m_pendingRequests.head();
......@@ -2583,6 +2584,17 @@ int SFTPInternal::GetRequest::readChunks(QByteArray &data)
return -1;
}
// Move the offset back to where it was before the read.
// The way this works is that originally the offset is at the maximum of all pending requests,
// read then reduces that by the amount that it came up short, we then seek to where the short request
// left off and make another request for the remaining data. After that we need to move the offset
// back to the original value - without the reduction because we re-requested the missing data!
rc = sftp_seek64(m_file, initialOffset);
if (rc < 0) {
// Failed to continue reading
return -1;
}
return totalRead;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment