-
-
Notifications
You must be signed in to change notification settings - Fork 142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(mm): 修复fat文件系统的PageCache同步问题 #1005
base: master
Are you sure you want to change the base?
fix(mm): 修复fat文件系统的PageCache同步问题 #1005
Conversation
@MemoryShore: no appropriate reviewer found, use |
这样的写法我感觉过度的把pagecache的逻辑跟fat本身的逻辑进行了耦合,而且耦合的很紧密啊(都涉及到了FAT写入文件的具体实现的函数那里了)。我认为这样写的不好,得把page cache的逻辑抽取出来。毕竟将来会有不同的文件系统。 @dragonosbot author |
我感觉也没有很耦合吧,pagecache的read和write就只接收一个offset和buf而已,别的文件系统也能用? |
这耦合程度很深吧,你想想假如有10种文件系统,pagecache如果改动涉及写入的地方,就要改10个文件系统里面都改。而且,如果有10种不同的文件系统,你这里这段代码得复制10遍。从这个角度来看,这里是缺少抽象的。 |
貌似我好像没找到脏页回写机制? |
page_writeback函数 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if unmap { | ||
// 删除页面 | ||
page_cache.remove_page(page_index); | ||
page_manager_lock_irqsave().remove_page(&paddr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里没有释放页面?是不是page manager需要改改逻辑? @Jomocool
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
我的设计是在InnerPage
被drop的时候自动释放页面
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
我的设计是在
InnerPage
被drop的时候自动释放页面
哦哦看到了,不过对于Page结构的创建,我觉得可能有点问题。现在这种搞法,容易造成同一个物理地址,存在多个page实例,然后其中一个drop了,就出现use after free的内存安全问题了。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
是的,所以我打算增加插入判断逻辑
let vaddr = | ||
unsafe { MMArch::phys_2_virt(page.read_irqsave().phys_address()).unwrap() }; | ||
|
||
unsafe { | ||
core::slice::from_raw_parts_mut( | ||
(vaddr.data() + last_len) as *mut u8, | ||
MMArch::PAGE_SIZE - last_len, | ||
) | ||
.fill(0) | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个可以集成到Page的方法里面去。
kernel/src/mm/fault.rs
Outdated
@@ -314,7 +314,8 @@ impl PageFaultHandler { | |||
} | |||
let cow_page_phys = cow_page_phys.unwrap(); | |||
|
|||
let cow_page = Arc::new(Page::new(false, cow_page_phys)); | |||
let cow_page = Arc::new(Page::copy(cache_page.read_irqsave(), cow_page_phys)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
copy方法最好也是直接返回Arc,不然page drop的时候也会有问题。
kernel/src/mm/page.rs
Outdated
if self.shared { | ||
shm_manager_lock().free_id(&self.shm_id.unwrap()); | ||
} | ||
unsafe { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kernel/src/mm/page.rs
Outdated
page_manager_guard.insert(phys, &Arc::new(Page::new(false, phys))) | ||
page_manager_guard | ||
.insert(&Arc::new(Page::new(false, phys, PageType::Uninit))) | ||
.unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这段逻辑也要用create_page去创建页面
PageType::Other, | ||
PageFlags::empty(), | ||
&mut LockedFrameAllocator, | ||
PageFrameCount::new(len / PAGE_SIZE), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
) -> Result<Arc<Page>, SystemError> { | ||
let old_page = self.get(old_phys).ok_or(SystemError::EINVAL)?; | ||
let paddr = unsafe { allocator.allocate_one().ok_or(SystemError::ENOMEM)? }; | ||
let page = Page::copy(old_page.read_irqsave(), paddr)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
copy失败的时候要释放页面。
let mut ret = Vec::new(); | ||
for _ in 0..count.data() { | ||
let page = Page::new(shared, cur_phys.phys_address(), page_type.clone(), flags); | ||
self.insert(&page)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
insert失败时,缺少错误处理。会导致内存泄露。
修复fat文件系统中调用read/write对文件进行读写时与缓存中的内容不同步的问题