|
|
@ -8,13 +8,16 @@ pub struct File<F, T> {
|
|
|
|
pub file_start: usize,
|
|
|
|
pub file_start: usize,
|
|
|
|
pub file_end: usize,
|
|
|
|
pub file_end: usize,
|
|
|
|
pub allocator: T,
|
|
|
|
pub allocator: T,
|
|
|
|
|
|
|
|
pub write_back: bool,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub trait Read: Clone + Send + Sync + 'static {
|
|
|
|
pub trait MappedFile: Clone + Send + Sync + 'static {
|
|
|
|
fn read_at(&self, offset: usize, buf: &mut [u8]) -> usize;
|
|
|
|
fn read_at(&self, offset: usize, buf: &mut [u8]) -> usize;
|
|
|
|
|
|
|
|
fn write_at(&self, offset: usize, buf: &[u8]) -> usize;
|
|
|
|
|
|
|
|
fn sync_all(&self);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl<F: Read, T: FrameAllocator> MemoryHandler for File<F, T> {
|
|
|
|
impl<F: MappedFile, T: FrameAllocator> MemoryHandler for File<F, T> {
|
|
|
|
fn box_clone(&self) -> Box<dyn MemoryHandler> {
|
|
|
|
fn box_clone(&self) -> Box<dyn MemoryHandler> {
|
|
|
|
Box::new(self.clone())
|
|
|
|
Box::new(self.clone())
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -33,6 +36,9 @@ impl<F: Read, T: FrameAllocator> MemoryHandler for File<F, T> {
|
|
|
|
|
|
|
|
|
|
|
|
// PageTable::unmap requires page to be present
|
|
|
|
// PageTable::unmap requires page to be present
|
|
|
|
entry.set_present(true);
|
|
|
|
entry.set_present(true);
|
|
|
|
|
|
|
|
if self.write_back && entry.dirty() {
|
|
|
|
|
|
|
|
self.write_data(pt, addr);
|
|
|
|
|
|
|
|
}
|
|
|
|
pt.unmap(addr);
|
|
|
|
pt.unmap(addr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -73,7 +79,7 @@ impl<F: Read, T: FrameAllocator> MemoryHandler for File<F, T> {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl<F: Read, T: FrameAllocator> File<F, T> {
|
|
|
|
impl<F: MappedFile, T: FrameAllocator> File<F, T> {
|
|
|
|
fn fill_data(&self, pt: &mut dyn PageTable, addr: VirtAddr) {
|
|
|
|
fn fill_data(&self, pt: &mut dyn PageTable, addr: VirtAddr) {
|
|
|
|
let data = pt.get_page_slice_mut(addr);
|
|
|
|
let data = pt.get_page_slice_mut(addr);
|
|
|
|
let file_offset = addr + self.file_start - self.mem_start;
|
|
|
|
let file_offset = addr + self.file_start - self.mem_start;
|
|
|
@ -85,6 +91,16 @@ impl<F: Read, T: FrameAllocator> File<F, T> {
|
|
|
|
data[read_size..].iter_mut().for_each(|x| *x = 0);
|
|
|
|
data[read_size..].iter_mut().for_each(|x| *x = 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn write_data(&self, pt: &mut dyn PageTable, addr: VirtAddr) {
|
|
|
|
|
|
|
|
let data = pt.get_page_slice_mut(addr);
|
|
|
|
|
|
|
|
let file_offset = addr + self.file_start - self.mem_start;
|
|
|
|
|
|
|
|
let write_size = (self.file_end as isize - file_offset as isize)
|
|
|
|
|
|
|
|
.min(PAGE_SIZE as isize)
|
|
|
|
|
|
|
|
.max(0) as usize;
|
|
|
|
|
|
|
|
let written_size = self.file.write_at(file_offset, &mut data[..write_size]);
|
|
|
|
|
|
|
|
assert!(write_size == written_size);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl<F, T> Debug for File<F, T> {
|
|
|
|
impl<F, T> Debug for File<F, T> {
|
|
|
|