summary refs log tree commit diff
path: root/disk
diff options
context:
space:
mode:
authorChirantan Ekbote <chirantan@chromium.org>2020-05-15 20:06:58 +0900
committerCommit Bot <commit-bot@chromium.org>2020-05-25 19:14:07 +0000
commite7d1221c9d5a4e23b6142ef466892ccf38cfde9c (patch)
tree62345d17a52b48aac24c125fab25ef33cccf2a1e /disk
parentbe5824412cec9e55fdfb523c80e33393e1054140 (diff)
downloadcrosvm-e7d1221c9d5a4e23b6142ef466892ccf38cfde9c.tar
crosvm-e7d1221c9d5a4e23b6142ef466892ccf38cfde9c.tar.gz
crosvm-e7d1221c9d5a4e23b6142ef466892ccf38cfde9c.tar.bz2
crosvm-e7d1221c9d5a4e23b6142ef466892ccf38cfde9c.tar.lz
crosvm-e7d1221c9d5a4e23b6142ef466892ccf38cfde9c.tar.xz
crosvm-e7d1221c9d5a4e23b6142ef466892ccf38cfde9c.tar.zst
crosvm-e7d1221c9d5a4e23b6142ef466892ccf38cfde9c.zip
Make VolatileSlice ABI-compatible with iovec
Change VolatileSlice so that it is ABI-compatible with iovec.  This
allows us to directly pass in a VolatileSlice for a C function that
expects an iovec without having to create temporaries that convert from
one to the other.

Also change all the parameters from u64 to usize.  It's not possible to
address more memory than fits into a usize so having u64 here didn't
really provide much benefit and led to a lot of tedious casting back and
forth all over the place.

BUG=none
TEST=unit tests

Cq-Depend: chromium:2206621
Change-Id: I258f9123c603d9a4c6c5e2d4d10eb4aedf74466d
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2203998
Tested-by: Chirantan Ekbote <chirantan@chromium.org>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Chirantan Ekbote <chirantan@chromium.org>
Diffstat (limited to 'disk')
-rw-r--r--disk/src/android_sparse.rs47
-rw-r--r--disk/src/qcow/mod.rs51
-rw-r--r--disk/src/qcow/qcow_raw_file.rs13
3 files changed, 50 insertions, 61 deletions
diff --git a/disk/src/android_sparse.rs b/disk/src/android_sparse.rs
index 0772bfc..6e1a50c 100644
--- a/disk/src/android_sparse.rs
+++ b/disk/src/android_sparse.rs
@@ -291,9 +291,9 @@ impl FileReadWriteAtVolatile for AndroidSparse {
         ))?;
         let chunk_offset = offset - chunk_start;
         let chunk_size = *expanded_size;
-        let subslice = if chunk_offset + slice.size() > chunk_size {
+        let subslice = if chunk_offset + (slice.size() as u64) > chunk_size {
             slice
-                .sub_slice(0, chunk_size - chunk_offset)
+                .sub_slice(0, (chunk_size - chunk_offset) as usize)
                 .map_err(|e| io::Error::new(ErrorKind::InvalidData, format!("{:?}", e)))?
         } else {
             slice
@@ -331,7 +331,6 @@ impl FileReadWriteAtVolatile for AndroidSparse {
 #[cfg(test)]
 mod tests {
     use super::*;
-    use data_model::VolatileMemory;
     use std::io::{Cursor, Write};
     use sys_util::SharedMemory;
 
@@ -435,12 +434,11 @@ mod tests {
         }];
         let mut image = test_image(chunks);
         let mut input_memory = [55u8; 100];
-        let input_volatile_memory = &mut input_memory[..];
         image
-            .read_exact_at_volatile(input_volatile_memory.get_slice(0, 100).unwrap(), 0)
+            .read_exact_at_volatile(VolatileSlice::new(&mut input_memory[..]), 0)
             .expect("Could not read");
-        let input_vec: Vec<u8> = input_memory.into_iter().cloned().collect();
-        assert_eq!(input_vec, vec![0u8; 100]);
+        let expected = [0u8; 100];
+        assert_eq!(&expected[..], &input_memory[..]);
     }
 
     #[test]
@@ -451,12 +449,11 @@ mod tests {
         }];
         let mut image = test_image(chunks);
         let mut input_memory = [55u8; 8];
-        let input_volatile_memory = &mut input_memory[..];
         image
-            .read_exact_at_volatile(input_volatile_memory.get_slice(0, 8).unwrap(), 0)
+            .read_exact_at_volatile(VolatileSlice::new(&mut input_memory[..]), 0)
             .expect("Could not read");
-        let input_vec: Vec<u8> = input_memory.into_iter().cloned().collect();
-        assert_eq!(input_vec, vec![10, 20, 10, 20, 10, 20, 10, 20]);
+        let expected = [10, 20, 10, 20, 10, 20, 10, 20];
+        assert_eq!(&expected[..], &input_memory[..]);
     }
 
     #[test]
@@ -467,12 +464,11 @@ mod tests {
         }];
         let mut image = test_image(chunks);
         let mut input_memory = [55u8; 6];
-        let input_volatile_memory = &mut input_memory[..];
         image
-            .read_exact_at_volatile(input_volatile_memory.get_slice(0, 6).unwrap(), 1)
+            .read_exact_at_volatile(VolatileSlice::new(&mut input_memory[..]), 1)
             .expect("Could not read");
-        let input_vec: Vec<u8> = input_memory.into_iter().cloned().collect();
-        assert_eq!(input_vec, vec![20, 30, 10, 20, 30, 10]);
+        let expected = [20, 30, 10, 20, 30, 10];
+        assert_eq!(&expected[..], &input_memory[..]);
     }
 
     #[test]
@@ -489,12 +485,11 @@ mod tests {
         ];
         let mut image = test_image(chunks);
         let mut input_memory = [55u8; 7];
-        let input_volatile_memory = &mut input_memory[..];
         image
-            .read_exact_at_volatile(input_volatile_memory.get_slice(0, 7).unwrap(), 39)
+            .read_exact_at_volatile(VolatileSlice::new(&mut input_memory[..]), 39)
             .expect("Could not read");
-        let input_vec: Vec<u8> = input_memory.into_iter().cloned().collect();
-        assert_eq!(input_vec, vec![20, 30, 10, 20, 30, 10, 20]);
+        let expected = [20, 30, 10, 20, 30, 10, 20];
+        assert_eq!(&expected[..], &input_memory[..]);
     }
 
     #[test]
@@ -506,12 +501,11 @@ mod tests {
         let mut image = test_image(chunks);
         write!(image.file, "hello").expect("Failed to write into internal file");
         let mut input_memory = [55u8; 5];
-        let input_volatile_memory = &mut input_memory[..];
         image
-            .read_exact_at_volatile(input_volatile_memory.get_slice(0, 5).unwrap(), 0)
+            .read_exact_at_volatile(VolatileSlice::new(&mut input_memory[..]), 0)
             .expect("Could not read");
-        let input_vec: Vec<u8> = input_memory.into_iter().cloned().collect();
-        assert_eq!(input_vec, vec![104, 101, 108, 108, 111]);
+        let expected = [104, 101, 108, 108, 111];
+        assert_eq!(&expected[..], &input_memory[..]);
     }
 
     #[test]
@@ -528,11 +522,10 @@ mod tests {
         ];
         let mut image = test_image(chunks);
         let mut input_memory = [55u8; 8];
-        let input_volatile_memory = &mut input_memory[..];
         image
-            .read_exact_at_volatile(input_volatile_memory.get_slice(0, 8).unwrap(), 0)
+            .read_exact_at_volatile(VolatileSlice::new(&mut input_memory[..]), 0)
             .expect("Could not read");
-        let input_vec: Vec<u8> = input_memory.into_iter().cloned().collect();
-        assert_eq!(input_vec, vec![10, 20, 10, 20, 30, 40, 30, 40]);
+        let expected = [10, 20, 10, 20, 30, 40, 30, 40];
+        assert_eq!(&expected[..], &input_memory[..]);
     }
 }
diff --git a/disk/src/qcow/mod.rs b/disk/src/qcow/mod.rs
index c5e119d..c699e50 100644
--- a/disk/src/qcow/mod.rs
+++ b/disk/src/qcow/mod.rs
@@ -1090,8 +1090,7 @@ impl QcowFile {
                     let cluster_size = self.raw_file.cluster_size();
                     let cluster_begin = address - (address % cluster_size);
                     let mut cluster_data = vec![0u8; cluster_size as usize];
-                    let raw_slice = cluster_data.as_mut_slice();
-                    let volatile_slice = raw_slice.get_slice(0, cluster_size).unwrap();
+                    let volatile_slice = VolatileSlice::new(&mut cluster_data);
                     backing.read_exact_at_volatile(volatile_slice, cluster_begin)?;
                     Some(cluster_data)
                 } else {
@@ -1537,12 +1536,13 @@ impl AsRawFds for QcowFile {
 
 impl Read for QcowFile {
     fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
-        let slice = buf.get_slice(0, buf.len() as u64).unwrap();
+        let len = buf.len();
+        let slice = VolatileSlice::new(buf);
         let read_count = self.read_cb(
             self.current_offset,
-            buf.len(),
+            len,
             |file, already_read, offset, count| {
-                let sub_slice = slice.get_slice(already_read as u64, count as u64).unwrap();
+                let sub_slice = slice.get_slice(already_read, count).unwrap();
                 match file {
                     Some(f) => f.read_exact_at_volatile(sub_slice, offset),
                     None => {
@@ -1610,9 +1610,9 @@ impl FileReadWriteVolatile for QcowFile {
     fn read_volatile(&mut self, slice: VolatileSlice) -> io::Result<usize> {
         let read_count = self.read_cb(
             self.current_offset,
-            slice.size() as usize,
+            slice.size(),
             |file, read, offset, count| {
-                let sub_slice = slice.get_slice(read as u64, count as u64).unwrap();
+                let sub_slice = slice.get_slice(read, count).unwrap();
                 match file {
                     Some(f) => f.read_exact_at_volatile(sub_slice, offset),
                     None => {
@@ -1627,14 +1627,11 @@ impl FileReadWriteVolatile for QcowFile {
     }
 
     fn write_volatile(&mut self, slice: VolatileSlice) -> io::Result<usize> {
-        let write_count = self.write_cb(
-            self.current_offset,
-            slice.size() as usize,
-            |file, offset, count| {
-                let sub_slice = slice.get_slice(offset as u64, count as u64).unwrap();
+        let write_count =
+            self.write_cb(self.current_offset, slice.size(), |file, offset, count| {
+                let sub_slice = slice.get_slice(offset, count).unwrap();
                 file.write_all_volatile(sub_slice)
-            },
-        )?;
+            })?;
         self.current_offset += write_count as u64;
         Ok(write_count)
     }
@@ -1642,25 +1639,21 @@ impl FileReadWriteVolatile for QcowFile {
 
 impl FileReadWriteAtVolatile for QcowFile {
     fn read_at_volatile(&mut self, slice: VolatileSlice, offset: u64) -> io::Result<usize> {
-        self.read_cb(
-            offset,
-            slice.size() as usize,
-            |file, read, offset, count| {
-                let sub_slice = slice.get_slice(read as u64, count as u64).unwrap();
-                match file {
-                    Some(f) => f.read_exact_at_volatile(sub_slice, offset),
-                    None => {
-                        sub_slice.write_bytes(0);
-                        Ok(())
-                    }
+        self.read_cb(offset, slice.size(), |file, read, offset, count| {
+            let sub_slice = slice.get_slice(read, count).unwrap();
+            match file {
+                Some(f) => f.read_exact_at_volatile(sub_slice, offset),
+                None => {
+                    sub_slice.write_bytes(0);
+                    Ok(())
                 }
-            },
-        )
+            }
+        })
     }
 
     fn write_at_volatile(&mut self, slice: VolatileSlice, offset: u64) -> io::Result<usize> {
-        self.write_cb(offset, slice.size() as usize, |file, offset, count| {
-            let sub_slice = slice.get_slice(offset as u64, count as u64).unwrap();
+        self.write_cb(offset, slice.size(), |file, offset, count| {
+            let sub_slice = slice.get_slice(offset, count).unwrap();
             file.write_all_volatile(sub_slice)
         })
     }
diff --git a/disk/src/qcow/qcow_raw_file.rs b/disk/src/qcow/qcow_raw_file.rs
index 09d2176..5ffdc30 100644
--- a/disk/src/qcow/qcow_raw_file.rs
+++ b/disk/src/qcow/qcow_raw_file.rs
@@ -6,7 +6,7 @@ use std::fs::File;
 use std::io::{self, BufWriter, Read, Seek, SeekFrom, Write};
 use std::mem::size_of;
 
-use data_model::VolatileMemory;
+use data_model::VolatileSlice;
 use sys_util::{FileReadWriteAtVolatile, WriteZeroes};
 
 /// A qcow file. Allows reading/writing clusters and appending clusters.
@@ -149,10 +149,13 @@ impl QcowRawFile {
 
     /// Writes
     pub fn write_cluster(&mut self, address: u64, mut initial_data: Vec<u8>) -> io::Result<()> {
-        let raw_slice = initial_data.as_mut_slice();
-        let volatile_slice = raw_slice
-            .get_slice(0, self.cluster_size)
-            .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("{:?}", e)))?;
+        if (initial_data.len() as u64) < self.cluster_size {
+            return Err(io::Error::new(
+                io::ErrorKind::InvalidInput,
+                "`initial_data` is too small",
+            ));
+        }
+        let volatile_slice = VolatileSlice::new(&mut initial_data[..self.cluster_size as usize]);
         self.file.write_all_at_volatile(volatile_slice, address)
     }
 }