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

Function next_data_extent

vmm/src/memory_manager.rs:68–95  ·  view source on GitHub ↗

Find the next populated (data) extent in `[cursor, end)` of `fd`, driven by `lseek(SEEK_DATA)` / `lseek(SEEK_HOLE)`. Returns `Ok(Some((offset, len)))` for the next data extent within the window, or `Ok(None)` if there is no more data. Returns `Err` if the fd or filesystem does not support `SEEK_HOLE` (e.g. hugetlbfs) or for any other I/O error. Callers should treat a first-call error as "fall back

(fd: BorrowedFd<'_>, cursor: u64, end: u64)

Source from the content-addressed store, hash-verified

66/// other I/O error. Callers should treat a first-call error as "fall
67/// back to the dense path".
68fn next_data_extent(fd: BorrowedFd<'_>, cursor: u64, end: u64) -> io::Result<Option<(u64, u64)>> {
69 let raw = fd.as_raw_fd();
70 // SAFETY: BorrowedFd guarantees the fd is valid for the lifetime of
71 // the borrow; lseek does not consume or close it.
72 let data_off = unsafe { libc::lseek(raw, cursor as i64, libc::SEEK_DATA) };
73 if data_off < 0 {
74 let e = io::Error::last_os_error();
75 // ENXIO from SEEK_DATA means there is no more data at or after
76 // cursor. Any other error means the filesystem does not support
77 // SEEK_HOLE; the caller falls back to the dense path.
78 return if e.raw_os_error() == Some(libc::ENXIO) {
79 Ok(None)
80 } else {
81 Err(e)
82 };
83 }
84 let data_off = data_off as u64;
85 if data_off >= end {
86 return Ok(None);
87 }
88 // SAFETY: same as above.
89 let hole_off = unsafe { libc::lseek(raw, data_off as i64, libc::SEEK_HOLE) };
90 if hole_off < 0 {
91 return Err(io::Error::last_os_error());
92 }
93 let hole_off = (hole_off as u64).min(end);
94 Ok(Some((data_off, hole_off - data_off)))
95}
96
97struct UffdHandler {
98 stop_event: EventFd,

Callers 4

fill_saved_regionsMethod · 0.85
write_region_sparseFunction · 0.85
collect_extentsFunction · 0.85

Calls 1

as_raw_fdMethod · 0.45

Tested by 1