mmap write back

master
Harry Cheng 5 years ago
parent 384f6dd1c3
commit d2d6afc4de

@ -8,13 +8,16 @@ pub struct File<F, T> {
pub file_start: usize,
pub file_end: usize,
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 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> {
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
entry.set_present(true);
if self.write_back && entry.dirty() {
self.write_data(pt, 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) {
let data = pt.get_page_slice_mut(addr);
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);
}
}
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> {

@ -1,7 +1,8 @@
use super::*;
use core::any::Any;
// here may be a interesting part for lab
pub trait MemoryHandler: Debug + Send + Sync + 'static {
pub trait MemoryHandler: Any + Debug + Send + Sync + 'static {
fn box_clone(&self) -> Box<dyn MemoryHandler>;
/// Map `addr` in the page table
@ -44,5 +45,5 @@ mod linear;
pub use self::byframe::ByFrame;
pub use self::delay::Delay;
pub use self::file::{File, Read};
pub use self::file::{File, MappedFile};
pub use self::linear::Linear;

@ -15,7 +15,7 @@ use xmas_elf::{
use crate::arch::interrupt::{Context, TrapFrame};
use crate::fs::{FileHandle, FileLike, OpenOptions, FOLLOW_MAX_DEPTH};
use crate::memory::{
ByFrame, Delay, File, GlobalFrameAlloc, KernelStack, MemoryAttr, MemorySet, Read,
ByFrame, Delay, File, GlobalFrameAlloc, KernelStack, MemoryAttr, MemorySet, MappedFile,
};
use crate::sync::{Condvar, SpinNoIrqLock as Mutex};
@ -471,6 +471,7 @@ impl ElfExt for ElfFile<'_> {
file_start: ph.offset() as usize,
file_end: ph.offset() as usize + ph.file_size() as usize,
allocator: GlobalFrameAlloc,
write_back: false,
},
"elf",
);
@ -519,8 +520,16 @@ impl ElfExt for ElfFile<'_> {
#[derive(Clone)]
pub struct INodeForMap(pub Arc<dyn INode>);
impl Read for INodeForMap {
impl MappedFile for INodeForMap {
fn read_at(&self, offset: usize, buf: &mut [u8]) -> usize {
self.0.read_at(offset, buf).unwrap()
}
fn write_at(&self, offset: usize, buf: &[u8]) -> usize {
self.0.write_at(offset, buf).unwrap()
}
fn sync_all(&self) {
self.0.sync_all().unwrap();
}
}

@ -82,6 +82,7 @@ impl Syscall<'_> {
file_start: offset,
file_end: offset + len,
allocator: GlobalFrameAlloc,
write_back: flags.contains(MmapFlags::SHARED),
},
"mmap_file",
);
@ -116,7 +117,25 @@ impl Syscall<'_> {
self.vm().pop_with_split(addr, addr + len);
Ok(0)
}
pub fn sys_msync(&mut self, addr: usize, len: usize, flags: usize) -> SysResult {
let flags = MsyncFlags::from_bits_truncate(flags);
if flags.contains(MsyncFlags::SYNC | MsyncFlags::ASYNC) {
return Err(SysError::EINVAL);
}
Ok(0)
}
}
bitflags! {
pub struct MsyncFlags: usize {
const ASYNC = 1;
const INVALIDATE = 2;
const SYNC = 4;
}
}
bitflags! {
pub struct MmapProt: usize {
/// Data cannot be accessed

@ -170,6 +170,7 @@ impl Syscall<'_> {
SYS_MPROTECT => self.sys_mprotect(args[0], args[1], args[2]),
SYS_MUNMAP => self.sys_munmap(args[0], args[1]),
SYS_MADVISE => self.unimplemented("madvise", Ok(0)),
SYS_MSYNC => self.sys_msync(args[0], args[1], args[2]),
// signal
SYS_RT_SIGACTION => self.unimplemented("sigaction", Ok(0)),

Loading…
Cancel
Save