feat: Implement std_fs_call handling to initfs, ramfs, acpi and xhci

This commit is contained in:
Ibuki Omatsu
2026-02-28 15:15:16 +00:00
committed by Jeremy Soller
parent 9624cd3c2c
commit 2738f69224
27 changed files with 512 additions and 306 deletions
+23 -4
View File
@@ -8,7 +8,7 @@ use crate::scheme::socket::{Handle, SchemeSocket, SocketScheme};
use libredox::flag;
use libredox::Fd;
use redox_scheme::{
scheme::{IntoTag, Op, SchemeResponse, SchemeSync},
scheme::{IntoTag, Op, SchemeResponse, SchemeState, SchemeSync},
CallerCtx, RequestKind, Response, SignalBehavior, Socket,
};
use smoltcp;
@@ -316,6 +316,7 @@ where
SocketT: SchemeSocket + AnySocket<'static>,
{
scheme: socket::SocketScheme<SocketT>,
state: SchemeState,
wait_queue: WaitQueue,
}
impl<SocketT> SchemeWrapper<SocketT>
@@ -334,6 +335,7 @@ where
.map_err(|e| {
Error::from_syscall_error(e, &format!("failed to initialize {} scheme", name))
})?,
state: SchemeState::new(),
wait_queue: Vec::new(),
})
}
@@ -397,7 +399,8 @@ where
continue;
}
};
let resp = match op.handle_sync_dont_consume(&caller, &mut self.scheme) {
let resp = match op.handle_sync_dont_consume(&caller, &mut self.scheme, &mut self.state)
{
SchemeResponse::Opened(Err(SyscallError {
errno: syscall::EWOULDBLOCK,
}))
@@ -433,6 +436,9 @@ where
}
SchemeResponse::Regular(r) => Response::new(r, op),
SchemeResponse::Opened(o) => Response::open_dup_like(o, op),
SchemeResponse::RegularAndNotifyOnDetach(status) => {
Response::new_notify_on_detach(status, op)
}
};
let _ = self
.scheme
@@ -449,6 +455,7 @@ where
// Notify non-blocking sockets
let scheme = &mut self.scheme;
let state = &mut self.state;
for (&fd, handle) in &mut scheme.handles {
let Handle::File(file) = handle else {
@@ -469,7 +476,7 @@ where
while i < queue.len() {
let handle = &mut queue[i];
let (op, caller) = &mut handle.packet;
let res = op.handle_sync_dont_consume(caller, scheme);
let res = op.handle_sync_dont_consume(caller, scheme, state);
match res {
SchemeResponse::Opened(Err(SyscallError {
@@ -531,7 +538,19 @@ where
Error::from_syscall_error(e.into(), "failed to write response")
})?;
}
};
SchemeResponse::RegularAndNotifyOnDetach(status) => {
let (op, _) = queue.swap_remove(i).packet;
let _ = scheme
.scheme_file
.write_response(
Response::new_notify_on_detach(status, op),
SignalBehavior::Restart,
)
.map_err(|e| {
Error::from_syscall_error(e.into(), "failed to write response")
})?;
}
}
}
Ok(())
+33 -22
View File
@@ -3,8 +3,8 @@ mod nodes;
mod notifier;
use redox_scheme::{
scheme::register_scheme_inner, scheme::SchemeSync, CallerCtx, OpenResult, RequestKind,
Response, SignalBehavior, Socket,
scheme::{register_scheme_inner, SchemeState, SchemeSync},
CallerCtx, OpenResult, RequestKind, Response, SignalBehavior, Socket,
};
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address};
use std::cell::RefCell;
@@ -325,17 +325,9 @@ impl NetCfgFile {
}
}
enum Handle {
SchemeRoot,
File(NetCfgFile),
}
pub struct NetCfgScheme {
scheme_file: Socket,
next_fd: usize,
handles: BTreeMap<usize, Handle>,
root_node: CfgNodeRef,
notifier: NotifierRef,
inner: NetCfgSchemeInner,
state: SchemeState,
}
impl NetCfgScheme {
@@ -349,7 +341,7 @@ impl NetCfgScheme {
let dns_config = Rc::new(RefCell::new(DNSConfig {
name_server: Ipv4Address::new(8, 8, 8, 8),
}));
let mut scheme = NetCfgScheme {
let mut inner = NetCfgSchemeInner {
scheme_file,
next_fd: 1,
handles: BTreeMap::new(),
@@ -362,18 +354,21 @@ impl NetCfgScheme {
),
notifier,
};
let cap_id = scheme
let cap_id = inner
.scheme_root()
.map_err(|e| Error::from_syscall_error(e, "failed to get scheme root id"))?;
register_scheme_inner(&scheme.scheme_file, "netcfg", cap_id).map_err(|e| {
register_scheme_inner(&inner.scheme_file, "netcfg", cap_id).map_err(|e| {
Error::from_syscall_error(e, "failed to register netcfg scheme to namespace")
})?;
Ok(scheme)
Ok(Self {
inner,
state: SchemeState::new(),
})
}
pub fn on_scheme_event(&mut self) -> Result<Option<()>> {
let result = loop {
let request = match self.scheme_file.next_request(SignalBehavior::Restart) {
let request = match self.inner.scheme_file.next_request(SignalBehavior::Restart) {
Ok(Some(req)) => req,
Ok(None) => {
break Some(());
@@ -394,7 +389,7 @@ impl NetCfgScheme {
let req = match request.kind() {
RequestKind::Call(c) => c,
RequestKind::OnClose { id } => {
self.on_close(id);
self.inner.on_close(id);
continue;
}
_ => {
@@ -405,23 +400,39 @@ impl NetCfgScheme {
let op = match req.op() {
Ok(op) => op,
Err(req) => {
self.scheme_file.write_response(
self.inner.scheme_file.write_response(
Response::err(syscall::EOPNOTSUPP, req),
SignalBehavior::Restart,
);
continue;
}
};
let resp = op.handle_sync(caller, self);
let resp = op.handle_sync(caller, &mut self.inner, &mut self.state);
let _ = self
.inner
.scheme_file
.write_response(resp, SignalBehavior::Restart)
.map_err(|e| Error::from_syscall_error(e.into(), "failed to write response"))?;
};
self.notify_scheduled_fds();
self.inner.notify_scheduled_fds();
Ok(result)
}
}
enum Handle {
SchemeRoot,
File(NetCfgFile),
}
struct NetCfgSchemeInner {
scheme_file: Socket,
next_fd: usize,
handles: BTreeMap<usize, Handle>,
root_node: CfgNodeRef,
notifier: NotifierRef,
}
impl NetCfgSchemeInner {
fn notify_scheduled_fds(&mut self) {
let fds_to_notify = self.notifier.borrow_mut().get_notified_fds();
for fd in fds_to_notify {
@@ -430,7 +441,7 @@ impl NetCfgScheme {
}
}
impl SchemeSync for NetCfgScheme {
impl SchemeSync for NetCfgSchemeInner {
fn scheme_root(&mut self) -> SyscallResult<usize> {
let id = self.next_fd;
self.next_fd += 1;