]> git.proxmox.com Git - proxmox-backup-qemu.git/commitdiff
read_image_at: iterate until buffer is filled
authorStefan Reiter <s.reiter@proxmox.com>
Wed, 22 Jul 2020 13:56:25 +0000 (15:56 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Wed, 22 Jul 2020 18:28:19 +0000 (20:28 +0200)
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>
current-api.h
src/lib.rs
src/restore.rs

index 15bb275ea97a949b4fd90769c8f04b5511b03e1f..d77eff6474eac3beea9be3ad98dc42594c408591 100644 (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,
index d4b9370370e2efaf19cbfb994a055fe210086361..3346be8dd2657a9d3808884e2c07b8ee0ccc823d 100644 (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(
index 2be029569af45bc81ea5a515f40c9c31d21ff52c..e43d040861912d533720d9077cbfcfe978df0d35 100644 (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?;
+        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(bytes.try_into()?)
+        Ok(read.try_into()?)
     }
 }