feat(storage): scoped grants (subtree, ro/rw), narrow-only, release revokes all holders; IPC KEEP_DELEGATE opt-in; shell cd/pwd, programs get ro cwd

This commit is contained in:
2026-10-27 20:20:34 +01:00
parent c603a578c0
commit 1fc5a54f06
38 changed files with 1237 additions and 170 deletions

View File

@@ -5,7 +5,9 @@ extern crate alloc;
pub mod adapters;
pub mod filesystem;
pub mod fs;
pub mod grants;
pub mod protocol;
pub mod scope;
pub mod server;
#[cfg(test)]
@@ -14,17 +16,22 @@ mod tests;
use libkos::syscall;
use types::address::VirtualAddress;
use types::badge::Badge;
use types::bounded::{CapSlot, PageCount};
use types::mapping::PagePerms;
use types::permission::{Permission, PermissionSet};
/// Client buffers sit high in storage's window, clear of its heap.
const BUFFERS_VA: usize = 0x0100_0000;
/// Each client's buffer is a fresh region, mapped here and handed to the
/// client, which maps the same pages in its own space.
struct RegionBuffers;
const EP: CapSlot = CapSlot::const_new(0);
impl server::Buffers for RegionBuffers {
/// Each client's buffer is a region, mapped here and handed to the
/// client, which maps the same pages in its own space. Grants are badged
/// copies of storage's endpoint.
struct Kernel;
impl server::Host for Kernel {
fn create(&mut self, client: usize) -> Option<(&'static mut [u8], Option<CapSlot>)> {
let va = BUFFERS_VA + client * protocol::BUFFER_SIZE;
let region = syscall::create_region(PageCount::new(protocol::BUFFER_PAGES as u16)?).ok()?;
@@ -34,12 +41,30 @@ impl server::Buffers for RegionBuffers {
let buf = unsafe { core::slice::from_raw_parts_mut(va as *mut u8, protocol::BUFFER_SIZE) };
Some((buf, Some(region)))
}
fn reclaim(&mut self, buffer: CapSlot) {
syscall::revoke(buffer);
}
/// Call it and pass it on; never Read, which would let the holder
/// take other clients' requests.
fn mint(&mut self, badge: usize) -> Option<CapSlot> {
let perms = PermissionSet::empty()
.with(Permission::Execute)
.with(Permission::Delegate);
syscall::mint(EP, Badge::new(badge), perms).ok()
}
fn revoke(&mut self, grant: CapSlot) {
syscall::revoke(grant);
syscall::drop_cap(grant);
}
}
pub fn run() -> ! {
libkos::println!("storage: started");
let ep = CapSlot::new(0).unwrap();
let ep = EP;
// Init hands over the disk before asking for anything.
let Some(device) = libkos::device::receive_device(ep)
.mmio
@@ -52,6 +77,6 @@ pub fn run() -> ! {
libkos::println!("storage: no ext4 filesystem it can read, exiting");
syscall::exit();
};
let mut srv = server::StorageServer::new(ext4, RegionBuffers);
let mut srv = server::StorageServer::new(ext4, Kernel);
server_framework::serve(&mut srv, ep)
}