Nothing to see here, move along meow
0

Configure Feed

Select the types of activity you want to include in your feed.

at main 8.2 kB View raw
1#![cfg_attr(feature = "userspace", no_std)] 2#![cfg_attr(feature = "userspace", no_main)] 3#![allow(dead_code)] 4 5#[cfg(not(feature = "userspace"))] 6fn main() {} 7 8#[cfg(feature = "userspace")] 9mod service { 10 use lancer_lancerfs::dispatch::FsState; 11 use lancer_lancerfs::handle::HandleTableSet; 12 use lancer_lancerfs::{block_io, blockref_block_num, cache, commit, dispatch, ipc_proto, pool}; 13 use lancer_user::syscall; 14 15 const BLOCK_RING_BASE_SLOT: u64 = 64; 16 const BLOCK_RING_FRAME_COUNT: u64 = 16; 17 const NOTIF_SLOT: u64 = 3; 18 #[allow(dead_code)] 19 const DRIVER_NOTIF_SLOT: u64 = 4; 20 const CLIENT_RING_BASE_SLOT: u64 = 96; 21 const CLIENT_RING_FRAME_COUNT: u64 = 16; 22 const CLIENT_NOTIF_SLOT: u64 = 6; 23 24 const BLOCK_RING_VADDR: u64 = 0x5000_0000; 25 const CLIENT_RING_VADDR: u64 = 0x5010_0000; 26 const RING_DATA_OFFSET: usize = 8192; 27 const RING_DATA_PAGES: usize = 14; 28 29 const CLIENT_RING_DATA_OFFSET: usize = 8192; 30 const CLIENT_RING_DATA_PAGES: usize = 14; 31 32 static mut CACHE: cache::BlockCache = cache::BlockCache::new(); 33 static mut POOL: pool::NodePool = pool::NodePool::new(); 34 static mut HANDLES: HandleTableSet = HandleTableSet::new(); 35 36 fn mount(bio: &mut block_io::BlockIo, cache_ref: &mut cache::BlockCache) -> FsState { 37 lancer_user::show!(lancerfs, "reading superblocks"); 38 39 let sb_pair = match commit::load_validated_superblock_pair(bio) { 40 Ok(pair) => { 41 lancer_user::show!(lancerfs, "superblock pair loaded"); 42 pair 43 } 44 Err(_) => { 45 lancer_user::show!(lancerfs, error, "no valid superblock found"); 46 syscall::exit(); 47 } 48 }; 49 50 #[allow(clippy::deref_addrof)] 51 let pool_ref = unsafe { &mut *(&raw mut POOL) }; 52 53 let tree_root = sb_pair.active().tree_root; 54 let root_ref = match lancer_lancerfs::btree::btree_lookup( 55 pool_ref, cache_ref, bio, &tree_root, 1, None, 56 ) { 57 Ok(Some(r)) => r, 58 _ => { 59 lancer_user::show!(lancerfs, error, "root inode not found in metadata tree"); 60 syscall::exit(); 61 } 62 }; 63 pool_ref.clear_all(); 64 65 let root_block = blockref_block_num(&root_ref); 66 let root_inode = match lancer_lancerfs::file::read_inode(cache_ref, bio, root_block) { 67 Ok(inode) => inode, 68 Err(_) => { 69 lancer_user::show!(lancerfs, error, "failed to read root inode"); 70 syscall::exit(); 71 } 72 }; 73 74 { 75 let active = sb_pair.active(); 76 lancer_user::show!( 77 lancerfs, 78 "mounted {} blocks seq {} txn {} tree_root {:#x} freemap_root {:#x}", 79 active.total_blocks, 80 active.sequence, 81 active.transaction_id, 82 active.tree_root.physical_block_addr(), 83 active.freemap_root.physical_block_addr() 84 ); 85 } 86 87 let mut state = FsState::from_superblock_pair( 88 sb_pair, 89 root_block, 90 root_inode.object_id, 91 root_inode.generation, 92 ); 93 94 lancer_user::show!( 95 lancerfs, 96 "ditto allocable {} scrub cursor {}", 97 state.ditto.allocable_data_blocks(), 98 state.scrub.cursor() 99 ); 100 101 state.handles = unsafe { core::ptr::read(&raw const HANDLES) }; 102 state 103 } 104 105 #[unsafe(no_mangle)] 106 pub extern "C" fn lancer_main() -> ! { 107 lancer_user::show!(lancerfs, "starting"); 108 109 match (0..BLOCK_RING_FRAME_COUNT).all(|i| { 110 syscall::frame_map(BLOCK_RING_BASE_SLOT + i, BLOCK_RING_VADDR + i * 4096, 1) >= 0 111 }) { 112 true => {} 113 false => { 114 lancer_user::show!(lancerfs, error, "failed to map block ring"); 115 syscall::exit(); 116 } 117 } 118 119 let ring_base = BLOCK_RING_VADDR as *mut u8; 120 121 let request_ring = 122 unsafe { lancer_core::packet_ring::PacketRingWriter::init(ring_base, 4096, 32) }; 123 let response_ring = unsafe { 124 lancer_core::packet_ring::PacketRingReader::attach(ring_base.add(4096), 4096) 125 }; 126 let data_area = (BLOCK_RING_VADDR as usize + RING_DATA_OFFSET) as *mut u8; 127 let data_area_size = RING_DATA_PAGES * 4096; 128 129 lancer_user::show!(lancerfs, "waiting for nvme driver"); 130 syscall::notify_wait(NOTIF_SLOT); 131 132 let sector_size = 512u32; 133 let mut bio = unsafe { 134 block_io::BlockIo::init( 135 request_ring, 136 response_ring, 137 data_area, 138 data_area_size, 139 sector_size, 140 ) 141 }; 142 143 #[allow(clippy::deref_addrof)] 144 let cache_ref = unsafe { &mut *(&raw mut CACHE) }; 145 146 let mut fs_state = mount(&mut bio, cache_ref); 147 148 let has_client_ring = (0..CLIENT_RING_FRAME_COUNT).all(|i| { 149 syscall::frame_map(CLIENT_RING_BASE_SLOT + i, CLIENT_RING_VADDR + i * 4096, 1) >= 0 150 }); 151 152 let (client_request_ring, client_response_ring, client_data_area, client_data_area_size) = 153 match has_client_ring { 154 true => { 155 lancer_user::show!(lancerfs, "client ring mapped"); 156 let client_base = CLIENT_RING_VADDR as *mut u8; 157 let crr = unsafe { 158 lancer_core::packet_ring::PacketRingReader::attach(client_base, 4096) 159 }; 160 let crw = unsafe { 161 lancer_core::packet_ring::PacketRingWriter::init( 162 client_base.wrapping_add(4096), 163 4096, 164 32, 165 ) 166 }; 167 let cda = (CLIENT_RING_VADDR as usize + CLIENT_RING_DATA_OFFSET) as *mut u8; 168 let cds = CLIENT_RING_DATA_PAGES * 4096; 169 (Some(crr), Some(crw), cda, cds) 170 } 171 false => { 172 lancer_user::show!(lancerfs, "no client ring, standalone mode"); 173 (None, None, core::ptr::null_mut(), 0) 174 } 175 }; 176 177 #[allow(clippy::deref_addrof)] 178 let pool = unsafe { &mut *(&raw mut POOL) }; 179 180 let mut scratch = [0u8; 8192]; 181 let mut hash_table = [0u16; 1 << 12]; 182 183 lancer_user::show!(lancerfs, "entering dispatch loop"); 184 syscall::notify_signal(CLIENT_NOTIF_SLOT, 1); 185 186 let client_pid: u16 = 0; 187 let _ = fs_state.handles.install_root_handle( 188 client_pid, 189 fs_state.root_object_id, 190 fs_state.root_generation, 191 fs_state.root_inode_block, 192 ); 193 194 loop { 195 syscall::notify_wait(NOTIF_SLOT); 196 197 if let (Some(reader), Some(writer)) = (&client_request_ring, &client_response_ring) { 198 let mut req_buf = [0u8; 64]; 199 let mut processed = 0u32; 200 (0..64u32).for_each(|_| { 201 if let Some(len) = reader.try_pop(&mut req_buf) 202 && len >= ipc_proto::FsRequest::SIZE 203 && let Some(req) = ipc_proto::FsRequest::from_bytes(&req_buf) 204 { 205 let resp = dispatch::dispatch_request( 206 &req, 207 pool, 208 cache_ref, 209 &mut bio, 210 &mut fs_state, 211 client_data_area, 212 client_data_area_size, 213 client_pid, 214 &mut scratch, 215 &mut hash_table, 216 ); 217 let _ = writer.try_push(resp.as_bytes()); 218 processed += 1; 219 } 220 }); 221 222 if processed > 0 { 223 syscall::notify_signal(CLIENT_NOTIF_SLOT, 1); 224 } 225 } 226 } 227 } 228}