summary refs log tree commit diff
path: root/disk/src
diff options
context:
space:
mode:
Diffstat (limited to 'disk/src')
-rw-r--r--disk/src/composite.rs25
-rw-r--r--disk/src/disk.rs5
-rw-r--r--disk/src/qcow/mod.rs13
3 files changed, 39 insertions, 4 deletions
diff --git a/disk/src/composite.rs b/disk/src/composite.rs
index c3cca00..cd048c1 100644
--- a/disk/src/composite.rs
+++ b/disk/src/composite.rs
@@ -13,7 +13,9 @@ use crate::{create_disk_file, DiskFile, DiskGetLen, ImageType};
 use data_model::VolatileSlice;
 use protos::cdisk_spec;
 use remain::sorted;
-use sys_util::{AsRawFds, FileReadWriteAtVolatile, FileSetLen, FileSync, PunchHole, WriteZeroesAt};
+use sys_util::{
+    AsRawFds, FileAllocate, FileReadWriteAtVolatile, FileSetLen, FileSync, PunchHole, WriteZeroesAt,
+};
 
 #[sorted]
 #[derive(Debug)]
@@ -292,6 +294,27 @@ impl PunchHole for CompositeDiskFile {
     }
 }
 
+impl FileAllocate for CompositeDiskFile {
+    fn allocate(&mut self, offset: u64, length: u64) -> io::Result<()> {
+        let range = offset..(offset + length);
+        let disks = self.disks_in_range(&range);
+        for disk in disks {
+            let intersection = range_intersection(&range, &disk.range());
+            if intersection.start >= intersection.end {
+                continue;
+            }
+            let result = disk.file.allocate(
+                intersection.start - disk.offset,
+                intersection.end - intersection.start,
+            );
+            if result.is_err() {
+                return result;
+            }
+        }
+        Ok(())
+    }
+}
+
 impl WriteZeroesAt for CompositeDiskFile {
     fn write_zeroes_at(&mut self, offset: u64, length: usize) -> io::Result<usize> {
         let cursor_location = offset;
diff --git a/disk/src/disk.rs b/disk/src/disk.rs
index 49b8127..2f9ad72 100644
--- a/disk/src/disk.rs
+++ b/disk/src/disk.rs
@@ -10,7 +10,8 @@ use std::io::{self, Read, Seek, SeekFrom, Write};
 use libc::EINVAL;
 use remain::sorted;
 use sys_util::{
-    AsRawFds, FileReadWriteAtVolatile, FileSetLen, FileSync, PunchHole, SeekHole, WriteZeroesAt,
+    AsRawFds, FileAllocate, FileReadWriteAtVolatile, FileSetLen, FileSync, PunchHole, SeekHole,
+    WriteZeroesAt,
 };
 
 mod qcow;
@@ -64,6 +65,7 @@ pub trait DiskFile:
     + FileReadWriteAtVolatile
     + PunchHole
     + WriteZeroesAt
+    + FileAllocate
     + Send
     + AsRawFds
     + Debug
@@ -76,6 +78,7 @@ impl<
             + PunchHole
             + FileReadWriteAtVolatile
             + WriteZeroesAt
+            + FileAllocate
             + Send
             + AsRawFds
             + Debug,
diff --git a/disk/src/qcow/mod.rs b/disk/src/qcow/mod.rs
index b1df192..add4f48 100644
--- a/disk/src/qcow/mod.rs
+++ b/disk/src/qcow/mod.rs
@@ -10,8 +10,8 @@ use data_model::{VolatileMemory, VolatileSlice};
 use libc::{EINVAL, ENOSPC, ENOTSUP};
 use remain::sorted;
 use sys_util::{
-    error, FileReadWriteAtVolatile, FileReadWriteVolatile, FileSetLen, FileSync, PunchHole,
-    SeekHole, WriteZeroesAt,
+    error, FileAllocate, FileReadWriteAtVolatile, FileReadWriteVolatile, FileSetLen, FileSync,
+    PunchHole, SeekHole, WriteZeroesAt,
 };
 
 use std::cmp::{max, min};
@@ -1582,6 +1582,15 @@ impl DiskGetLen for QcowFile {
     }
 }
 
+impl FileAllocate for QcowFile {
+    fn allocate(&mut self, offset: u64, len: u64) -> io::Result<()> {
+        // Call write_cb with a do-nothing callback, which will have the effect
+        // of allocating all clusters in the specified range.
+        self.write_cb(offset, len as usize, |_file, _offset, _count| Ok(()))?;
+        Ok(())
+    }
+}
+
 impl PunchHole for QcowFile {
     fn punch_hole(&mut self, offset: u64, length: u64) -> std::io::Result<()> {
         let mut remaining = length;