Skip to content
This repository was archived by the owner on Nov 26, 2025. It is now read-only.

文件页缓存#53

Open
OrangeQi-CQ wants to merge 19 commits into
oscomp:mainfrom
OrangeQi-CQ:pr/page_cache
Open

文件页缓存#53
OrangeQi-CQ wants to merge 19 commits into
oscomp:mainfrom
OrangeQi-CQ:pr/page_cache

Conversation

@OrangeQi-CQ
Copy link
Copy Markdown

  1. 编写文件页缓存,主要在 api/src/file/page_cache.rs
  2. 将各种文件操作与页缓存配合(取决于 open 是否有 DIRECT 标志),包括文件打开关闭、读写、获取状态、fsync 同步等,主要在 api/src/imp/fs 的相关改动
  3. 将 mmap 与页缓存配合,以及 msync 同步
  4. 新增两个 libc 测例:mmap.c 和 page_cache.c

arceos 提交了相应的pr: oscomp/arceos#48

Comment thread api/src/file/fs.rs Outdated
use axerrno::{LinuxError, LinuxResult};
use axfs::fops::DirEntry;
use axio::PollState;
use axio::SeekFrom;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Merge it with axio::PollState

Comment thread api/src/file/fs.rs Outdated
is_direct: bool,
cache: Weak<PageCache>,
) -> Self {
debug!("Starry-api open file {}", path);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

remove this log

Comment thread api/src/file/fs.rs Outdated
debug!("Starry-api open file {}", path);
let size = {
if is_direct {
let inner = inner.clone().unwrap();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

How can you judge this inner is Some(..)?

Comment thread api/src/file/fs.rs Outdated
}
}

pub fn get_cache(&self) -> Arc<PageCache> {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

rename it as cache()

Comment thread api/src/file/fs.rs Outdated
self.cache.upgrade().unwrap()
}

pub fn get_size(&self) -> usize {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

rename it as size()

Comment thread api/src/imp/fs/fd_ops.rs Outdated
) -> LinuxResult<isize> {
let path = path.get_as_str()?;
let opts = flags_to_options(flags, mode);
let opts: OpenOptions = flags_to_options(flags, mode);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

remove this type comment.

Comment thread api/src/imp/fs/stat.rs Outdated
Ok(file) => File::new(
Some(Arc::new(Mutex::new(file))),
path.into(),
false,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why set is_direct as false?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Because stat_at_path(path) use path rather than fd, it may be called without open a file, so I don't use page cache here. Instead, sys_fstat(fd, statbuf) uses fd to query stat of an opened file, so I use page cache.

Comment thread api/src/imp/mm/mmap.rs Outdated

let map_flags = MmapFlags::from_bits_truncate(flags);
if map_flags.contains(MmapFlags::PRIVATE | MmapFlags::SHARED) {
if !(map_flags.contains(MmapFlags::PRIVATE) ^ map_flags.contains(MmapFlags::SHARED)) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

When flags contained none of MAP_PRIVATE, MAP_SHARED, or MAP_SHARED_VALIDATE, it will cause EINVAL.

Comment thread api/src/imp/mm/mmap.rs
}

let offset = offset as usize;
if offset % PAGE_SIZE_4K != 0 {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

When the offset is not align, it will not cause error.

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#define NORMAL_PAGE_SIZE 4096 // 4KB

int main()
{
    // 输出当前 pid
    printf("Current PID: %d\n", getpid());

    // 申请 4KB 的普通页内存
    void *normal_mem = mmap(NULL, NORMAL_PAGE_SIZE - 1024, PROT_READ | PROT_WRITE,
                            MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

    if (normal_mem == MAP_FAILED)
    {
        perror("Normal page mmap failed");
    }
    else
    {
        printf("Normal memory allocated at %p\n", normal_mem);
    }
    return 0;
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Maybe you mean the length may not be align, but according to Linux manual, offset must be a multiple of the page size.

1750321474707

Comment thread api/src/imp/mm/mmap.rs Outdated
false
let anonymous = map_flags.contains(MmapFlags::ANONYMOUS) || fd == -1;
let private = map_flags.contains(MmapFlags::PRIVATE);
let fd = { if anonymous { -1 } else { fd } };
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why set fd repeatedly?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants