From 179705a3fc905301a883af2e84f0a66dd7fc5385 Mon Sep 17 00:00:00 2001 From: Ruihan Li Date: Mon, 16 Sep 2024 23:52:58 +0800 Subject: [PATCH] Fix RamFS readahead --- kernel/src/fs/utils/page_cache.rs | 12 ++++++---- test/apps/mmap/mmap_readahead.c | 39 +++++++++++++++++++++++++++++++ test/apps/scripts/process.sh | 1 + 3 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 test/apps/mmap/mmap_readahead.c diff --git a/kernel/src/fs/utils/page_cache.rs b/kernel/src/fs/utils/page_cache.rs index 21528c982..ebc5d8a7b 100644 --- a/kernel/src/fs/utils/page_cache.rs +++ b/kernel/src/fs/utils/page_cache.rs @@ -306,8 +306,12 @@ impl ReadaheadState { for async_idx in window.readahead_range() { let mut async_page = Page::alloc()?; let pg_waiter = backend.read_page_async(async_idx, async_page.frame())?; - self.waiter.concat(pg_waiter); - async_page.set_state(PageState::Uninit); + if pg_waiter.nreqs() > 0 { + self.waiter.concat(pg_waiter); + } else { + // Some backends (e.g. RamFS) do not issue requests, but fill the page directly. + async_page.set_state(PageState::UpToDate); + } pages.put(async_idx, async_page); } Ok(()) @@ -394,9 +398,7 @@ impl PageCacheManager { if let PageState::Uninit = page.state() { // Cond 2: We should wait for the previous readahead. // If there is no previous readahead, an error must have occurred somewhere. - if ra_state.request_number() == 0 { - return_errno!(Errno::EINVAL) - } + assert!(ra_state.request_number() != 0); ra_state.wait_for_prev_readahead(&mut pages)?; pages.get(&idx).unwrap().frame().clone() } else { diff --git a/test/apps/mmap/mmap_readahead.c b/test/apps/mmap/mmap_readahead.c new file mode 100644 index 000000000..f2d176031 --- /dev/null +++ b/test/apps/mmap/mmap_readahead.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: MPL-2.0 + +#include +#include +#include + +#include "../network/test.h" + +#define FILE_NAME "/tmp/mmap_readahead.txt" + +#define PAGE_SIZE 4096 +#define NR_PAGES 16 + +static char *addr; + +FN_SETUP(mmap_readahead) +{ + int fd; + + fd = CHECK(open(FILE_NAME, O_RDWR | O_CREAT)); + CHECK(unlink(FILE_NAME)); + + CHECK(ftruncate(fd, PAGE_SIZE * NR_PAGES)); + + addr = mmap(NULL, PAGE_SIZE * NR_PAGES, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + CHECK(addr == MAP_FAILED ? -1 : 0); +} +END_SETUP() + +FN_TEST(mmap_readahead) +{ + int i; + + for (i = 0; i < NR_PAGES; ++i) { + TEST_RES(addr[i * PAGE_SIZE], _ret == 0); + } +} +END_TEST() diff --git a/test/apps/scripts/process.sh b/test/apps/scripts/process.sh index bcabbc549..56bc06b57 100755 --- a/test/apps/scripts/process.sh +++ b/test/apps/scripts/process.sh @@ -22,6 +22,7 @@ itimer/setitimer itimer/timer_create mmap/mmap_and_fork mmap/mmap_shared_filebacked +mmap/mmap_readahead pthread/pthread_test pty/open_pty signal_c/parent_death_signal