MCPcopy Create free account
hub / github.com/cloud-hypervisor/cloud-hypervisor / write

Function write

block/src/vhdx/vhdx_io.rs:141–219  ·  view source on GitHub ↗

VHDx IO write routine: requires relative sector index and count for the requested data.

(
    f: &mut File,
    buf: &[u8],
    disk_spec: &mut DiskSpec,
    bat_offset: u64,
    bat: &mut [BatEntry],
    mut sector_index: u64,
    mut sector_count: u64,
)

Source from the content-addressed store, hash-verified

139/// VHDx IO write routine: requires relative sector index and count for the
140/// requested data.
141pub fn write(
142 f: &mut File,
143 buf: &[u8],
144 disk_spec: &mut DiskSpec,
145 bat_offset: u64,
146 bat: &mut [BatEntry],
147 mut sector_index: u64,
148 mut sector_count: u64,
149) -> Result<usize> {
150 if disk_spec.has_parent {
151 return Err(VhdxIoError::UnsupportedMode);
152 }
153
154 let mut write_count: usize = 0;
155 while sector_count > 0 {
156 let sector = Sector::new(disk_spec, bat, sector_index, sector_count)?;
157
158 let bat_entry = match bat.get(sector.bat_index as usize) {
159 Some(entry) => entry.0,
160 None => {
161 return Err(VhdxIoError::InvalidBatIndex);
162 }
163 };
164
165 match bat_entry & vhdx_bat::BAT_STATE_BIT_MASK {
166 vhdx_bat::PAYLOAD_BLOCK_NOT_PRESENT
167 | vhdx_bat::PAYLOAD_BLOCK_UNDEFINED
168 | vhdx_bat::PAYLOAD_BLOCK_UNMAPPED
169 | vhdx_bat::PAYLOAD_BLOCK_ZERO => {
170 let file_offset =
171 align!(disk_spec.image_size, vhdx_metadata::BLOCK_SIZE_MIN as u64);
172 let new_size = file_offset
173 .checked_add(disk_spec.block_size as u64)
174 .ok_or(VhdxIoError::InvalidDiskSize)?;
175
176 f.set_len(new_size).map_err(VhdxIoError::ResizeFile)?;
177 disk_spec.image_size = new_size;
178
179 let new_bat_entry = file_offset
180 | (vhdx_bat::PAYLOAD_BLOCK_FULLY_PRESENT & vhdx_bat::BAT_STATE_BIT_MASK);
181 bat[sector.bat_index as usize] = BatEntry(new_bat_entry);
182 BatEntry::write_bat_entries(f, bat_offset, bat).map_err(VhdxIoError::WriteBat)?;
183
184 if file_offset < vhdx_metadata::BLOCK_SIZE_MIN as u64 {
185 break;
186 }
187
188 f.seek(SeekFrom::Start(file_offset))
189 .map_err(VhdxIoError::ReadSectorBlock)?;
190 f.write_all(
191 &buf[write_count..(write_count + (sector.free_sectors * SECTOR_SIZE) as usize)],
192 )
193 .map_err(VhdxIoError::ReadSectorBlock)?;
194 }
195 vhdx_bat::PAYLOAD_BLOCK_FULLY_PRESENT => {
196 if sector.file_offset < vhdx_metadata::BLOCK_SIZE_MIN as u64 {
197 break;
198 }

Callers 8

test_fw_cfgFunction · 0.85
_test_api_create_bootFunction · 0.85
_test_api_shutdownFunction · 0.85
_test_api_deleteFunction · 0.85
_test_api_pause_resumeFunction · 0.85
map_writeMethod · 0.85
writeMethod · 0.85

Calls 5

newFunction · 0.85
BatEntryClass · 0.85
getMethod · 0.45
set_lenMethod · 0.45
seekMethod · 0.45

Tested by 6

test_fw_cfgFunction · 0.68
_test_api_create_bootFunction · 0.68
_test_api_shutdownFunction · 0.68
_test_api_deleteFunction · 0.68
_test_api_pause_resumeFunction · 0.68