redox-rt: two-step namespace resolution in sys::open (upstream contract)
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.
This commit is contained in:
+17
-3
@@ -589,10 +589,24 @@ pub fn getns() -> Result<usize> {
|
||||
|
||||
pub fn open<T: AsRef<str>>(path: T, flags: usize) -> Result<usize> {
|
||||
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<T: AsRef<str>>(
|
||||
fd: usize,
|
||||
|
||||
Reference in New Issue
Block a user