read_image_at: iterate until buffer is filled

QEMU will always assume EOF when less bytes than requested are returned
by a block drivers 'read' interface, so we need to fill the buffer up to
'size' if possible.

Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
This commit is contained in:
Stefan Reiter 2020-07-22 15:56:25 +02:00 committed by Thomas Lamprecht
parent 8e63f0386d
commit a9e0937c2d
3 changed files with 20 additions and 8 deletions

View File

@ -364,8 +364,8 @@ int proxmox_restore_read_image_at(ProxmoxRestoreHandle *handle,
* Note: The data pointer needs to be valid until the async
* opteration is finished.
*
* Note: It is not an error for a successful call to transfer fewer
* bytes than requested.
* Note: The call will only ever transfer less than 'size' bytes if
* the end of the file has been reached.
*/
void proxmox_restore_read_image_at_async(ProxmoxRestoreHandle *handle,
uint8_t aid,

View File

@ -934,8 +934,8 @@ pub extern "C" fn proxmox_restore_read_image_at(
/// Note: The data pointer needs to be valid until the async
/// opteration is finished.
///
/// Note: It is not an error for a successful call to transfer fewer
/// bytes than requested.
/// Note: The call will only ever transfer less than 'size' bytes if
/// the end of the file has been reached.
#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn proxmox_restore_read_image_at_async(

View File

@ -262,10 +262,22 @@ impl RestoreTask {
}
let mut reader = reader.lock().await;
reader.seek(SeekFrom::Start(offset)).await?;
let buf: &mut [u8] = unsafe { std::slice::from_raw_parts_mut(data.0 as *mut u8, size as usize)};
let bytes = reader.read(buf).await?;
Ok(bytes.try_into()?)
let buf: &mut [u8] = unsafe { std::slice::from_raw_parts_mut(data.0 as *mut u8, size as usize)};
let mut read = 0;
while read < size {
reader.seek(SeekFrom::Start(offset + read)).await?;
let bytes = reader.read(&mut buf[read as usize..]).await?;
if bytes == 0 {
// EOF
break;
}
read += bytes as u64;
}
Ok(read.try_into()?)
}
}