imago/qcow2/
preallocation.rs1use super::*;
6use crate::storage::ext::write_full_zeroes;
7
8#[maybe_async]
9impl<S: Storage + 'static, F: WrappedFormat<S> + 'static> Qcow2<S, F> {
10 pub(super) async fn preallocate_zero(&self, mut offset: u64, length: u64) -> io::Result<()> {
14 let max_offset = offset.checked_add(length).ok_or_else(|| {
15 io::Error::new(io::ErrorKind::InvalidInput, "Preallocate range overflow")
16 })?;
17
18 let max_offset = max_offset.next_multiple_of(self.header.cluster_size() as u64);
21
22 while offset < max_offset {
23 let (zofs, zlen) = self
24 .ensure_fixed_mapping(
25 GuestOffset(offset),
26 max_offset - offset,
27 FixedMapping::ZeroRetainAllocation,
28 )
29 .await?;
30 let zofs = zofs.0;
31 if zofs > offset {
32 self.preallocate(offset, zofs - offset, storage::PreallocateMode::Zero)
33 .await?;
34 }
35 offset = zofs + zlen;
36 if zlen == 0 && offset < max_offset {
37 self.preallocate(offset, max_offset - offset, storage::PreallocateMode::Zero)
38 .await?;
39 break;
40 }
41 }
42
43 Ok(())
44 }
45
46 pub(super) async fn preallocate(
53 &self,
54 mut offset: u64,
55 length: u64,
56 storage_prealloc_mode: storage::PreallocateMode,
57 ) -> io::Result<()> {
58 let max_offset = offset.checked_add(length).ok_or_else(|| {
59 io::Error::new(io::ErrorKind::InvalidInput, "Preallocate range overflow")
60 })?;
61
62 if let Some(data_file) = self.storage.as_ref() {
64 data_file.resize(max_offset, storage_prealloc_mode).await?;
65 }
66
67 while offset < max_offset {
68 let (file, fofs, flen) = self
69 .do_ensure_data_mapping(GuestOffset(offset), max_offset - offset, true, true)
70 .await?;
71
72 if self.storage.is_none() {
74 match storage_prealloc_mode {
75 storage::PreallocateMode::None => (), storage::PreallocateMode::Zero => {
77 file.write_zeroes(fofs, flen).await?;
78 }
79 storage::PreallocateMode::Allocate => {
80 file.write_allocated_zeroes(fofs, flen).await?;
81 }
82 storage::PreallocateMode::WriteData => {
83 write_full_zeroes(file, fofs, flen).await?;
84 }
85 }
86 }
87
88 offset += flen;
89 }
90
91 Ok(())
92 }
93}