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:
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user