Implement fmap for read cache

This commit is contained in:
Wildan M
2026-05-13 06:34:39 +07:00
parent f26c86b176
commit 5b515c0c9b
2 changed files with 63 additions and 20 deletions
+60 -16
View File
@@ -27,7 +27,13 @@ pub trait Resource<D: Disk> {
fn set_path(&mut self, path: &str);
fn read(&mut self, buf: &mut [u8], offset: u64, tx: &mut Transaction<D>) -> Result<usize>;
fn read(
&mut self,
fmaps: &mut Fmaps,
buf: &mut [u8],
offset: u64,
tx: &mut Transaction<D>,
) -> Result<usize>;
fn write(&mut self, buf: &[u8], offset: u64, tx: &mut Transaction<D>) -> Result<usize>;
@@ -193,7 +199,13 @@ impl<D: Disk> Resource<D> for DirResource {
self.path = path.to_string();
}
fn read(&mut self, _buf: &mut [u8], _offset: u64, _tx: &mut Transaction<D>) -> Result<usize> {
fn read(
&mut self,
_fmaps: &mut Fmaps,
_buf: &mut [u8],
_offset: u64,
_tx: &mut Transaction<D>,
) -> Result<usize> {
Err(Error::new(EISDIR))
}
@@ -410,7 +422,7 @@ impl FileMmapInfo {
}
pub fn in_use(&self) -> bool {
self.open_fds > 0 || !self.ranges.is_empty()
self.open_fds > 0 || self.ranges.iter().any(|(_, fmap)| fmap.rc > 0)
}
}
@@ -457,10 +469,44 @@ impl<D: Disk> Resource<D> for FileResource {
self.path = path.to_string();
}
fn read(&mut self, buf: &mut [u8], offset: u64, tx: &mut Transaction<D>) -> Result<usize> {
fn read(
&mut self,
fmaps: &mut Fmaps,
buf: &mut [u8],
offset: u64,
tx: &mut Transaction<D>,
) -> Result<usize> {
if self.flags & O_ACCMODE != O_RDWR && self.flags & O_ACCMODE != O_RDONLY {
return Err(Error::new(EBADF));
}
if let Some(fmap_info) = fmaps.get_mut(&self.node_ptr.id()) {
if !fmap_info.base.is_null() {
let requested_end = offset + buf.len() as u64;
let mut next_offset = offset;
let mut cacheable = true;
for (range, _fmap) in fmap_info.ranges.conflicts(offset..requested_end) {
if range.start > next_offset {
// there's a hole
cacheable = false;
break;
}
next_offset = next_offset.max(range.end);
}
if cacheable && next_offset >= requested_end {
unsafe {
core::ptr::copy_nonoverlapping(
fmap_info.base.add(offset as usize),
buf.as_mut_ptr(),
buf.len(),
);
}
return Ok(buf.len());
}
}
}
let atime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
tx.read_node(
self.node_ptr,
@@ -567,26 +613,26 @@ impl<D: Disk> Resource<D> for FileResource {
for (range, v_opt) in affected_fmaps {
//dbg!(&range);
let range_size = range.end - range.start;
if let Some(mut fmap) = v_opt {
fmap.rc += 1;
fmap.flags |= flags;
//FIXME: Use result?
let _ = fmap_info
.ranges
.insert(range.start, range.end - range.start, fmap);
let _ = fmap_info.ranges.insert(range.start, range_size, fmap);
} else {
let map = unsafe {
Fmap::new(
self.node_ptr,
flags,
unaligned_size,
offset,
range_size as usize,
range.start,
fmap_info.base,
tx,
)?
};
//FIXME: Use result?
let _ = fmap_info.ranges.insert(offset, aligned_size as u64, map);
//TODO: Save aligned size for unmap
let _ = fmap_info.ranges.insert(range.start, range_size, map);
}
}
//dbg!(&self.fmaps);
@@ -624,12 +670,10 @@ impl<D: Disk> Resource<D> for FileResource {
)?;
}
if fmap.rc > 0 {
//FIXME: Use result?
let _ = fmap_info
.ranges
.insert(range.start, range.end - range.start, fmap);
}
//FIXME: Use result?
let _ = fmap_info
.ranges
.insert(range.start, range.end - range.start, fmap);
}
//dbg!(&self.fmaps);
+3 -4
View File
@@ -623,7 +623,7 @@ impl<'sock, D: Disk> SchemeSync for FileScheme<'sock, D> {
let Some(Handle::Resource(file)) = self.handles.get_mut(&id) else {
return Err(Error::new(EBADF));
};
self.fs.tx(|tx| file.read(buf, offset, tx))
self.fs.tx(|tx| file.read(&mut self.fmap, buf, offset, tx))
}
fn write(
@@ -1006,13 +1006,12 @@ impl<'sock, D: Disk> SchemeSync for FileScheme<'sock, D> {
self.fs.tx(|tx| file.fmap(fmaps, flags, size, offset, tx))
}
#[allow(unused_variables)]
fn munmap(
&mut self,
id: usize,
offset: u64,
size: usize,
flags: MunmapFlags,
_flags: MunmapFlags,
_ctx: &CallerCtx,
) -> Result<()> {
let Some(Handle::Resource(file)) = self.handles.get_mut(&id) else {
@@ -1181,7 +1180,7 @@ impl<'sock, D: Disk> SchemeSync for FileScheme<'sock, D> {
&mut self,
id: usize,
kind: StdFsCallKind,
payload: &mut [u8],
_payload: &mut [u8],
metadata: StdFsCallMeta,
ctx: &CallerCtx,
) -> Result<usize> {