Files
k-os/crates/servers/storage-server/src/lib.rs

82 lines
2.4 KiB
Rust

#![no_std]
#![forbid(unsafe_code)]
extern crate alloc;
pub mod adapters;
pub mod encrypted;
pub mod filesystem;
pub mod fs;
pub mod grants;
pub mod protocol;
pub mod scope;
pub mod server;
#[cfg(test)]
#[path = "tests/mod.rs"]
mod tests;
use libkos::syscall;
use types::address::VirtualAddress;
use types::badge::Badge;
use types::bounded::{CapSlot, PageCount};
use types::permission::{Permission, PermissionSet};
/// Client buffers sit high in storage's window, clear of its heap.
const BUFFERS_VA: VirtualAddress = VirtualAddress::from_raw(0x0100_0000);
const EP: CapSlot = CapSlot::const_new(0);
/// 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 = VirtualAddress::from_raw(BUFFERS_VA.raw() + client * protocol::BUFFER_SIZE);
let region = syscall::create_region(PageCount::new(protocol::BUFFER_PAGES as u16)?).ok()?;
// Storage never drops `region`, so the buffer stays mapped.
let buf = libkos::window::map_buffer(region, va).ok()?;
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 = EP;
// Init hands over the disk before asking for anything.
let Some(device) = libkos::device::receive_device(ep)
.mmio
.and_then(driver_block_virtio::VirtioBlockDevice::new)
else {
libkos::println!("storage: no block device, exiting");
syscall::exit();
};
let Some(ext4) = fs::ext4::Ext4::mount(device) else {
libkos::println!("storage: no ext4 filesystem it can read, exiting");
syscall::exit();
};
let mut srv = server::StorageServer::new(ext4, Kernel);
server_framework::serve(&mut srv, ep)
}