Skip to content
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

Open
wants to merge 26 commits into
base: master
Choose a base branch
from

Conversation

MemoryShore
Copy link
Collaborator

修复fat文件系统中调用read/write对文件进行读写时与缓存中的内容不同步的问题

@dragonosbot
Copy link

@MemoryShore: no appropriate reviewer found, use r? to override

@dragonosbot dragonosbot added A-fs Area: 文件系统 S-等待审查 Status: 等待assignee以及相关方的审查。 labels Oct 21, 2024
@github-actions github-actions bot added the Bug fix A bug is fixed in this pull request label Oct 21, 2024
@fslongjin
Copy link
Member

fslongjin commented Oct 21, 2024

这样的写法我感觉过度的把pagecache的逻辑跟fat本身的逻辑进行了耦合,而且耦合的很紧密啊(都涉及到了FAT写入文件的具体实现的函数那里了)。我认为这样写的不好,得把page cache的逻辑抽取出来。毕竟将来会有不同的文件系统。

@dragonosbot author

@dragonosbot dragonosbot added S-等待作者修改 Status: 这正在等待作者的一些操作(例如代码更改或更多信息)。 and removed S-等待审查 Status: 等待assignee以及相关方的审查。 labels Oct 21, 2024
@MemoryShore
Copy link
Collaborator Author

MemoryShore commented Oct 21, 2024

这样的写法我感觉过度的把pagecache的逻辑跟fat本身的逻辑进行了耦合,而且耦合的很紧密啊(都涉及到了FAT写入文件的具体实现的函数那里了)。我认为这样写的不好,得把page cache的逻辑抽取出来。毕竟将来会有不同的文件系统。

@dragonosbot author

我感觉也没有很耦合吧,pagecache的read和write就只接收一个offset和buf而已,别的文件系统也能用?
@fslongjin

@fslongjin
Copy link
Member

fslongjin commented Oct 22, 2024

这耦合程度很深吧,你想想假如有10种文件系统,pagecache如果改动涉及写入的地方,就要改10个文件系统里面都改。而且,如果有10种不同的文件系统,你这里这段代码得复制10遍。从这个角度来看,这里是缺少抽象的。

@MemoryShore

@fslongjin
Copy link
Member

貌似我好像没找到脏页回写机制?

@MemoryShore
Copy link
Collaborator Author

貌似我好像没找到脏页回写机制?

page_writeback函数

Copy link
Member

@fslongjin fslongjin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shrink_list函数里面应该是产生了use after free了?怎么先释放了内存,才从page_cache删除掉?然后还page write back. 这个应该是有问题的。
image

kernel/src/filesystem/fat/fs.rs Outdated Show resolved Hide resolved
kernel/src/filesystem/vfs/mod.rs Outdated Show resolved Hide resolved
kernel/src/mm/page.rs Outdated Show resolved Hide resolved
@dragonosbot dragonosbot added the A-driver Area: 驱动程序 label Nov 12, 2024
@fslongjin
Copy link
Member

@Jomocool 麻烦看看这里的逻辑 7a3608b

kernel/src/mm/page.rs Outdated Show resolved Hide resolved
if unmap {
// 删除页面
page_cache.remove_page(page_index);
page_manager_lock_irqsave().remove_page(&paddr);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里没有释放页面?是不是page manager需要改改逻辑? @Jomocool

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我的设计是在InnerPage被drop的时候自动释放页面

Copy link
Member

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的内存安全问题了。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

是的,所以我打算增加插入判断逻辑

@fslongjin
Copy link
Member

image
page的new方法改为私有吧,然后有两个地方是手动Page new的,也改改

Comment on lines +445 to +454
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)
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个可以集成到Page的方法里面去。

@@ -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));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copy方法最好也是直接返回Arc,不然page drop的时候也会有问题。

Comment on lines 502 to 505
if self.shared {
shm_manager_lock().free_id(&self.shm_id.unwrap());
}
unsafe {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里我感觉不对:
一个shm有多个page. page释放的时候,不应该去改shm,释放shm的id。

并且shared的页面也不一定是共享内存吧

@Jomocool 麻烦看看?

page_manager_guard.insert(phys, &Arc::new(Page::new(false, phys)))
page_manager_guard
.insert(&Arc::new(Page::new(false, phys, PageType::Uninit)))
.unwrap();
Copy link
Member

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),
Copy link
Member

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)?;
Copy link
Member

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)?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

insert失败时,缺少错误处理。会导致内存泄露。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-driver Area: 驱动程序 A-fs Area: 文件系统 Bug fix A bug is fixed in this pull request S-等待作者修改 Status: 这正在等待作者的一些操作(例如代码更改或更多信息)。
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants