From dc801786b16b3930704df7f6bd2d72ee99238760 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Mon, 5 May 2025 19:37:53 -0700 Subject: [PATCH] [VFS] Move victoria falls to rust. (Breaks voyageurs) Move victoria falls to rust, which allows us to remove both the denali and victoria falls C++ code. This disk driver appears to work properly but has highlighted some instability in the voyageus xhci implementation which now breaks. --- rust/Cargo.lock | 1 + .../client/denali_client/src/disk_reader.rs | 27 +- rust/lib/fs/ext2/Cargo.toml | 1 + rust/lib/fs/ext2/src/ext2_driver.rs | 285 +++++++++++++++++- rust/lib/fs/ext2/src/types.rs | 94 ++++++ rust/lib/mammoth/src/mem.rs | 11 + .../victoriafalls/src/bin/victoriafalls.rs | 27 +- rust/sys/victoriafalls/src/lib.rs | 1 + rust/sys/victoriafalls/src/server.rs | 75 +++++ scripts/build_image.sh | 2 +- sys/denali/CMakeLists.txt | 1 - sys/denali/lib/denali/denali.yunq | 27 -- sys/denali/lib/denali/denali.yunq.client.cpp | 100 ------ sys/denali/lib/denali/denali.yunq.client.h | 37 --- sys/denali/lib/denali/denali.yunq.cpp | 186 ------------ sys/denali/lib/denali/denali.yunq.h | 138 --------- sys/denali/lib/denali/denali.yunq.server.cpp | 152 ---------- sys/denali/lib/denali/denali.yunq.server.h | 50 --- sys/victoriafalls/CMakeLists.txt | 26 -- sys/victoriafalls/fs/ext2/ext2.h | 76 ----- .../fs/ext2/ext2_block_reader.cpp | 117 ------- sys/victoriafalls/fs/ext2/ext2_block_reader.h | 49 --- sys/victoriafalls/fs/ext2/ext2_driver.cpp | 160 ---------- sys/victoriafalls/fs/ext2/ext2_driver.h | 36 --- sys/victoriafalls/fs/ext2/inode_table.cpp | 33 -- sys/victoriafalls/fs/ext2/inode_table.h | 24 -- .../lib/victoriafalls/victoriafalls.yunq | 23 -- .../victoriafalls.yunq.client.cpp | 100 ------ .../victoriafalls/victoriafalls.yunq.client.h | 37 --- .../lib/victoriafalls/victoriafalls.yunq.cpp | 173 ----------- .../lib/victoriafalls/victoriafalls.yunq.h | 124 -------- .../victoriafalls.yunq.server.cpp | 152 ---------- .../victoriafalls/victoriafalls.yunq.server.h | 50 --- sys/victoriafalls/victoriafalls.cpp | 35 --- sys/victoriafalls/victoriafalls_server.cpp | 109 ------- sys/victoriafalls/victoriafalls_server.h | 24 -- yunq/rust/src/codegen.rs | 6 +- 37 files changed, 504 insertions(+), 2065 deletions(-) create mode 100644 rust/sys/victoriafalls/src/server.rs delete mode 100644 sys/denali/CMakeLists.txt delete mode 100644 sys/denali/lib/denali/denali.yunq delete mode 100644 sys/denali/lib/denali/denali.yunq.client.cpp delete mode 100644 sys/denali/lib/denali/denali.yunq.client.h delete mode 100644 sys/denali/lib/denali/denali.yunq.cpp delete mode 100644 sys/denali/lib/denali/denali.yunq.h delete mode 100644 sys/denali/lib/denali/denali.yunq.server.cpp delete mode 100644 sys/denali/lib/denali/denali.yunq.server.h delete mode 100644 sys/victoriafalls/CMakeLists.txt delete mode 100644 sys/victoriafalls/fs/ext2/ext2.h delete mode 100644 sys/victoriafalls/fs/ext2/ext2_block_reader.cpp delete mode 100644 sys/victoriafalls/fs/ext2/ext2_block_reader.h delete mode 100644 sys/victoriafalls/fs/ext2/ext2_driver.cpp delete mode 100644 sys/victoriafalls/fs/ext2/ext2_driver.h delete mode 100644 sys/victoriafalls/fs/ext2/inode_table.cpp delete mode 100644 sys/victoriafalls/fs/ext2/inode_table.h delete mode 100644 sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq delete mode 100644 sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.client.cpp delete mode 100644 sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.client.h delete mode 100644 sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.cpp delete mode 100644 sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.h delete mode 100644 sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.server.cpp delete mode 100644 sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.server.h delete mode 100644 sys/victoriafalls/victoriafalls.cpp delete mode 100644 sys/victoriafalls/victoriafalls_server.cpp delete mode 100644 sys/victoriafalls/victoriafalls_server.h diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 6083562..982c6db 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -54,6 +54,7 @@ version = "0.1.0" dependencies = [ "denali_client", "mammoth", + "yellowstone-yunq", ] [[package]] diff --git a/rust/lib/client/denali_client/src/disk_reader.rs b/rust/lib/client/denali_client/src/disk_reader.rs index 2d9a6a8..0283d29 100644 --- a/rust/lib/client/denali_client/src/disk_reader.rs +++ b/rust/lib/client/denali_client/src/disk_reader.rs @@ -1,31 +1,50 @@ use mammoth::{cap::Capability, zion::ZError}; -use crate::{DenaliClient, DiskBlock, ReadRequest}; +use crate::{DenaliClient, DiskBlock, ReadManyRequest, ReadRequest}; pub struct DiskReader { client: DenaliClient, disk_id: u64, lba_offset: u64, + block_multiplier: u64, } impl DiskReader { - pub fn new(client: DenaliClient, disk_id: u64, lba_offset: u64) -> Self { + pub fn new(client: DenaliClient, disk_id: u64, lba_offset: u64, block_multiplier: u64) -> Self { Self { client, disk_id, lba_offset, + block_multiplier, } } + // TODO: Make yunq clients callable from a non-mutable reference so this can be called from + // shared ownership. pub fn read(&mut self, lba: u64, cnt: u64) -> Result { let read_resp = self.client.read(&ReadRequest { device_id: self.disk_id, block: DiskBlock { - lba: self.lba_offset + lba, - size: cnt, + lba: self.lba_offset + (lba * self.block_multiplier), + size: cnt * self.block_multiplier, }, })?; Ok(Capability::take(read_resp.memory)) } + + pub fn read_many(&mut self, blocks: &[DiskBlock]) -> Result { + let read_resp = self.client.read_many(&ReadManyRequest { + device_id: self.disk_id, + blocks: blocks + .iter() + .map(|b| DiskBlock { + lba: self.lba_offset + (b.lba * self.block_multiplier), + size: b.size * self.block_multiplier, + }) + .collect(), + })?; + + Ok(Capability::take(read_resp.memory)) + } } diff --git a/rust/lib/fs/ext2/Cargo.toml b/rust/lib/fs/ext2/Cargo.toml index 631197a..17c6f3f 100644 --- a/rust/lib/fs/ext2/Cargo.toml +++ b/rust/lib/fs/ext2/Cargo.toml @@ -6,3 +6,4 @@ edition = "2024" [dependencies] denali_client = { path = "../../client/denali_client" } mammoth = { path = "../../mammoth" } +yellowstone-yunq = { path = "../../yellowstone/" } diff --git a/rust/lib/fs/ext2/src/ext2_driver.rs b/rust/lib/fs/ext2/src/ext2_driver.rs index 5354dd3..96bb858 100644 --- a/rust/lib/fs/ext2/src/ext2_driver.rs +++ b/rust/lib/fs/ext2/src/ext2_driver.rs @@ -1,19 +1,284 @@ -use denali_client::DiskReader; -use mammoth::mem::MemoryRegion; +use core::cmp::min; -use crate::types::Superblock; +use alloc::{collections::BTreeMap, string::String, vec::Vec}; +use denali_client::{DenaliClient, DiskBlock, DiskReader, ReadRequest}; +use mammoth::{cap::Capability, debug, mem::MemoryRegion, zion::ZError}; +use yellowstone_yunq::DenaliInfo; +use crate::types::{BlockGroupDescriptor, DirEntry, Inode, Superblock}; + +pub struct FileInfo { + pub inode: u32, + pub name: String, +} + +/// Ext2 Driver with the ability to read files and directories from the given disk. +/// +/// Implementation based on the information available at +/// https://www.nongnu.org/ext2-doc/ext2.html pub struct Ext2Driver { reader: DiskReader, + superblock_region: MemoryRegion, + bgdt_region: MemoryRegion, + + /// Cache of the memory regions for the inode tables available indexed by + /// the block_group number. + inode_table_map: Vec>, + + /// Cache of inode_num to memory capability. + /// This is particularly important for directories so we + /// don't iterate over the disk each time. + inode_cache: BTreeMap, } impl Ext2Driver { - pub fn new(mut reader: DiskReader) -> Self { - let super_block_mem = MemoryRegion::from_cap(reader.read(2, 2).unwrap()).unwrap(); - let super_block: &Superblock = super_block_mem.as_ref(); - let inodes = super_block.inodes_count; - let magic = super_block.magic; - mammoth::debug!("Superblock ({:#x}): inodes: {:#x}", magic, inodes); - Self { reader } + pub fn new(denali_info: DenaliInfo) -> Self { + let mut client = DenaliClient::new(Capability::take(denali_info.denali_endpoint)); + + // Calculate the absolute offset and size of the superblock. It is located at + // offset 1024 of the partition and is 1024 bytes long. (Mostly extra + // reserved space). + // Ref: https://www.nongnu.org/ext2-doc/ext2.html#def-superblock + let abs_superblock_start = denali_info.lba_offset + 2; + let abs_superblock_size = 2; // TODO: This assumes 512 bytes sectors. + let superblock_region = MemoryRegion::from_cap(Capability::take( + client + .read(&ReadRequest { + device_id: denali_info.device_id, + block: DiskBlock { + lba: abs_superblock_start, + size: abs_superblock_size, + }, + }) + .unwrap() + .memory, + )) + .unwrap(); + let superblock: &Superblock = superblock_region.as_ref(); + assert!(superblock.is_valid()); + + let mut reader = DiskReader::new( + client, + denali_info.device_id, + denali_info.lba_offset, + superblock.sectors_per_block(), + ); + + let bgdt_region = MemoryRegion::from_cap( + reader + .read(superblock.bgdt_block_num(), superblock.bgdt_block_size()) + .unwrap(), + ) + .unwrap(); + + let mut inode_table_map = Vec::new(); + inode_table_map.resize_with(superblock.num_block_groups() as usize, || None); + + Self { + reader, + superblock_region, + bgdt_region, + inode_table_map, + inode_cache: BTreeMap::new(), + } + } + + fn superblock(&self) -> &Superblock { + self.superblock_region.as_ref() + } + + fn bgdt(&self) -> &[BlockGroupDescriptor] { + self.bgdt_region.slice() + } + + /// Updates the cached inode tables to contain the inode table for + /// a specific group. + fn populate_inode_table_if_none(&mut self, block_group_num: usize) { + if let None = self.inode_table_map[block_group_num] { + debug!( + "Cache MISS on inode table for block_group {}", + block_group_num + ); + let inode_table = self.bgdt()[block_group_num].inode_table; + self.inode_table_map[block_group_num] = Some( + MemoryRegion::from_cap( + self.reader + .read( + inode_table as u64, + self.superblock().inode_table_block_size(), + ) + .unwrap(), + ) + .unwrap(), + ); + } else { + debug!( + "Cache HIT on inode table for block_group {}", + block_group_num + ); + } + } + + pub fn get_inode(&mut self, inode_num: u32) -> Inode { + // See the following for a description of finding an inode. + // https://www.nongnu.org/ext2-doc/ext2.html#idm140660447281728 + let block_group_num = (inode_num - 1) / self.superblock().inodes_per_group; + self.populate_inode_table_if_none(block_group_num as usize); + let region = self.inode_table_map[block_group_num as usize] + .as_ref() + .unwrap(); + + let local_index = (inode_num - 1) % self.superblock().inodes_per_group; + let offset = self.superblock().inode_size() * local_index as u64; + unsafe { region.raw_ptr_at_offset::(offset).read().clone() } + } + + fn get_blocks_from_single_indirect(&mut self, block_num: u64, num_blocks: usize) -> Vec { + assert!(num_blocks <= 256); + let single_indr_block_mem = + MemoryRegion::from_cap(self.reader.read(block_num, 1).unwrap()).unwrap(); + + single_indr_block_mem.slice()[..num_blocks].to_vec() + } + + fn get_blocks_from_double_indirect(&mut self, block_num: u64, num_blocks: usize) -> Vec { + assert!(num_blocks > 0 && num_blocks <= (256 * 256)); + let num_dbl_indr = ((num_blocks - 1) / 256) + 1; + + let dbl_indr_block_mem = + MemoryRegion::from_cap(self.reader.read(block_num, 1).unwrap()).unwrap(); + + let dbl_indr_blocks: &[u32] = dbl_indr_block_mem.slice(); + + let mut blocks_to_read = Vec::new(); + + for i in 0..num_dbl_indr { + let num_blocks_in_single = min(num_blocks - (256 * i), 256); + blocks_to_read.append( + &mut self.get_blocks_from_single_indirect( + dbl_indr_blocks[i] as u64, + num_blocks_in_single, + ), + ); + } + + blocks_to_read + } + + fn run_len_compress_blocks(&self, blocks: Vec) -> Vec { + let mut curr_block = DiskBlock { + lba: blocks[0] as u64, + size: 1, + }; + + let mut iter = blocks.into_iter(); + iter.next(); + + let mut blocks = Vec::new(); + + while let Some(block) = iter.next() { + if block as u64 == (curr_block.lba + curr_block.size) { + curr_block.size += 1; + } else { + blocks.push(curr_block.clone()); + + curr_block.lba = block as u64; + curr_block.size = 1; + } + } + + blocks.push(curr_block); + + blocks + } + + fn read_inode(&mut self, _inode_num: u32, inode: Inode) -> Result { + // TODO: Cache this method using _inode_num + // TODO: This assumes 512 byte sectors. + let real_block_cnt = (inode.blocks as u64 - 1) / (self.superblock().block_size() / 512) + 1; + if inode.block[14] != 0 { + debug!("Can't handle triply indirect inodes yet."); + return Err(ZError::UNIMPLEMENTED); + } + + let mut blocks_to_read = Vec::new(); + + for i in 0..min(12, real_block_cnt) { + blocks_to_read.push(inode.block[i as usize]) + } + + // Singly indirect block. + if inode.block[12] != 0 { + let num_blocks = min(256, real_block_cnt - 12) as usize; + blocks_to_read.append( + &mut self.get_blocks_from_single_indirect(inode.block[12] as u64, num_blocks), + ); + } + + // Doubly indirect block. + if inode.block[13] != 0 { + let num_blocks = min(256 * 256, real_block_cnt - 268) as usize; + blocks_to_read.append( + &mut self.get_blocks_from_double_indirect(inode.block[13] as u64, num_blocks), + ); + }; + + self.reader + .read_many(&self.run_len_compress_blocks(blocks_to_read)) + } + + fn read_inode_into_mem( + &mut self, + inode_num: u32, + inode: Inode, + ) -> Result { + if !self.inode_cache.contains_key(&inode_num) { + debug!("Cache MISS for inode_num: {}", inode_num); + let inode_cap = self.read_inode(inode_num, inode)?; + self.inode_cache.insert(inode_num, inode_cap); + } else { + debug!("Cache HIT for inode_num: {}", inode_num); + } + + MemoryRegion::from_cap(self.inode_cache[&inode_num].duplicate(Capability::PERMS_ALL)?) + } + + pub fn read_file(&mut self, inode_num: u32) -> Result { + let inode = self.get_inode(inode_num); + if (inode.mode & 0x8000) == 0 { + debug!("Reading non file."); + return Err(ZError::INVALID_ARGUMENT); + } + self.read_inode(inode_num, inode) + } + + pub fn read_directory(&mut self, inode_num: u32) -> Result, ZError> { + let inode = self.get_inode(inode_num); + if (inode.mode & 0x4000) == 0 { + let mode = inode.mode; + debug!("Reading non directory. Inode {:?}, Mode {}", inode, mode); + return Err(ZError::INVALID_ARGUMENT); + } + + let dir = self.read_inode_into_mem(inode_num, inode)?; + + let mut file_names = Vec::new(); + + let mut offset = 0; + while offset < dir.size() { + let dir_ptr: DirEntry = unsafe { dir.raw_ptr_at_offset::(offset).read() }; + + let name = dir_ptr.name; + let file_name: String = + String::from_utf8(name[..dir_ptr.name_len as usize].to_vec()).unwrap(); + file_names.push(FileInfo { + inode: dir_ptr.inode, + name: file_name, + }); + + offset += dir_ptr.record_length as u64; + } + + Ok(file_names) } } diff --git a/rust/lib/fs/ext2/src/types.rs b/rust/lib/fs/ext2/src/types.rs index e01b545..7aa3d2b 100644 --- a/rust/lib/fs/ext2/src/types.rs +++ b/rust/lib/fs/ext2/src/types.rs @@ -1,3 +1,5 @@ +/// Superblock structure. +/// https://www.nongnu.org/ext2-doc/ext2.html#superblock #[repr(C, packed)] pub struct Superblock { pub inodes_count: u32, @@ -28,3 +30,95 @@ pub struct Superblock { pub first_ino: u32, pub inode_size: u16, } + +impl Superblock { + pub fn is_valid(&self) -> bool { + self.magic == 0xEF53 + } + + pub fn sectors_per_block(&self) -> u64 { + 1 << (self.log_block_size + 1) + } + + pub fn block_size(&self) -> u64 { + 1024 << self.log_block_size + } + + pub fn bgdt_block_num(&self) -> u64 { + if self.block_size() == 1024 { 2 } else { 1 } + } + + pub fn bgdt_block_size(&self) -> u64 { + (self.num_block_groups() * (size_of::() as u64) - 1) + / self.block_size() + + 1 + } + + pub fn num_block_groups(&self) -> u64 { + (((self.blocks_count - 1) / self.blocks_per_group) + 1) as u64 + } + + pub fn inode_size(&self) -> u64 { + if self.rev_level >= 1 { + self.inode_size as u64 + } else { + const DEFAULT_INODE_SIZE: u64 = 0x80; + DEFAULT_INODE_SIZE + } + } + + pub fn inode_table_block_size(&self) -> u64 { + (self.inode_size() * self.inodes_per_group as u64) / self.block_size() + } +} + +#[repr(C, packed)] +#[derive(Debug)] +pub struct BlockGroupDescriptor { + pub block_bitmap: u32, + pub inode_bitmap: u32, + pub inode_table: u32, + pub free_blocks_count: u16, + pub free_inodes_count: u16, + pub used_dirs_count: u16, + reserved: [u8; 14], +} + +const _: () = assert!(size_of::() == 32); + +#[repr(C, packed)] +#[derive(Clone, Debug)] +pub struct Inode { + pub mode: u16, + pub uid: u16, + pub size: u32, + pub atime: u32, + pub ctime: u32, + pub mtime: u32, + pub dtime: u32, + pub gid: u16, + pub links_count: u16, + pub blocks: u32, + pub flags: u32, + pub osd1: u32, + pub block: [u32; 15], + pub generation: u32, + pub file_acl: u32, + pub dir_acl: u32, + pub faddr: u32, + pub osd2: [u32; 3], +} + +const _: () = assert!(size_of::() == 128); + +pub const EXT2_FT_FILE: u8 = 0x1; +pub const EXT2_FT_DIR: u8 = 0x2; + +#[repr(C, packed)] +pub struct DirEntry { + pub inode: u32, + pub record_length: u16, + pub name_len: u8, + pub file_type: u8, + pub name: [u8; 256], +} diff --git a/rust/lib/mammoth/src/mem.rs b/rust/lib/mammoth/src/mem.rs index 0beb262..4b6d674 100644 --- a/rust/lib/mammoth/src/mem.rs +++ b/rust/lib/mammoth/src/mem.rs @@ -94,10 +94,21 @@ impl MemoryRegion { } } + pub fn raw_ptr_at_offset(&self, offset: u64) -> *const T { + // TODO: Come up with a better safety check here. + // We can't use the size of T because it might not be sized. + assert!(offset + size_of::() as u64 <= self.size); + (self.virt_addr + offset) as *const T + } + pub fn cap(&self) -> &Capability { &self.mem_cap } + pub fn size(&self) -> u64 { + self.size + } + pub fn duplicate(&self, offset: u64, length: u64) -> Result { syscall::memory_obj_duplicate(&self.mem_cap, offset, length) } diff --git a/rust/sys/victoriafalls/src/bin/victoriafalls.rs b/rust/sys/victoriafalls/src/bin/victoriafalls.rs index f8fef0f..770b238 100644 --- a/rust/sys/victoriafalls/src/bin/victoriafalls.rs +++ b/rust/sys/victoriafalls/src/bin/victoriafalls.rs @@ -1,9 +1,12 @@ #![no_std] #![no_main] -use denali_client::{DenaliClient, DiskReader}; use ext2::Ext2Driver; -use mammoth::{cap::Capability, define_entry, zion::z_err_t}; +use mammoth::{define_entry, zion::z_err_t}; +use victoriafalls::{server::VictoriaFallsServerImpl, VFSServer}; +use yellowstone_yunq::RegisterEndpointRequest; +use yunq::server::spawn_server_thread; +use yunq::server::YunqServer; define_entry!(); @@ -12,13 +15,21 @@ extern "C" fn main() -> z_err_t { let yellowstone = yellowstone_yunq::from_init_endpoint(); let denali_info = yellowstone.get_denali().unwrap(); - let client = DenaliClient::new(Capability::take(denali_info.denali_endpoint)); - let driver = Ext2Driver::new(DiskReader::new( - client, - denali_info.device_id, - denali_info.lba_offset, - )); + let driver = Ext2Driver::new(denali_info); + + let vfs_server = VFSServer::new(VictoriaFallsServerImpl::new(driver)).unwrap(); + + let yellowstone = yellowstone_yunq::from_init_endpoint(); + yellowstone + .register_endpoint(&RegisterEndpointRequest { + endpoint_name: "victoriafalls".into(), + endpoint_capability: vfs_server.create_client_cap().unwrap().release(), + }) + .unwrap(); + + let server_thread = spawn_server_thread(vfs_server); + server_thread.join().unwrap(); 0 } diff --git a/rust/sys/victoriafalls/src/lib.rs b/rust/sys/victoriafalls/src/lib.rs index a397f36..b7b9ca3 100644 --- a/rust/sys/victoriafalls/src/lib.rs +++ b/rust/sys/victoriafalls/src/lib.rs @@ -6,6 +6,7 @@ include!(concat!(env!("OUT_DIR"), "/yunq.rs")); pub mod dir; pub mod file; +pub mod server; static mut VFS_CLIENT: Option = None; diff --git a/rust/sys/victoriafalls/src/server.rs b/rust/sys/victoriafalls/src/server.rs new file mode 100644 index 0000000..0c2edb8 --- /dev/null +++ b/rust/sys/victoriafalls/src/server.rs @@ -0,0 +1,75 @@ +use alloc::{string::String, vec::Vec}; +use ext2::Ext2Driver; +use mammoth::{debug, zion::ZError}; + +use crate::{Directory, GetDirectoryRequest, OpenFileRequest, OpenFileResponse, VFSServerHandler}; + +pub struct VictoriaFallsServerImpl { + ext2_driver: Ext2Driver, +} + +impl VictoriaFallsServerImpl { + pub fn new(ext2_driver: Ext2Driver) -> Self { + VictoriaFallsServerImpl { ext2_driver } + } + + fn find_path_in_dir(&mut self, inode_num: u32, file_name: &str) -> Result { + let files = self.ext2_driver.read_directory(inode_num)?; + + files + .iter() + .find(|fi| fi.name == file_name) + .map(|fi| fi.inode) + .ok_or(ZError::NOT_FOUND) + } +} + +impl VFSServerHandler for VictoriaFallsServerImpl { + fn open_file(&mut self, req: OpenFileRequest) -> Result { + debug!("Reading {}", req.path); + let mut tokens = req.path.split('/'); + if tokens.next() != Some("") { + debug!("Path must be absolute"); + return Err(ZError::INVALID_ARGUMENT); + } + + let mut inode_num = 2; // Start with root. + + while let Some(path_token) = tokens.next() { + inode_num = self.find_path_in_dir(inode_num, path_token)?; + } + + let inode = self.ext2_driver.get_inode(inode_num); + Ok(OpenFileResponse { + path: req.path, + memory: self.ext2_driver.read_file(inode_num)?.release(), + size: inode.size as u64, + }) + } + + fn get_directory(&mut self, req: GetDirectoryRequest) -> Result { + debug!("Reading dir {}", req.path); + let mut tokens = req.path.split('/'); + if tokens.next() != Some("") { + debug!("Path must be absolute"); + return Err(ZError::INVALID_ARGUMENT); + } + + let mut inode_num = 2; // Start with root. + + while let Some(path_token) = tokens.next() { + inode_num = self.find_path_in_dir(inode_num, path_token)?; + } + + let files: Vec = self + .ext2_driver + .read_directory(inode_num)? + .into_iter() + .map(|fi| fi.name) + .collect(); + + Ok(Directory { + filenames: files.join(","), + }) + } +} diff --git a/scripts/build_image.sh b/scripts/build_image.sh index ed8b082..8500427 100644 --- a/scripts/build_image.sh +++ b/scripts/build_image.sh @@ -41,7 +41,7 @@ cp zion/zion efi/ mkdir -p efi/sys cp ../sysroot/bin/yellowstone efi/sys/yellowstone cp ../sysroot/bin/denali efi/sys/denali -cp sys/victoriafalls/victoriafalls efi/sys/victoriafalls +cp ../sysroot/bin/victoriafalls efi/sys/victoriafalls mkdir -p sysroot mount "${dev}p2" sysroot/ diff --git a/sys/denali/CMakeLists.txt b/sys/denali/CMakeLists.txt deleted file mode 100644 index 86fd4de..0000000 --- a/sys/denali/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -yunq_gen(lib/denali lib denali) diff --git a/sys/denali/lib/denali/denali.yunq b/sys/denali/lib/denali/denali.yunq deleted file mode 100644 index 450870c..0000000 --- a/sys/denali/lib/denali/denali.yunq +++ /dev/null @@ -1,27 +0,0 @@ -interface Denali { - method Read(ReadRequest) -> (ReadResponse); - method ReadMany(ReadManyRequest) -> (ReadResponse); -} - -message DiskBlock { - u64 lba; - u64 size; -} - -message ReadRequest { - u64 device_id; - DiskBlock block; -} - - -message ReadManyRequest { - u64 device_id; - repeated DiskBlock blocks; -} - -message ReadResponse { - u64 device_id; - u64 size; - capability memory; -} - diff --git a/sys/denali/lib/denali/denali.yunq.client.cpp b/sys/denali/lib/denali/denali.yunq.client.cpp deleted file mode 100644 index 09e6f6a..0000000 --- a/sys/denali/lib/denali/denali.yunq.client.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// Generated file - DO NOT MODIFY -#include "denali.yunq.client.h" - -#include -#include -#include -#include - - - - -DenaliClient::~DenaliClient() { - if (endpoint_ != 0) { - check(ZCapRelease(endpoint_)); - } -} - - - - -glcr::Status DenaliClient::Read(const ReadRequest& request, ReadResponse& response) { - - uint64_t buffer_size = kBufferSize; - uint64_t cap_size = kCapBufferSize; - - const uint32_t kSentinel = 0xBEEFDEAD; - buffer_.WriteAt(0, kSentinel); - buffer_.WriteAt(8, 0); - - cap_buffer_.Reset(); - - uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); - - - buffer_.WriteAt(4, 16 + length); - - z_cap_t reply_port_cap; - RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer_.RawPtr(), cap_buffer_.UsedSlots(), cap_buffer_.RawPtr(), &reply_port_cap)); - - // FIXME: Add a way to zero out the first buffer. - RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, buffer_.RawPtr(), &cap_size, cap_buffer_.RawPtr())); - - if (buffer_.At(0) != kSentinel) { - return glcr::InvalidResponse("Got an invalid response from server."); - } - - // Check Response Code. - RET_ERR(buffer_.At(8)); - - - yunq::MessageView resp_view(buffer_, 16); - RETURN_ERROR(response.ParseFromBytes(resp_view, cap_buffer_)); - - - return glcr::OK; -} - - - - -glcr::Status DenaliClient::ReadMany(const ReadManyRequest& request, ReadResponse& response) { - - uint64_t buffer_size = kBufferSize; - uint64_t cap_size = kCapBufferSize; - - const uint32_t kSentinel = 0xBEEFDEAD; - buffer_.WriteAt(0, kSentinel); - buffer_.WriteAt(8, 1); - - cap_buffer_.Reset(); - - uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); - - - buffer_.WriteAt(4, 16 + length); - - z_cap_t reply_port_cap; - RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer_.RawPtr(), cap_buffer_.UsedSlots(), cap_buffer_.RawPtr(), &reply_port_cap)); - - // FIXME: Add a way to zero out the first buffer. - RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, buffer_.RawPtr(), &cap_size, cap_buffer_.RawPtr())); - - if (buffer_.At(0) != kSentinel) { - return glcr::InvalidResponse("Got an invalid response from server."); - } - - // Check Response Code. - RET_ERR(buffer_.At(8)); - - - yunq::MessageView resp_view(buffer_, 16); - RETURN_ERROR(response.ParseFromBytes(resp_view, cap_buffer_)); - - - return glcr::OK; -} - - - - diff --git a/sys/denali/lib/denali/denali.yunq.client.h b/sys/denali/lib/denali/denali.yunq.client.h deleted file mode 100644 index 46fd28d..0000000 --- a/sys/denali/lib/denali/denali.yunq.client.h +++ /dev/null @@ -1,37 +0,0 @@ -// Generated file - DO NOT MODIFY -#pragma once - -#include -#include -#include -#include - -#include "denali.yunq.h" - - -class DenaliClient { - public: - DenaliClient(z_cap_t Denali_cap) : endpoint_(Denali_cap) {} - DenaliClient(const DenaliClient&) = delete; - DenaliClient(DenaliClient&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;}; - ~DenaliClient(); - - z_cap_t Capability() { return endpoint_; } - - - - [[nodiscard]] glcr::Status Read(const ReadRequest& request, ReadResponse& response); - - - - [[nodiscard]] glcr::Status ReadMany(const ReadManyRequest& request, ReadResponse& response); - - - private: - z_cap_t endpoint_; - uint64_t kBufferSize = 0x1000; - glcr::ByteBuffer buffer_{kBufferSize}; - uint64_t kCapBufferSize = 0x10; - glcr::CapBuffer cap_buffer_{kCapBufferSize}; -}; - diff --git a/sys/denali/lib/denali/denali.yunq.cpp b/sys/denali/lib/denali/denali.yunq.cpp deleted file mode 100644 index de259cc..0000000 --- a/sys/denali/lib/denali/denali.yunq.cpp +++ /dev/null @@ -1,186 +0,0 @@ -// Generated file -- DO NOT MODIFY. -#include "denali.yunq.h" - -#include -#include - - -namespace { - -const uint64_t header_size = 24; // 4x uint32, 1x uint64 - -struct ExtPointer { - uint32_t offset; - uint32_t length; -}; - -} // namespace -glcr::Status DiskBlock::ParseFromBytes(const yunq::MessageView& message) { - RETURN_ERROR(ParseFromBytesInternal(message)); - return glcr::Status::Ok(); -} - -glcr::Status DiskBlock::ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer& caps) { - RETURN_ERROR(ParseFromBytesInternal(message)); - return glcr::Status::Ok(); -} - -glcr::Status DiskBlock::ParseFromBytesInternal(const yunq::MessageView& message) { - RETURN_ERROR(message.CheckHeader()); - // Parse lba. - ASSIGN_OR_RETURN(lba_, message.ReadField(0)); - // Parse size. - ASSIGN_OR_RETURN(size_, message.ReadField(1)); - - return glcr::Status::Ok(); -} - -uint64_t DiskBlock::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { - yunq::Serializer serializer(bytes, offset, 2); - return SerializeInternal(serializer); -} - -uint64_t DiskBlock::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { - yunq::Serializer serializer(bytes, offset, 2, caps); - return SerializeInternal(serializer); -} - -uint64_t DiskBlock::SerializeInternal(yunq::Serializer& serializer) const { - // Write lba. - serializer.WriteField(0, lba_); - // Write size. - serializer.WriteField(1, size_); - - serializer.WriteHeader(); - - return serializer.size(); -} -glcr::Status ReadRequest::ParseFromBytes(const yunq::MessageView& message) { - RETURN_ERROR(ParseFromBytesInternal(message)); - return glcr::Status::Ok(); -} - -glcr::Status ReadRequest::ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer& caps) { - RETURN_ERROR(ParseFromBytesInternal(message)); - return glcr::Status::Ok(); -} - -glcr::Status ReadRequest::ParseFromBytesInternal(const yunq::MessageView& message) { - RETURN_ERROR(message.CheckHeader()); - // Parse device_id. - ASSIGN_OR_RETURN(device_id_, message.ReadField(0)); - // Parse block. - message.ReadMessage(1, block_); - - return glcr::Status::Ok(); -} - -uint64_t ReadRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { - yunq::Serializer serializer(bytes, offset, 2); - return SerializeInternal(serializer); -} - -uint64_t ReadRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { - yunq::Serializer serializer(bytes, offset, 2, caps); - return SerializeInternal(serializer); -} - -uint64_t ReadRequest::SerializeInternal(yunq::Serializer& serializer) const { - // Write device_id. - serializer.WriteField(0, device_id_); - // Write block. - serializer.WriteMessage(1, block_); - - serializer.WriteHeader(); - - return serializer.size(); -} -glcr::Status ReadManyRequest::ParseFromBytes(const yunq::MessageView& message) { - RETURN_ERROR(ParseFromBytesInternal(message)); - return glcr::Status::Ok(); -} - -glcr::Status ReadManyRequest::ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer& caps) { - RETURN_ERROR(ParseFromBytesInternal(message)); - return glcr::Status::Ok(); -} - -glcr::Status ReadManyRequest::ParseFromBytesInternal(const yunq::MessageView& message) { - RETURN_ERROR(message.CheckHeader()); - // Parse device_id. - ASSIGN_OR_RETURN(device_id_, message.ReadField(0)); - // Parse blocks. - message.ReadRepeatedMessage(1, blocks_); - - - return glcr::Status::Ok(); -} - -uint64_t ReadManyRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { - yunq::Serializer serializer(bytes, offset, 2); - return SerializeInternal(serializer); -} - -uint64_t ReadManyRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { - yunq::Serializer serializer(bytes, offset, 2, caps); - return SerializeInternal(serializer); -} - -uint64_t ReadManyRequest::SerializeInternal(yunq::Serializer& serializer) const { - // Write device_id. - serializer.WriteField(0, device_id_); - // Write blocks. - serializer.WriteRepeatedMessage(1, blocks_); - - serializer.WriteHeader(); - - return serializer.size(); -} -glcr::Status ReadResponse::ParseFromBytes(const yunq::MessageView& message) { - RETURN_ERROR(ParseFromBytesInternal(message)); - // Parse memory. - ASSIGN_OR_RETURN(memory_, message.ReadCapability(2)); - return glcr::Status::Ok(); -} - -glcr::Status ReadResponse::ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer& caps) { - RETURN_ERROR(ParseFromBytesInternal(message)); - // Parse memory. - ASSIGN_OR_RETURN(memory_, message.ReadCapability(2, caps)); - return glcr::Status::Ok(); -} - -glcr::Status ReadResponse::ParseFromBytesInternal(const yunq::MessageView& message) { - RETURN_ERROR(message.CheckHeader()); - // Parse device_id. - ASSIGN_OR_RETURN(device_id_, message.ReadField(0)); - // Parse size. - ASSIGN_OR_RETURN(size_, message.ReadField(1)); - // Parse memory. - - return glcr::Status::Ok(); -} - -uint64_t ReadResponse::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { - yunq::Serializer serializer(bytes, offset, 3); - return SerializeInternal(serializer); -} - -uint64_t ReadResponse::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { - yunq::Serializer serializer(bytes, offset, 3, caps); - return SerializeInternal(serializer); -} - -uint64_t ReadResponse::SerializeInternal(yunq::Serializer& serializer) const { - // Write device_id. - serializer.WriteField(0, device_id_); - // Write size. - serializer.WriteField(1, size_); - // Write memory. - serializer.WriteCapability(2, memory_); - - serializer.WriteHeader(); - - return serializer.size(); -} - diff --git a/sys/denali/lib/denali/denali.yunq.h b/sys/denali/lib/denali/denali.yunq.h deleted file mode 100644 index 7874c91..0000000 --- a/sys/denali/lib/denali/denali.yunq.h +++ /dev/null @@ -1,138 +0,0 @@ -// Generated file - DO NOT MODIFY -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - - -class DiskBlock { - public: - DiskBlock() {} - // Delete copy and move until implemented. - DiskBlock(const DiskBlock&) = delete; - DiskBlock(DiskBlock&&) = default; - DiskBlock& operator=(DiskBlock&&) = default; - - [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message); - [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer&); - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; - - const uint64_t& lba() const { return lba_; } - uint64_t& mutable_lba() { return lba_; } - void set_lba(const uint64_t& value) { lba_ = value; } - - const uint64_t& size() const { return size_; } - uint64_t& mutable_size() { return size_; } - void set_size(const uint64_t& value) { size_ = value; } - - private: - uint64_t lba_; - uint64_t size_; - - // Parses everything except for caps. - glcr::Status ParseFromBytesInternal(const yunq::MessageView& message); - - uint64_t SerializeInternal(yunq::Serializer& serializer) const; -}; -class ReadRequest { - public: - ReadRequest() {} - // Delete copy and move until implemented. - ReadRequest(const ReadRequest&) = delete; - ReadRequest(ReadRequest&&) = default; - ReadRequest& operator=(ReadRequest&&) = default; - - [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message); - [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer&); - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; - - const uint64_t& device_id() const { return device_id_; } - uint64_t& mutable_device_id() { return device_id_; } - void set_device_id(const uint64_t& value) { device_id_ = value; } - - const DiskBlock& block() const { return block_; } - DiskBlock& mutable_block() { return block_; } - - private: - uint64_t device_id_; - DiskBlock block_; - - // Parses everything except for caps. - glcr::Status ParseFromBytesInternal(const yunq::MessageView& message); - - uint64_t SerializeInternal(yunq::Serializer& serializer) const; -}; -class ReadManyRequest { - public: - ReadManyRequest() {} - // Delete copy and move until implemented. - ReadManyRequest(const ReadManyRequest&) = delete; - ReadManyRequest(ReadManyRequest&&) = default; - ReadManyRequest& operator=(ReadManyRequest&&) = default; - - [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message); - [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer&); - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; - - const uint64_t& device_id() const { return device_id_; } - uint64_t& mutable_device_id() { return device_id_; } - void set_device_id(const uint64_t& value) { device_id_ = value; } - - const glcr::Vector& blocks() const { return blocks_; } - glcr::Vector& mutable_blocks() { return blocks_; } - void add_blocks(DiskBlock&& value) { blocks_.PushBack(glcr::Move(value)); } - - private: - uint64_t device_id_; - glcr::Vector blocks_; - - // Parses everything except for caps. - glcr::Status ParseFromBytesInternal(const yunq::MessageView& message); - - uint64_t SerializeInternal(yunq::Serializer& serializer) const; -}; -class ReadResponse { - public: - ReadResponse() {} - // Delete copy and move until implemented. - ReadResponse(const ReadResponse&) = delete; - ReadResponse(ReadResponse&&) = default; - ReadResponse& operator=(ReadResponse&&) = default; - - [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message); - [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer&); - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; - - const uint64_t& device_id() const { return device_id_; } - uint64_t& mutable_device_id() { return device_id_; } - void set_device_id(const uint64_t& value) { device_id_ = value; } - - const uint64_t& size() const { return size_; } - uint64_t& mutable_size() { return size_; } - void set_size(const uint64_t& value) { size_ = value; } - - const z_cap_t& memory() const { return memory_; } - z_cap_t& mutable_memory() { return memory_; } - void set_memory(const z_cap_t& value) { memory_ = value; } - - private: - uint64_t device_id_; - uint64_t size_; - z_cap_t memory_; - - // Parses everything except for caps. - glcr::Status ParseFromBytesInternal(const yunq::MessageView& message); - - uint64_t SerializeInternal(yunq::Serializer& serializer) const; -}; - diff --git a/sys/denali/lib/denali/denali.yunq.server.cpp b/sys/denali/lib/denali/denali.yunq.server.cpp deleted file mode 100644 index 4fe21f5..0000000 --- a/sys/denali/lib/denali/denali.yunq.server.cpp +++ /dev/null @@ -1,152 +0,0 @@ -// Generated file -- DO NOT MODIFY. -#include "denali.yunq.server.h" - -#include -#include - - -namespace { - -const uint32_t kSentinel = 0xBEEFDEAD; -const uint32_t kHeaderSize = 0x10; - -void WriteError(glcr::ByteBuffer& buffer, glcr::ErrorCode err) { - buffer.WriteAt(0, kSentinel); - buffer.WriteAt(4, kHeaderSize); - buffer.WriteAt(8, err); -} - -void WriteHeader(glcr::ByteBuffer& buffer, uint64_t message_length) { - buffer.WriteAt(0, kSentinel); - buffer.WriteAt(4, kHeaderSize + message_length); - buffer.WriteAt(8, glcr::OK); -} - -} // namespace - - - -void DenaliServerBaseThreadBootstrap(void* server_base) { - ((DenaliServerBase*)server_base)->ServerThread(); -} - -DenaliServerBase::~DenaliServerBase() { - if (endpoint_ != 0) { - check(ZCapRelease(endpoint_)); - } -} - -glcr::ErrorOr DenaliServerBase::CreateClientCap() { - uint64_t client_cap; - RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap)); - return client_cap; -} - -glcr::ErrorOr DenaliServerBase::CreateClient() { - uint64_t client_cap; - RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap)); - return DenaliClient(client_cap); -} - -Thread DenaliServerBase::RunServer() { - return Thread(DenaliServerBaseThreadBootstrap, this); -} - -void DenaliServerBase::ServerThread() { - glcr::ByteBuffer recv_buffer(0x1000); - glcr::CapBuffer recv_cap(0x10); - glcr::ByteBuffer resp_buffer(0x1000); - glcr::CapBuffer resp_cap(0x10); - z_cap_t reply_port_cap; - - while (true) { - uint64_t recv_cap_size = 0x10; - uint64_t recv_buf_size = 0x1000; - recv_cap.Reset(); - glcr::ErrorCode recv_err = static_cast(ZEndpointRecv(endpoint_, &recv_buf_size, recv_buffer.RawPtr(), &recv_cap_size, recv_cap.RawPtr(), &reply_port_cap)); - if (recv_err != glcr::OK) { - dbgln("Error in receive: {x}", recv_err); - continue; - } - - uint64_t resp_length = 0; - - glcr::ErrorCode reply_err = glcr::OK; - resp_cap.Reset(); - glcr::Status err = HandleRequest(recv_buffer, recv_cap, resp_buffer, resp_length, resp_cap); - if (!err) { - WriteError(resp_buffer, err.code()); - dbgln("Responding Error {}", err.message()); - reply_err = static_cast(ZReplyPortSend(reply_port_cap, kHeaderSize, resp_buffer.RawPtr(), 0, nullptr)); - } else { - WriteHeader(resp_buffer, resp_length); - reply_err = static_cast(ZReplyPortSend(reply_port_cap, kHeaderSize + resp_length, resp_buffer.RawPtr(), resp_cap.UsedSlots(), resp_cap.RawPtr())); - } - if (reply_err != glcr::OK) { - dbgln("Error in reply: {x}", reply_err); - } - } - -} - -glcr::Status DenaliServerBase::HandleRequest(const glcr::ByteBuffer& request, - const glcr::CapBuffer& req_caps, - glcr::ByteBuffer& response, uint64_t& resp_length, - glcr::CapBuffer& resp_caps) { - if (request.At(0) != kSentinel) { - return glcr::InvalidArgument("Request Not Valid"); - } - - uint64_t method_select = request.At(8); - - switch(method_select) { - case 0: { - - - ReadRequest yunq_request; - yunq::MessageView request_view(request, kHeaderSize); - RETURN_ERROR(yunq_request.ParseFromBytes(request_view, req_caps)); - - - - ReadResponse yunq_response; - - - - RETURN_ERROR(HandleRead(yunq_request, yunq_response)); - - - - resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); - - break; - } - case 1: { - - - ReadManyRequest yunq_request; - yunq::MessageView request_view(request, kHeaderSize); - RETURN_ERROR(yunq_request.ParseFromBytes(request_view, req_caps)); - - - - ReadResponse yunq_response; - - - - RETURN_ERROR(HandleReadMany(yunq_request, yunq_response)); - - - - resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); - - break; - } - default: { - return glcr::Unimplemented("Method unimplemented by server."); - } - } - return glcr::Status::Ok(); -} - - diff --git a/sys/denali/lib/denali/denali.yunq.server.h b/sys/denali/lib/denali/denali.yunq.server.h deleted file mode 100644 index 5dc12e3..0000000 --- a/sys/denali/lib/denali/denali.yunq.server.h +++ /dev/null @@ -1,50 +0,0 @@ -// Generated File -- DO NOT MODIFY. -#pragma once - -#include -#include -#include -#include - -#include "denali.yunq.h" -#include "denali.yunq.client.h" - - - - - -class DenaliServerBase { - public: - DenaliServerBase(z_cap_t Denali_cap) : endpoint_(Denali_cap) {} - DenaliServerBase(const DenaliServerBase&) = delete; - DenaliServerBase(DenaliServerBase&&) = delete; - virtual ~DenaliServerBase(); - - glcr::ErrorOr CreateClientCap(); - glcr::ErrorOr CreateClient(); - - [[nodiscard]] Thread RunServer(); - - - - [[nodiscard]] virtual glcr::Status HandleRead(const ReadRequest&, ReadResponse&) = 0; - - - - [[nodiscard]] virtual glcr::Status HandleReadMany(const ReadManyRequest&, ReadResponse&) = 0; - - - - private: - z_cap_t endpoint_; - - friend void DenaliServerBaseThreadBootstrap(void*); - void ServerThread(); - - [[nodiscard]] glcr::Status HandleRequest(const glcr::ByteBuffer& request, const glcr::CapBuffer& req_caps, - glcr::ByteBuffer& response, uint64_t& resp_length, - glcr::CapBuffer& resp_caps); -}; - - - diff --git a/sys/victoriafalls/CMakeLists.txt b/sys/victoriafalls/CMakeLists.txt deleted file mode 100644 index 964bbab..0000000 --- a/sys/victoriafalls/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -add_executable(victoriafalls - fs/ext2/ext2_block_reader.cpp - fs/ext2/ext2_driver.cpp - fs/ext2/inode_table.cpp - victoriafalls.cpp - victoriafalls_server.cpp - ) - -target_include_directories(victoriafalls - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - "${CMAKE_CURRENT_SOURCE_DIR}/include") - -target_link_libraries(victoriafalls - denali_yunq - glacier - mammoth - victoriafalls_yunq - yellowstone_yunq - ) - -set_target_properties(victoriafalls PROPERTIES - COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${BASE_COMPILE_FLAGS}" - LINK_FLAGS "${CMAKE_EXE_LINK_FLAGS} ${BASE_LINK_FLAGS}" - ) - -yunq_gen(lib/victoriafalls lib victoriafalls) diff --git a/sys/victoriafalls/fs/ext2/ext2.h b/sys/victoriafalls/fs/ext2/ext2.h deleted file mode 100644 index 8a3ab2a..0000000 --- a/sys/victoriafalls/fs/ext2/ext2.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#include - -struct Superblock { - uint32_t inodes_count; - uint32_t blocks_count; - uint32_t reserved_blocks_count; - uint32_t free_blocks_count; - uint32_t free_inodes_count; - uint32_t first_data_blok; - uint32_t log_block_size; - uint32_t log_frag_size; - uint32_t blocks_per_group; - uint32_t frags_per_group; - uint32_t inodes_per_group; - uint32_t mtime; - uint32_t wtime; - uint16_t mnt_count; - uint16_t max_mnt_count; - uint16_t magic; - uint16_t state; - uint16_t errors; - uint16_t minor_rev_level; - uint32_t lastcheck; - uint32_t checkinterval; - uint32_t creator_os; - uint32_t rev_level; - uint16_t def_resuid; - uint16_t def_resgid; - uint32_t first_ino; - uint16_t inode_size; -} __attribute__((__packed__)); - -struct BlockGroupDescriptor { - uint32_t block_bitmap; - uint32_t inode_bitmap; - uint32_t inode_table; - uint16_t free_blocks_count; - uint16_t free_inodes_count; - uint16_t used_dirs_count; - uint8_t reserved[14]; -} __attribute__((__packed__)); - -struct Inode { - uint16_t mode; - uint16_t uid; - uint32_t size; - uint32_t atime; - uint32_t ctime; - uint32_t mtime; - uint32_t dtime; - uint16_t gid; - uint16_t links_count; - uint32_t blocks; - uint32_t flags; - uint32_t osd1; - uint32_t block[15]; - uint32_t generation; - uint32_t file_acl; - uint32_t dir_acl; - uint32_t faddr; - uint32_t osd2[3]; -} __attribute__((__packed__)); - -constexpr uint8_t kExt2FtUnknown = 0; -constexpr uint8_t kExt2FtFile = 1; -constexpr uint8_t kExt2FtDirectory = 2; - -struct DirEntry { - uint32_t inode; - uint16_t record_length; - uint8_t name_len; - uint8_t file_type; - char name[256]; -} __attribute__((__packed__)); diff --git a/sys/victoriafalls/fs/ext2/ext2_block_reader.cpp b/sys/victoriafalls/fs/ext2/ext2_block_reader.cpp deleted file mode 100644 index 4e8a08e..0000000 --- a/sys/victoriafalls/fs/ext2/ext2_block_reader.cpp +++ /dev/null @@ -1,117 +0,0 @@ -#include "fs/ext2/ext2_block_reader.h" - -#include - -glcr::ErrorOr> Ext2BlockReader::Init( - const yellowstone::DenaliInfo& denali_info) { - // Read 1024 bytes from 1024 offset. - // FIXME: Don't assume 512 byte sectors somehow. - DenaliClient client(denali_info.denali_endpoint()); - ReadRequest req; - req.set_device_id(denali_info.device_id()); - req.mutable_block().set_lba(denali_info.lba_offset() + 2); - req.mutable_block().set_size(2); - ReadResponse resp; - auto status = client.Read(req, resp); - if (!status.ok()) { - dbgln("Failed to read superblock: {}", status.message()); - return status.code(); - } - mmth::OwnedMemoryRegion superblock = - mmth::OwnedMemoryRegion::FromCapability(resp.memory()); - - return glcr::SharedPtr( - new Ext2BlockReader(glcr::Move(client), denali_info.device_id(), - denali_info.lba_offset(), glcr::Move(superblock))); -} - -Superblock* Ext2BlockReader::GetSuperblock() { - return reinterpret_cast(super_block_region_.vaddr()); -} - -uint64_t Ext2BlockReader::SectorsPerBlock() { - return 1 << (GetSuperblock()->log_block_size + 1); -} - -uint64_t Ext2BlockReader::BlockSize() { - return 1024 << (GetSuperblock()->log_block_size); -} - -uint64_t Ext2BlockReader::NumberOfBlockGroups() { - return ((GetSuperblock()->blocks_count - 1) / - GetSuperblock()->blocks_per_group) + - 1; -} - -uint64_t Ext2BlockReader::BgdtBlockNum() { - return (BlockSize() == 1024) ? 2 : 1; -} - -uint64_t Ext2BlockReader::BgdtBlockSize() { - return ((NumberOfBlockGroups() * sizeof(BlockGroupDescriptor) - 1) / - BlockSize()) + - 1; -} - -uint64_t Ext2BlockReader::InodeSize() { - constexpr uint64_t kDefaultInodeSize = 0x80; - return GetSuperblock()->rev_level >= 1 ? GetSuperblock()->inode_size - : kDefaultInodeSize; -} - -uint64_t Ext2BlockReader::InodeTableBlockSize() { - return (InodeSize() * GetSuperblock()->inodes_per_group) / BlockSize(); -} - -glcr::ErrorOr Ext2BlockReader::ReadBlock( - uint64_t block_number) { - return ReadBlocks(block_number, 1); -} -glcr::ErrorOr Ext2BlockReader::ReadBlocks( - uint64_t block_number, uint64_t num_blocks) { - ReadRequest req; - req.set_device_id(device_id_); - req.mutable_block().set_lba(lba_offset_ + block_number * SectorsPerBlock()); - req.mutable_block().set_size(num_blocks * SectorsPerBlock()); - ReadResponse resp; - auto status = denali_.Read(req, resp); - if (!status.ok()) { - dbgln("Failed to read block: {}", status.code()); - return status.code(); - } - return mmth::OwnedMemoryRegion::FromCapability(resp.memory()); -} - -glcr::ErrorOr Ext2BlockReader::ReadBlocks( - const glcr::Vector& block_list) { - ReadManyRequest req; - req.set_device_id(device_id_); - for (uint64_t i = 0; i < block_list.size(); i++) { - uint64_t curr_start = lba_offset_ + block_list.at(i) * SectorsPerBlock(); - uint64_t curr_run_len = 1; - while ((i + 1) < block_list.size() && - block_list.at(i + 1) == block_list.at(i) + 1) { - i++; - curr_run_len++; - } - DiskBlock block; - block.set_lba(curr_start); - block.set_size(curr_run_len * SectorsPerBlock()); - req.add_blocks(glcr::Move(block)); - } - ReadResponse resp; - auto status = denali_.ReadMany(req, resp); - if (!status.ok()) { - dbgln("Failed to read blocks: {}", status.code()); - return status.code(); - } - return mmth::OwnedMemoryRegion::FromCapability(resp.memory()); -} - -Ext2BlockReader::Ext2BlockReader(DenaliClient&& denali, uint64_t device_id, - uint64_t lba_offset, - mmth::OwnedMemoryRegion&& super_block) - : denali_(glcr::Move(denali)), - device_id_(device_id), - lba_offset_(lba_offset), - super_block_region_(glcr::Move(super_block)) {} diff --git a/sys/victoriafalls/fs/ext2/ext2_block_reader.h b/sys/victoriafalls/fs/ext2/ext2_block_reader.h deleted file mode 100644 index aa49fba..0000000 --- a/sys/victoriafalls/fs/ext2/ext2_block_reader.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include "fs/ext2/ext2.h" - -/* Simple Wrapper class around the denali client to translate blocks to sectors. - * - * By necessity contains the Ext Superblock (to make the translation - * calculation). - * */ -class Ext2BlockReader { - public: - static glcr::ErrorOr> Init( - const yellowstone::DenaliInfo& denali_info); - - // TODO: Consider creating a new class wrapper with these computations. - Superblock* GetSuperblock(); - uint64_t BlockSize(); - uint64_t NumberOfBlockGroups(); - uint64_t BgdtBlockNum(); - uint64_t BgdtBlockSize(); - uint64_t InodeSize(); - // FIXME: This probably needs to take into account the block group number - // because the last table will likely be smaller. - uint64_t InodeTableBlockSize(); - - glcr::ErrorOr ReadBlock(uint64_t block_number); - glcr::ErrorOr ReadBlocks(uint64_t block_number, - uint64_t num_blocks); - - glcr::ErrorOr ReadBlocks( - const glcr::Vector& block_list); - - private: - DenaliClient denali_; - uint64_t device_id_; - uint64_t lba_offset_; - mmth::OwnedMemoryRegion super_block_region_; - - Ext2BlockReader(DenaliClient&& denali, uint64_t device_id, - uint64_t lba_offset, mmth::OwnedMemoryRegion&& super_block); - - uint64_t SectorsPerBlock(); -}; diff --git a/sys/victoriafalls/fs/ext2/ext2_driver.cpp b/sys/victoriafalls/fs/ext2/ext2_driver.cpp deleted file mode 100644 index 9483838..0000000 --- a/sys/victoriafalls/fs/ext2/ext2_driver.cpp +++ /dev/null @@ -1,160 +0,0 @@ -#include "fs/ext2/ext2_driver.h" - -#include -#include - -#define EXT2_DEBUG 0 - -glcr::ErrorOr Ext2Driver::Init( - const yellowstone::DenaliInfo& denali_info) { - ASSIGN_OR_RETURN(glcr::SharedPtr reader, - Ext2BlockReader::Init(glcr::Move(denali_info))); - - ASSIGN_OR_RETURN( - mmth::OwnedMemoryRegion bgdt, - reader->ReadBlocks(reader->BgdtBlockNum(), reader->BgdtBlockSize())); - glcr::UniquePtr inode_table( - new InodeTable(reader, glcr::Move(bgdt))); - - return Ext2Driver(reader, glcr::Move(inode_table)); -} - -glcr::ErrorCode Ext2Driver::ProbePartition() { - Superblock* superblock = ext2_reader_->GetSuperblock(); - if (superblock->magic != 0xEF53) { - dbgln("Invalid EXT2 magic code: {x}"); - return glcr::INVALID_ARGUMENT; - } - -#if EXT2_DEBUG - dbgln("Block size: 0x{x}", 1024 << superblock->log_block_size); - - dbgln("Blocks: 0x{x} (0x{x} per group)", superblock->blocks_count, - superblock->blocks_per_group); - dbgln("Inodes: 0x{x} (0x{x} per group)", superblock->inodes_count, - superblock->inodes_per_group); - dbgln("Inode size: 0x{x}", superblock->inode_size); - - dbgln("Mounts: 0x{x} out of 0x{x}", superblock->mnt_count, - superblock->max_mnt_count); - dbgln("State: {x}", superblock->state); - - dbgln("Created by: {x}", superblock->creator_os); -#endif - - return glcr::OK; -} - -glcr::ErrorOr Ext2Driver::GetInode(uint32_t inode_number) { - return inode_table_->GetInode(inode_number); -} - -glcr::ErrorOr> Ext2Driver::ReadDirectory( - uint32_t inode_number) { - ASSIGN_OR_RETURN(Inode * inode, inode_table_->GetInode(inode_number)); - if (!(inode->mode & 0x4000)) { - dbgln("Reading non directory."); - return glcr::INVALID_ARGUMENT; - } - ASSIGN_OR_RETURN(mmth::OwnedMemoryRegion dir, ReadInode(inode_number, inode)); - - glcr::Vector directory; - - uint64_t addr = dir.vaddr(); - while (addr < dir.vaddr() + ext2_reader_->BlockSize()) { - DirEntry* entry = reinterpret_cast(addr); - directory.PushBack(*entry); - glcr::StringView name(entry->name, entry->name_len); -#if EXT2_DEBUG - switch (entry->file_type) { - case kExt2FtFile: - dbgln("FILE (0x{x}): {}", entry->inode, name); - break; - case kExt2FtDirectory: - dbgln("DIR (0x{x}): {}", entry->inode, name); - break; - default: - dbgln("UNK (0x{x}): {}", entry->inode, name); - } -#endif - addr += entry->record_length; - } - return directory; -} - -glcr::ErrorOr Ext2Driver::ReadFile( - uint64_t inode_number) { - ASSIGN_OR_RETURN(Inode * inode, inode_table_->GetInode(inode_number)); - - if (!(inode->mode & 0x8000)) { - dbgln("Reading non file."); - return glcr::INVALID_ARGUMENT; - } - return ReadInode(inode_number, inode); -} - -glcr::ErrorOr Ext2Driver::ReadInode(uint64_t inode_num, - Inode* inode) { - if (inode_cache_.Contains(inode_num)) { - return inode_cache_.at(inode_num).Duplicate(); - } - // This calculation is cursed. - uint64_t real_block_cnt = - (inode->blocks - 1) / (ext2_reader_->BlockSize() / 512) + 1; - - if (inode->block[14]) { - dbgln("Can't handle triply-indirect blocks yet."); - return glcr::UNIMPLEMENTED; - } - - mmth::OwnedMemoryRegion double_indirect_block; - if (inode->block[13]) { - ASSIGN_OR_RETURN(double_indirect_block, - ext2_reader_->ReadBlock(inode->block[13])); - } - - mmth::OwnedMemoryRegion indirect_block; - if (inode->block[12]) { - ASSIGN_OR_RETURN(indirect_block, ext2_reader_->ReadBlock(inode->block[12])); - } - - glcr::Vector blocks_to_read; - for (uint64_t i = 0; i < 12 && i < real_block_cnt; i++) { - blocks_to_read.PushBack(inode->block[i]); - } - - uint32_t* indr_block_array = - reinterpret_cast(indirect_block.vaddr()); - for (uint64_t i = 12; i < 268 && i < real_block_cnt; i++) { - uint64_t offset = i - 12; - blocks_to_read.PushBack(indr_block_array[offset]); - } - - uint32_t* dbl_indr_block_array = - reinterpret_cast(double_indirect_block.vaddr()); - for (uint64_t i = 0; i < 256; i++) { - uint64_t block = 268 + (256 * i); - if (block >= real_block_cnt) { - break; - } - ASSIGN_OR_RETURN(mmth::OwnedMemoryRegion single_indr_block, - ext2_reader_->ReadBlock(dbl_indr_block_array[i])); - uint32_t* single_indr_block_array = - reinterpret_cast(single_indr_block.vaddr()); - for (uint64_t j = 0; j < 256; j++) { - uint64_t block_inner = block + j; - if (block_inner >= real_block_cnt) { - break; - } - if (single_indr_block_array[j] != 0) { - blocks_to_read.PushBack(single_indr_block_array[j]); - } else { - dbgln("WARN skipping 0 block in inode"); - } - } - } - - ASSIGN_OR_RETURN(auto inode_mem, ext2_reader_->ReadBlocks(blocks_to_read)); - RET_ERR(inode_cache_.Insert(glcr::Move(inode_num), inode_mem.Duplicate())); - return inode_mem; -} diff --git a/sys/victoriafalls/fs/ext2/ext2_driver.h b/sys/victoriafalls/fs/ext2/ext2_driver.h deleted file mode 100644 index b3600cc..0000000 --- a/sys/victoriafalls/fs/ext2/ext2_driver.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "fs/ext2/ext2.h" -#include "fs/ext2/ext2_block_reader.h" -#include "fs/ext2/inode_table.h" - -class Ext2Driver { - public: - static glcr::ErrorOr Init( - const yellowstone::DenaliInfo& denali_info); - - glcr::ErrorCode ProbePartition(); - - glcr::ErrorOr GetInode(uint32_t inode_number); - - glcr::ErrorOr> ReadDirectory(uint32_t inode_number); - - glcr::ErrorOr ReadFile(uint64_t inode_number); - - private: - glcr::SharedPtr ext2_reader_; - glcr::UniquePtr inode_table_; - glcr::HashMap inode_cache_; - - Ext2Driver(const glcr::SharedPtr& reader, - glcr::UniquePtr inode_table) - : ext2_reader_(reader), inode_table_(glcr::Move(inode_table)) {} - - glcr::ErrorOr ReadInode(uint64_t inode_num, - Inode* inode); -}; diff --git a/sys/victoriafalls/fs/ext2/inode_table.cpp b/sys/victoriafalls/fs/ext2/inode_table.cpp deleted file mode 100644 index 12bab0f..0000000 --- a/sys/victoriafalls/fs/ext2/inode_table.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "fs/ext2/inode_table.h" - -InodeTable::InodeTable(const glcr::SharedPtr& reader, - mmth::OwnedMemoryRegion&& bgdt_region) - : ext2_reader_(reader), - bgdt_region_(glcr::Move(bgdt_region)), - bgdt_(reinterpret_cast(bgdt_region_.vaddr())) { - inode_tables_.Resize(ext2_reader_->NumberOfBlockGroups()); -} - -glcr::ErrorOr InodeTable::GetInode(uint32_t inode_num) { - uint64_t inodes_per_group = ext2_reader_->GetSuperblock()->inodes_per_group; - uint64_t block_group_num = (inode_num - 1) / inodes_per_group; - ASSIGN_OR_RETURN(Inode * root, GetRootOfInodeTable(block_group_num)); - uint64_t local_index = (inode_num - 1) % inodes_per_group; - return reinterpret_cast(reinterpret_cast(root) + - local_index * ext2_reader_->InodeSize()); -} - -glcr::ErrorOr InodeTable::GetRootOfInodeTable( - uint64_t block_group_num) { - if (block_group_num > ext2_reader_->NumberOfBlockGroups()) { - return glcr::INVALID_ARGUMENT; - } - - if (!inode_tables_[block_group_num]) { - ASSIGN_OR_RETURN( - inode_tables_[block_group_num], - ext2_reader_->ReadBlocks(bgdt_[block_group_num].inode_table, - ext2_reader_->InodeTableBlockSize())); - } - return reinterpret_cast(inode_tables_[block_group_num].vaddr()); -} diff --git a/sys/victoriafalls/fs/ext2/inode_table.h b/sys/victoriafalls/fs/ext2/inode_table.h deleted file mode 100644 index 18bb36d..0000000 --- a/sys/victoriafalls/fs/ext2/inode_table.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "fs/ext2/ext2_block_reader.h" - -class InodeTable { - public: - InodeTable(const glcr::SharedPtr& driver, - mmth::OwnedMemoryRegion&& bgdt_region); - - glcr::ErrorOr GetInode(uint32_t inode_num); - - private: - glcr::SharedPtr ext2_reader_; - mmth::OwnedMemoryRegion bgdt_region_; - BlockGroupDescriptor* bgdt_; - - glcr::Vector inode_tables_; - - glcr::ErrorOr GetRootOfInodeTable(uint64_t block_group_num); -}; diff --git a/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq b/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq deleted file mode 100644 index 5da582e..0000000 --- a/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq +++ /dev/null @@ -1,23 +0,0 @@ -interface VFS { - method OpenFile(OpenFileRequest) -> (OpenFileResponse); - method GetDirectory(GetDirectoryRequest) -> (Directory); -} - -message OpenFileRequest { - string path; -} - -message OpenFileResponse { - string path; - u64 size; - capability memory; -} - -message GetDirectoryRequest { - string path; -} - -message Directory { - // , separated list of filenames until we have repeated strings. - string filenames; -} diff --git a/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.client.cpp b/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.client.cpp deleted file mode 100644 index dec023a..0000000 --- a/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.client.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// Generated file - DO NOT MODIFY -#include "victoriafalls.yunq.client.h" - -#include -#include -#include -#include - - - - -VFSClient::~VFSClient() { - if (endpoint_ != 0) { - check(ZCapRelease(endpoint_)); - } -} - - - - -glcr::Status VFSClient::OpenFile(const OpenFileRequest& request, OpenFileResponse& response) { - - uint64_t buffer_size = kBufferSize; - uint64_t cap_size = kCapBufferSize; - - const uint32_t kSentinel = 0xBEEFDEAD; - buffer_.WriteAt(0, kSentinel); - buffer_.WriteAt(8, 0); - - cap_buffer_.Reset(); - - uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); - - - buffer_.WriteAt(4, 16 + length); - - z_cap_t reply_port_cap; - RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer_.RawPtr(), cap_buffer_.UsedSlots(), cap_buffer_.RawPtr(), &reply_port_cap)); - - // FIXME: Add a way to zero out the first buffer. - RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, buffer_.RawPtr(), &cap_size, cap_buffer_.RawPtr())); - - if (buffer_.At(0) != kSentinel) { - return glcr::InvalidResponse("Got an invalid response from server."); - } - - // Check Response Code. - RET_ERR(buffer_.At(8)); - - - yunq::MessageView resp_view(buffer_, 16); - RETURN_ERROR(response.ParseFromBytes(resp_view, cap_buffer_)); - - - return glcr::OK; -} - - - - -glcr::Status VFSClient::GetDirectory(const GetDirectoryRequest& request, Directory& response) { - - uint64_t buffer_size = kBufferSize; - uint64_t cap_size = kCapBufferSize; - - const uint32_t kSentinel = 0xBEEFDEAD; - buffer_.WriteAt(0, kSentinel); - buffer_.WriteAt(8, 1); - - cap_buffer_.Reset(); - - uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); - - - buffer_.WriteAt(4, 16 + length); - - z_cap_t reply_port_cap; - RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer_.RawPtr(), cap_buffer_.UsedSlots(), cap_buffer_.RawPtr(), &reply_port_cap)); - - // FIXME: Add a way to zero out the first buffer. - RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, buffer_.RawPtr(), &cap_size, cap_buffer_.RawPtr())); - - if (buffer_.At(0) != kSentinel) { - return glcr::InvalidResponse("Got an invalid response from server."); - } - - // Check Response Code. - RET_ERR(buffer_.At(8)); - - - yunq::MessageView resp_view(buffer_, 16); - RETURN_ERROR(response.ParseFromBytes(resp_view, cap_buffer_)); - - - return glcr::OK; -} - - - - diff --git a/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.client.h b/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.client.h deleted file mode 100644 index 35dab56..0000000 --- a/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.client.h +++ /dev/null @@ -1,37 +0,0 @@ -// Generated file - DO NOT MODIFY -#pragma once - -#include -#include -#include -#include - -#include "victoriafalls.yunq.h" - - -class VFSClient { - public: - VFSClient(z_cap_t VFS_cap) : endpoint_(VFS_cap) {} - VFSClient(const VFSClient&) = delete; - VFSClient(VFSClient&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;}; - ~VFSClient(); - - z_cap_t Capability() { return endpoint_; } - - - - [[nodiscard]] glcr::Status OpenFile(const OpenFileRequest& request, OpenFileResponse& response); - - - - [[nodiscard]] glcr::Status GetDirectory(const GetDirectoryRequest& request, Directory& response); - - - private: - z_cap_t endpoint_; - uint64_t kBufferSize = 0x1000; - glcr::ByteBuffer buffer_{kBufferSize}; - uint64_t kCapBufferSize = 0x10; - glcr::CapBuffer cap_buffer_{kCapBufferSize}; -}; - diff --git a/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.cpp b/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.cpp deleted file mode 100644 index 21fea87..0000000 --- a/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.cpp +++ /dev/null @@ -1,173 +0,0 @@ -// Generated file -- DO NOT MODIFY. -#include "victoriafalls.yunq.h" - -#include -#include - - -namespace { - -const uint64_t header_size = 24; // 4x uint32, 1x uint64 - -struct ExtPointer { - uint32_t offset; - uint32_t length; -}; - -} // namespace -glcr::Status OpenFileRequest::ParseFromBytes(const yunq::MessageView& message) { - RETURN_ERROR(ParseFromBytesInternal(message)); - return glcr::Status::Ok(); -} - -glcr::Status OpenFileRequest::ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer& caps) { - RETURN_ERROR(ParseFromBytesInternal(message)); - return glcr::Status::Ok(); -} - -glcr::Status OpenFileRequest::ParseFromBytesInternal(const yunq::MessageView& message) { - RETURN_ERROR(message.CheckHeader()); - // Parse path. - ASSIGN_OR_RETURN(path_, message.ReadField(0)); - - return glcr::Status::Ok(); -} - -uint64_t OpenFileRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { - yunq::Serializer serializer(bytes, offset, 1); - return SerializeInternal(serializer); -} - -uint64_t OpenFileRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { - yunq::Serializer serializer(bytes, offset, 1, caps); - return SerializeInternal(serializer); -} - -uint64_t OpenFileRequest::SerializeInternal(yunq::Serializer& serializer) const { - // Write path. - serializer.WriteField(0, path_); - - serializer.WriteHeader(); - - return serializer.size(); -} -glcr::Status OpenFileResponse::ParseFromBytes(const yunq::MessageView& message) { - RETURN_ERROR(ParseFromBytesInternal(message)); - // Parse memory. - ASSIGN_OR_RETURN(memory_, message.ReadCapability(2)); - return glcr::Status::Ok(); -} - -glcr::Status OpenFileResponse::ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer& caps) { - RETURN_ERROR(ParseFromBytesInternal(message)); - // Parse memory. - ASSIGN_OR_RETURN(memory_, message.ReadCapability(2, caps)); - return glcr::Status::Ok(); -} - -glcr::Status OpenFileResponse::ParseFromBytesInternal(const yunq::MessageView& message) { - RETURN_ERROR(message.CheckHeader()); - // Parse path. - ASSIGN_OR_RETURN(path_, message.ReadField(0)); - // Parse size. - ASSIGN_OR_RETURN(size_, message.ReadField(1)); - // Parse memory. - - return glcr::Status::Ok(); -} - -uint64_t OpenFileResponse::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { - yunq::Serializer serializer(bytes, offset, 3); - return SerializeInternal(serializer); -} - -uint64_t OpenFileResponse::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { - yunq::Serializer serializer(bytes, offset, 3, caps); - return SerializeInternal(serializer); -} - -uint64_t OpenFileResponse::SerializeInternal(yunq::Serializer& serializer) const { - // Write path. - serializer.WriteField(0, path_); - // Write size. - serializer.WriteField(1, size_); - // Write memory. - serializer.WriteCapability(2, memory_); - - serializer.WriteHeader(); - - return serializer.size(); -} -glcr::Status GetDirectoryRequest::ParseFromBytes(const yunq::MessageView& message) { - RETURN_ERROR(ParseFromBytesInternal(message)); - return glcr::Status::Ok(); -} - -glcr::Status GetDirectoryRequest::ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer& caps) { - RETURN_ERROR(ParseFromBytesInternal(message)); - return glcr::Status::Ok(); -} - -glcr::Status GetDirectoryRequest::ParseFromBytesInternal(const yunq::MessageView& message) { - RETURN_ERROR(message.CheckHeader()); - // Parse path. - ASSIGN_OR_RETURN(path_, message.ReadField(0)); - - return glcr::Status::Ok(); -} - -uint64_t GetDirectoryRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { - yunq::Serializer serializer(bytes, offset, 1); - return SerializeInternal(serializer); -} - -uint64_t GetDirectoryRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { - yunq::Serializer serializer(bytes, offset, 1, caps); - return SerializeInternal(serializer); -} - -uint64_t GetDirectoryRequest::SerializeInternal(yunq::Serializer& serializer) const { - // Write path. - serializer.WriteField(0, path_); - - serializer.WriteHeader(); - - return serializer.size(); -} -glcr::Status Directory::ParseFromBytes(const yunq::MessageView& message) { - RETURN_ERROR(ParseFromBytesInternal(message)); - return glcr::Status::Ok(); -} - -glcr::Status Directory::ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer& caps) { - RETURN_ERROR(ParseFromBytesInternal(message)); - return glcr::Status::Ok(); -} - -glcr::Status Directory::ParseFromBytesInternal(const yunq::MessageView& message) { - RETURN_ERROR(message.CheckHeader()); - // Parse filenames. - ASSIGN_OR_RETURN(filenames_, message.ReadField(0)); - - return glcr::Status::Ok(); -} - -uint64_t Directory::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { - yunq::Serializer serializer(bytes, offset, 1); - return SerializeInternal(serializer); -} - -uint64_t Directory::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { - yunq::Serializer serializer(bytes, offset, 1, caps); - return SerializeInternal(serializer); -} - -uint64_t Directory::SerializeInternal(yunq::Serializer& serializer) const { - // Write filenames. - serializer.WriteField(0, filenames_); - - serializer.WriteHeader(); - - return serializer.size(); -} - diff --git a/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.h b/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.h deleted file mode 100644 index 52daf7a..0000000 --- a/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.h +++ /dev/null @@ -1,124 +0,0 @@ -// Generated file - DO NOT MODIFY -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - - -class OpenFileRequest { - public: - OpenFileRequest() {} - // Delete copy and move until implemented. - OpenFileRequest(const OpenFileRequest&) = delete; - OpenFileRequest(OpenFileRequest&&) = default; - OpenFileRequest& operator=(OpenFileRequest&&) = default; - - [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message); - [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer&); - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; - - const glcr::String& path() const { return path_; } - glcr::String& mutable_path() { return path_; } - void set_path(const glcr::String& value) { path_ = value; } - - private: - glcr::String path_; - - // Parses everything except for caps. - glcr::Status ParseFromBytesInternal(const yunq::MessageView& message); - - uint64_t SerializeInternal(yunq::Serializer& serializer) const; -}; -class OpenFileResponse { - public: - OpenFileResponse() {} - // Delete copy and move until implemented. - OpenFileResponse(const OpenFileResponse&) = delete; - OpenFileResponse(OpenFileResponse&&) = default; - OpenFileResponse& operator=(OpenFileResponse&&) = default; - - [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message); - [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer&); - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; - - const glcr::String& path() const { return path_; } - glcr::String& mutable_path() { return path_; } - void set_path(const glcr::String& value) { path_ = value; } - - const uint64_t& size() const { return size_; } - uint64_t& mutable_size() { return size_; } - void set_size(const uint64_t& value) { size_ = value; } - - const z_cap_t& memory() const { return memory_; } - z_cap_t& mutable_memory() { return memory_; } - void set_memory(const z_cap_t& value) { memory_ = value; } - - private: - glcr::String path_; - uint64_t size_; - z_cap_t memory_; - - // Parses everything except for caps. - glcr::Status ParseFromBytesInternal(const yunq::MessageView& message); - - uint64_t SerializeInternal(yunq::Serializer& serializer) const; -}; -class GetDirectoryRequest { - public: - GetDirectoryRequest() {} - // Delete copy and move until implemented. - GetDirectoryRequest(const GetDirectoryRequest&) = delete; - GetDirectoryRequest(GetDirectoryRequest&&) = default; - GetDirectoryRequest& operator=(GetDirectoryRequest&&) = default; - - [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message); - [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer&); - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; - - const glcr::String& path() const { return path_; } - glcr::String& mutable_path() { return path_; } - void set_path(const glcr::String& value) { path_ = value; } - - private: - glcr::String path_; - - // Parses everything except for caps. - glcr::Status ParseFromBytesInternal(const yunq::MessageView& message); - - uint64_t SerializeInternal(yunq::Serializer& serializer) const; -}; -class Directory { - public: - Directory() {} - // Delete copy and move until implemented. - Directory(const Directory&) = delete; - Directory(Directory&&) = default; - Directory& operator=(Directory&&) = default; - - [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message); - [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer&); - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; - uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; - - const glcr::String& filenames() const { return filenames_; } - glcr::String& mutable_filenames() { return filenames_; } - void set_filenames(const glcr::String& value) { filenames_ = value; } - - private: - glcr::String filenames_; - - // Parses everything except for caps. - glcr::Status ParseFromBytesInternal(const yunq::MessageView& message); - - uint64_t SerializeInternal(yunq::Serializer& serializer) const; -}; - diff --git a/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.server.cpp b/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.server.cpp deleted file mode 100644 index f5e7061..0000000 --- a/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.server.cpp +++ /dev/null @@ -1,152 +0,0 @@ -// Generated file -- DO NOT MODIFY. -#include "victoriafalls.yunq.server.h" - -#include -#include - - -namespace { - -const uint32_t kSentinel = 0xBEEFDEAD; -const uint32_t kHeaderSize = 0x10; - -void WriteError(glcr::ByteBuffer& buffer, glcr::ErrorCode err) { - buffer.WriteAt(0, kSentinel); - buffer.WriteAt(4, kHeaderSize); - buffer.WriteAt(8, err); -} - -void WriteHeader(glcr::ByteBuffer& buffer, uint64_t message_length) { - buffer.WriteAt(0, kSentinel); - buffer.WriteAt(4, kHeaderSize + message_length); - buffer.WriteAt(8, glcr::OK); -} - -} // namespace - - - -void VFSServerBaseThreadBootstrap(void* server_base) { - ((VFSServerBase*)server_base)->ServerThread(); -} - -VFSServerBase::~VFSServerBase() { - if (endpoint_ != 0) { - check(ZCapRelease(endpoint_)); - } -} - -glcr::ErrorOr VFSServerBase::CreateClientCap() { - uint64_t client_cap; - RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap)); - return client_cap; -} - -glcr::ErrorOr VFSServerBase::CreateClient() { - uint64_t client_cap; - RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap)); - return VFSClient(client_cap); -} - -Thread VFSServerBase::RunServer() { - return Thread(VFSServerBaseThreadBootstrap, this); -} - -void VFSServerBase::ServerThread() { - glcr::ByteBuffer recv_buffer(0x1000); - glcr::CapBuffer recv_cap(0x10); - glcr::ByteBuffer resp_buffer(0x1000); - glcr::CapBuffer resp_cap(0x10); - z_cap_t reply_port_cap; - - while (true) { - uint64_t recv_cap_size = 0x10; - uint64_t recv_buf_size = 0x1000; - recv_cap.Reset(); - glcr::ErrorCode recv_err = static_cast(ZEndpointRecv(endpoint_, &recv_buf_size, recv_buffer.RawPtr(), &recv_cap_size, recv_cap.RawPtr(), &reply_port_cap)); - if (recv_err != glcr::OK) { - dbgln("Error in receive: {x}", recv_err); - continue; - } - - uint64_t resp_length = 0; - - glcr::ErrorCode reply_err = glcr::OK; - resp_cap.Reset(); - glcr::Status err = HandleRequest(recv_buffer, recv_cap, resp_buffer, resp_length, resp_cap); - if (!err) { - WriteError(resp_buffer, err.code()); - dbgln("Responding Error {}", err.message()); - reply_err = static_cast(ZReplyPortSend(reply_port_cap, kHeaderSize, resp_buffer.RawPtr(), 0, nullptr)); - } else { - WriteHeader(resp_buffer, resp_length); - reply_err = static_cast(ZReplyPortSend(reply_port_cap, kHeaderSize + resp_length, resp_buffer.RawPtr(), resp_cap.UsedSlots(), resp_cap.RawPtr())); - } - if (reply_err != glcr::OK) { - dbgln("Error in reply: {x}", reply_err); - } - } - -} - -glcr::Status VFSServerBase::HandleRequest(const glcr::ByteBuffer& request, - const glcr::CapBuffer& req_caps, - glcr::ByteBuffer& response, uint64_t& resp_length, - glcr::CapBuffer& resp_caps) { - if (request.At(0) != kSentinel) { - return glcr::InvalidArgument("Request Not Valid"); - } - - uint64_t method_select = request.At(8); - - switch(method_select) { - case 0: { - - - OpenFileRequest yunq_request; - yunq::MessageView request_view(request, kHeaderSize); - RETURN_ERROR(yunq_request.ParseFromBytes(request_view, req_caps)); - - - - OpenFileResponse yunq_response; - - - - RETURN_ERROR(HandleOpenFile(yunq_request, yunq_response)); - - - - resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); - - break; - } - case 1: { - - - GetDirectoryRequest yunq_request; - yunq::MessageView request_view(request, kHeaderSize); - RETURN_ERROR(yunq_request.ParseFromBytes(request_view, req_caps)); - - - - Directory yunq_response; - - - - RETURN_ERROR(HandleGetDirectory(yunq_request, yunq_response)); - - - - resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); - - break; - } - default: { - return glcr::Unimplemented("Method unimplemented by server."); - } - } - return glcr::Status::Ok(); -} - - diff --git a/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.server.h b/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.server.h deleted file mode 100644 index bf91f66..0000000 --- a/sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq.server.h +++ /dev/null @@ -1,50 +0,0 @@ -// Generated File -- DO NOT MODIFY. -#pragma once - -#include -#include -#include -#include - -#include "victoriafalls.yunq.h" -#include "victoriafalls.yunq.client.h" - - - - - -class VFSServerBase { - public: - VFSServerBase(z_cap_t VFS_cap) : endpoint_(VFS_cap) {} - VFSServerBase(const VFSServerBase&) = delete; - VFSServerBase(VFSServerBase&&) = delete; - virtual ~VFSServerBase(); - - glcr::ErrorOr CreateClientCap(); - glcr::ErrorOr CreateClient(); - - [[nodiscard]] Thread RunServer(); - - - - [[nodiscard]] virtual glcr::Status HandleOpenFile(const OpenFileRequest&, OpenFileResponse&) = 0; - - - - [[nodiscard]] virtual glcr::Status HandleGetDirectory(const GetDirectoryRequest&, Directory&) = 0; - - - - private: - z_cap_t endpoint_; - - friend void VFSServerBaseThreadBootstrap(void*); - void ServerThread(); - - [[nodiscard]] glcr::Status HandleRequest(const glcr::ByteBuffer& request, const glcr::CapBuffer& req_caps, - glcr::ByteBuffer& response, uint64_t& resp_length, - glcr::CapBuffer& resp_caps); -}; - - - diff --git a/sys/victoriafalls/victoriafalls.cpp b/sys/victoriafalls/victoriafalls.cpp deleted file mode 100644 index 56ee383..0000000 --- a/sys/victoriafalls/victoriafalls.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include -#include - -#include "fs/ext2/ext2_driver.h" -#include "victoriafalls_server.h" - -using yellowstone::DenaliInfo; -using yellowstone::RegisterEndpointRequest; -using yellowstone::YellowstoneClient; - -uint64_t main(uint64_t init_cap) { - ParseInitPort(init_cap); - - dbgln("VFs Started"); - - YellowstoneClient yellowstone(gInitEndpointCap); - DenaliInfo denali_info; - check(yellowstone.GetDenali(denali_info)); - ASSIGN_OR_RETURN(Ext2Driver ext2, Ext2Driver::Init(denali_info)); - - ASSIGN_OR_RETURN(auto server, VFSServer::Create(ext2)); - - Thread server_thread = server->RunServer(); - - RegisterEndpointRequest req; - req.set_endpoint_name("victoriafalls"); - ASSIGN_OR_RETURN(auto client_cap, server->CreateClientCap()); - req.set_endpoint_capability(client_cap); - check(yellowstone.RegisterEndpoint(req)); - - RET_ERR(server_thread.Join()); - - return 0; -} diff --git a/sys/victoriafalls/victoriafalls_server.cpp b/sys/victoriafalls/victoriafalls_server.cpp deleted file mode 100644 index c48be7b..0000000 --- a/sys/victoriafalls/victoriafalls_server.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include "victoriafalls_server.h" - -#include -#include -#include - -glcr::ErrorOr> VFSServer::Create( - Ext2Driver& driver) { - z_cap_t endpoint_cap; - RET_ERR(ZEndpointCreate(&endpoint_cap)); - return glcr::UniquePtr(new VFSServer(endpoint_cap, driver)); -} - -glcr::Status VFSServer::HandleOpenFile(const OpenFileRequest& request, - OpenFileResponse& response) { - auto path_tokens = glcr::StrSplit(request.path(), '/'); - // Require all paths to be absolute rather than relative. - // If the path starts with '/' then the first token will be empty. - if (path_tokens.at(0) != "") { - return glcr::InvalidArgument("Open file supports only absolute paths."); - } - - ASSIGN_OR_RETURN(auto files, driver_.ReadDirectory(2)); - for (uint64_t i = 1; i < path_tokens.size() - 1; i++) { - bool found_token = false; - for (uint64_t j = 0; j < files.size() && !found_token; j++) { - if (path_tokens.at(i) == - glcr::StringView(files.at(j).name, files.at(j).name_len)) { - ASSIGN_OR_RETURN(files, driver_.ReadDirectory(files.at(j).inode)); - found_token = true; - } - } - if (!found_token) { - return glcr::NotFound(glcr::StrFormat("Directory '{}' not found.", - glcr::String(path_tokens.at(i)))); - } - } - - uint64_t inode_num; - mmth::OwnedMemoryRegion region; - for (uint64_t j = 0; j < files.size(); j++) { - if (path_tokens.at(path_tokens.size() - 1) == - glcr::StringView(files.at(j).name, files.at(j).name_len)) { - inode_num = files.at(j).inode; - ASSIGN_OR_RETURN(region, driver_.ReadFile(files.at(j).inode)); - break; - } - } - if (!region) { - return glcr::NotFound( - glcr::StrFormat("File '{}' not found.", - glcr::String(path_tokens.at(path_tokens.size() - 1)))); - } - - response.set_path(request.path()); - // FIXME: There isn't really a reason we need to map the file into memory then - // duplicate the cap. In the future just get the cap from the read then pass - // it to the caller directly. - response.set_memory(region.DuplicateCap()); - // TODO: Consider folding this up into the actual read call. - ASSIGN_OR_RETURN(Inode * inode, driver_.GetInode(inode_num)); - // FIXME: This technically only sets the lower 32 bits. - response.set_size(inode->size); - return glcr::Status::Ok(); -} - -glcr::Status VFSServer::HandleGetDirectory(const GetDirectoryRequest& request, - Directory& response) { - auto path_tokens = glcr::StrSplit(request.path(), '/'); - - if (path_tokens.at(0) != "") { - return glcr::InvalidArgument("Get Directory only supports absolute path."); - } - - // If there is a trailing slash we can get rid of the empty string. - if (path_tokens.at(path_tokens.size() - 1) == "") { - path_tokens.PopBack(); - } - - ASSIGN_OR_RETURN(auto files, driver_.ReadDirectory(2)); - for (uint64_t i = 1; i < path_tokens.size(); i++) { - bool found_token = false; - for (uint64_t j = 0; j < files.size() && !found_token; j++) { - if (path_tokens.at(i) == - glcr::StringView(files.at(j).name, files.at(j).name_len)) { - ASSIGN_OR_RETURN(files, driver_.ReadDirectory(files.at(j).inode)); - found_token = true; - } - } - if (!found_token) { - return glcr::NotFound(glcr::StrFormat("Directory '{}' not found.", - glcr::String(path_tokens.at(i)))); - } - } - - glcr::VariableStringBuilder filelist; - for (const DirEntry& file : files) { - filelist.PushBack(glcr::StringView(file.name, file.name_len)); - filelist.PushBack(','); - } - // Remove trailing comma. - if (filelist.size() > 0) { - filelist.DeleteLast(); - } - - response.set_filenames(filelist.ToString()); - - return glcr::Status::Ok(); -} diff --git a/sys/victoriafalls/victoriafalls_server.h b/sys/victoriafalls/victoriafalls_server.h deleted file mode 100644 index 8716093..0000000 --- a/sys/victoriafalls/victoriafalls_server.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include - -#include "fs/ext2/ext2_driver.h" -#include "victoriafalls/victoriafalls.yunq.server.h" - -class VFSServer : public VFSServerBase { - public: - static glcr::ErrorOr> Create(Ext2Driver& driver); - - glcr::Status HandleOpenFile(const OpenFileRequest&, - OpenFileResponse&) override; - - glcr::Status HandleGetDirectory(const GetDirectoryRequest&, - Directory&) override; - - private: - // FIXME: Don't store this as a reference. - Ext2Driver& driver_; - - VFSServer(z_cap_t endpoint_cap, Ext2Driver& driver) - : VFSServerBase(endpoint_cap), driver_(driver) {} -}; diff --git a/yunq/rust/src/codegen.rs b/yunq/rust/src/codegen.rs index 237414b..7eefb66 100644 --- a/yunq/rust/src/codegen.rs +++ b/yunq/rust/src/codegen.rs @@ -34,7 +34,7 @@ fn serialize_field(field: &Field) -> proc_macro2::TokenStream { { let rep_offset = next_extension; let rep_len = self.#name.len() as u32; - next_extension = yunq::message::serialize_repeated(buf, next_extension as usize, &self.#name)? as u32; + next_extension = yunq::message::serialize_repeated(buf, offset + next_extension as usize, &self.#name)? as u32; buf.write_at(yunq::message::field_offset(offset, #ind), rep_offset)?; buf.write_at(yunq::message::field_offset(offset, #ind) + 4, rep_len)?; @@ -46,7 +46,7 @@ fn serialize_field(field: &Field) -> proc_macro2::TokenStream { { let rep_offset = next_extension; let rep_len = self.#name.len() as u32; - next_extension = yunq::message::serialize_repeated_message(buf, next_extension as usize, &self.#name, caps)? as u32; + next_extension = yunq::message::serialize_repeated_message(buf, offset + next_extension as usize, &self.#name, caps)? as u32; buf.write_at(yunq::message::field_offset(offset, #ind), rep_offset)?; buf.write_at(yunq::message::field_offset(offset, #ind) + 4, rep_len)?; @@ -232,7 +232,7 @@ fn generate_message(message: &Message) -> TokenStream { let serialize = generate_serialize(message); let parse = generate_parse(message); quote! { - #[derive(PartialEq, Eq)] + #[derive(PartialEq, Eq, Clone, Debug)] pub struct #name { #(pub #field_names: #field_types),* }