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

Method write

block/src/qcow/raw_file.rs:217–308  ·  view source on GitHub ↗
(&mut self, buf: &[u8])

Source from the content-addressed store, hash-verified

215
216impl Write for RawFile {
217 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
218 if self.is_aligned(buf) {
219 match self.file.write(buf) {
220 Ok(r) => {
221 self.position = self.position.checked_add(r.try_into().unwrap()).unwrap();
222 Ok(r)
223 }
224 Err(e) => Err(e),
225 }
226 } else {
227 let rounded_pos: u64 = self.round_down(self.position);
228 let file_offset: usize = self
229 .position
230 .checked_sub(rounded_pos)
231 .unwrap()
232 .try_into()
233 .unwrap();
234 let buf_len: usize = buf.len();
235 let rounded_len: usize = self
236 .round_up(
237 file_offset
238 .checked_add(buf_len)
239 .unwrap()
240 .try_into()
241 .unwrap(),
242 )
243 .try_into()
244 .unwrap();
245
246 let layout = Layout::from_size_align(rounded_len, self.alignment).unwrap();
247 // SAFETY: layout has non-zero size
248 let tmp_ptr = unsafe { alloc_zeroed(layout) };
249 if tmp_ptr.is_null() {
250 return Err(io::Error::last_os_error());
251 }
252
253 // SAFETY: tmp_ptr is at least rounded_len long
254 let tmp_buf = unsafe { slice::from_raw_parts_mut(tmp_ptr, rounded_len) };
255
256 // This can eventually replaced with read_at once its interface
257 // has been stabilized.
258 // SAFETY: FFI call
259 let ret = unsafe {
260 ::libc::pread64(
261 self.file.as_raw_fd(),
262 tmp_buf.as_mut_ptr().cast(),
263 tmp_buf.len(),
264 rounded_pos.try_into().unwrap(),
265 )
266 };
267 if ret < 0 {
268 // SAFETY: tmp_ptr was allocated by alloc_zeroed with layout
269 unsafe { dealloc(tmp_ptr, layout) };
270 return Err(io::Error::last_os_error());
271 }
272
273 tmp_buf[file_offset..(file_offset + buf_len)].copy_from_slice(buf);
274

Callers

nothing calls this directly

Calls 8

is_alignedMethod · 0.80
try_intoMethod · 0.80
round_downMethod · 0.80
round_upMethod · 0.80
as_mut_ptrMethod · 0.80
lenMethod · 0.45
as_raw_fdMethod · 0.45
seekMethod · 0.45

Tested by

no test coverage detected