-
Notifications
You must be signed in to change notification settings - Fork 126
fix: ext4 cache coherence and syscall compatibility for self-compilation #1061
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
Changes from all commits
9fcff51
5721b86
5f47a11
cf54d44
817b2bd
29dee5b
308f3f6
f5e2bcd
912c680
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -364,6 +364,12 @@ pub fn handle_syscall(uctx: &mut UserContext) { | |
| uctx.arg2() as _, | ||
| uctx.arg3().into(), | ||
| ), | ||
| Sysno::epoll_wait => sys_epoll_wait( | ||
| uctx.arg0() as _, | ||
| uctx.arg1().into(), | ||
| uctx.arg2() as _, | ||
| uctx.arg3() as _, | ||
| ), | ||
| Sysno::epoll_pwait => sys_epoll_pwait( | ||
| uctx.arg0() as _, | ||
| uctx.arg1().into(), | ||
|
|
@@ -804,12 +810,31 @@ pub fn handle_syscall(uctx: &mut UserContext) { | |
|
|
||
| // dummy fds | ||
| Sysno::userfaultfd | ||
| | Sysno::io_uring_setup | ||
| | Sysno::fsopen | ||
| | Sysno::fspick | ||
| | Sysno::open_tree | ||
| | Sysno::memfd_secret => sys_dummy_fd(sysno), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| // New mount API — return ENOSYS so mount(8) falls back to | ||
| // the traditional mount(2) syscall (which is implemented). | ||
| Sysno::fsopen | Sysno::fspick | Sysno::open_tree => { | ||
| warn!("new mount API not supported (sysno={sysno}), returning ENOSYS for fallback"); | ||
| Err(AxError::Unsupported) | ||
| } | ||
|
|
||
| // io_uring: fake enough support so tokio 1.x creates its I/O | ||
| // driver without panicking, then falls back to blocking I/O. | ||
| // io_uring_setup returns a dummy fd (tokio thinks io_uring is | ||
| // available), io_uring_enter/register return 0 (no events / | ||
| // success). Without this, tokio calls io_uring_enter on the | ||
| // dummy fd, gets ENOSYS, and panics — corrupting cargo state. | ||
| Sysno::io_uring_setup => { | ||
| warn!("io_uring_setup: returning dummy fd for compatibility"); | ||
| sys_dummy_fd(sysno) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. io_uring 的处理方式存在 ABI 语义问题(同 @yeanwang666 的意见):dummy fd + 恒返回 0 向用户态伪造 io_uring 可用,违反 Linux ABI。建议优先返回 ENOSYS 让运行时走回退路径,或实现带 fd 验证的伪 io_uring 类型。至少需要为 tokio/cargo 场景添加回归测试来证明该方案的稳定性。 |
||
| } | ||
| Sysno::io_uring_enter | Sysno::io_uring_register => { | ||
| // Return 0 = "0 completions" / "successful registration" | ||
| // so tokio's io_uring driver keeps polling without errors. | ||
| Ok(0) | ||
| } | ||
|
Comment on lines
+832
to
+836
|
||
|
|
||
| #[cfg(feature = "ebpf")] | ||
| Sysno::bpf => crate::ebpf::sys_bpf(uctx.arg0() as _, uctx.arg1(), uctx.arg2() as _), | ||
| #[cfg(feature = "ebpf")] | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,8 @@ | ||
| use alloc::{boxed::Box, sync::Arc}; | ||
| use core::cell::OnceCell; | ||
|
|
||
| use ax_kspin::{SpinNoIrq as Mutex, SpinNoIrqGuard as MutexGuard}; | ||
| use ax_hal; | ||
| use ax_sync::{Mutex, MutexGuard}; | ||
| use axfs_ng_vfs::{ | ||
| DirEntry, DirNode, Filesystem, FilesystemOps, Reference, StatFs, VfsResult, path::MAX_NAME_LEN, | ||
| }; | ||
|
|
@@ -63,18 +64,28 @@ impl Ext4Filesystem { | |
|
|
||
| /// Locks the shared rsext4 state. | ||
| /// | ||
| /// rsext4 operations may allocate, flush caches, commit journal state, and | ||
| /// call into the block device while this guard is held. The current rootfs | ||
| /// setup can also run in early atomic contexts where a blocking mutex trips | ||
| /// `might_sleep()`, so use `SpinNoIrq` instead of the older | ||
| /// `SpinNoPreempt` to close same-CPU IRQ reentry without changing the | ||
| /// boot-time calling contract. | ||
| /// In task context (IRQs enabled) this uses the blocking | ||
| /// `ax_sync::Mutex::lock`, sleeping on contention and freeing the | ||
| /// CPU for other tasks. During boot / shutdown IRQs may still be | ||
| /// disabled — fall back to spinning with `try_lock` so that | ||
| /// `might_sleep()` does not panic. | ||
| pub(crate) fn lock(&self) -> MutexGuard<'_, Ext4State> { | ||
| self.inner.lock() | ||
| if ax_hal::asm::irqs_enabled() { | ||
| // Task context — sleep on contention. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 将 |
||
| self.inner.lock() | ||
| } else { | ||
| // Atomic context (boot / shutdown) — spin. | ||
| loop { | ||
| if let Some(guard) = self.inner.try_lock() { | ||
| return guard; | ||
| } | ||
| core::hint::spin_loop(); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| pub(crate) fn sync_to_disk(&self) -> VfsResult<()> { | ||
| let mut state = self.inner.lock(); | ||
| let mut state = self.lock(); | ||
| let (fs, dev) = state.split(); | ||
| fs.datablock_cache.flush_all(dev).map_err(into_vfs_err)?; | ||
| fs.bitmap_cache.flush_all(dev).map_err(into_vfs_err)?; | ||
|
|
||
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.
cargo clippy -D warnings 报错:嵌套
if let Ok(written) = block_id.checked_add(off)+if id == written应合并为if let Ok(written) = block_id.checked_add(off) && id == written(collapsible_if lint)。此外,@yeanwang666 提出的问题也值得注意:如果 overlapping dirty entries 不可能产生,建议添加
debug_assert!说明不变量;如果可能,当前丢弃 dirty entry 但不做数据回写需要明确的理由。