From 2fa1aac5137b76f2d4623dc3d518e304b0b23ab1 Mon Sep 17 00:00:00 2001 From: vasilito Date: Fri, 31 Jul 2026 00:02:28 +0900 Subject: [PATCH] redox-rt: two-step namespace resolution in sys::open (upstream contract) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sys::open still sent the FULL path in a single SYS_OPENAT_INTO on the namespace fd — the pre-fd-allocation contract that forced the namespace manager to proxy every open with a blocking openat into the provider (the mini boot-freeze head-of-line; see base initnsmgr commit adopting the upstream capability-handoff path). Port the upstream two-step (verbatim from upstream/master, matching the open_into_upper and unlink helpers below that were already synced): 1. openat(ns_fd, full_path, O_DIRECTORY|O_CLOEXEC) — the nsmgr resolves only the scheme part and dups the scheme-root capability. 2. openat(root_fd, reference, flags) — the kernel routes straight to the provider; the nsmgr is out of the data path. With this, a busy/slow provider can no longer stall unrelated opens through the nsmgr's single request loop. --- redox-rt/src/sys.rs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/redox-rt/src/sys.rs b/redox-rt/src/sys.rs index e88a33270a..f2ac30d129 100644 --- a/redox-rt/src/sys.rs +++ b/redox-rt/src/sys.rs @@ -589,10 +589,24 @@ pub fn getns() -> Result { pub fn open>(path: T, flags: usize) -> Result { let _siglock = tmp_disable_signals(); - - let ns_fd = crate::current_namespace_fd()?; let fcntl_flags = flags & syscall::O_FCNTL_MASK; - openat_into_posix(ns_fd, path.as_ref(), flags, fcntl_flags) + // Two-step resolution (upstream contract, same as open_into_upper/unlink + // below): first obtain the scheme-root capability from the namespace + // manager (O_DIRECTORY open of the full path — the nsmgr only resolves the + // scheme part and dups its cap, it never opens into the provider), then + // open the reference AT that root so the kernel routes the request + // directly to the provider. The nsmgr is out of the data path entirely, + // which is what makes its single request loop unable to head-of-line + // block on a busy provider. + let redox_path = RedoxPath::from_absolute(path.as_ref()).ok_or(Error::new(EINVAL))?; + let (_, reference) = redox_path.as_parts().ok_or(Error::new(EINVAL))?; + let root_fd = FdGuard::new(openat_into_upper( + crate::current_namespace_fd()?, + path.as_ref(), + syscall::O_DIRECTORY | O_CLOEXEC, + 0, + )?); + openat_into_posix(root_fd.as_raw_fd(), reference.as_ref(), flags, fcntl_flags) } pub fn openat>( fd: usize,