strat9_kernel/vfs/
scheme_router.rs1use crate::{
17 ipc::port::PortId,
18 sync::SpinLock,
19 syscall::error::SyscallError,
20 vfs::scheme::{DynScheme, IpcScheme, KernelScheme},
21};
22use alloc::{collections::BTreeMap, string::String, sync::Arc, vec::Vec};
23use spin::RwLock;
24
25pub struct SchemeEntry {
27 pub name: String,
28 pub scheme: DynScheme,
29}
30
31static SCHEME_ROUTER: RwLock<SchemeRouter> = RwLock::new(SchemeRouter::new());
33static INITFS_KERNEL_SCHEME: SpinLock<Option<Arc<KernelScheme>>> = SpinLock::new(None);
34
35pub struct SchemeRouter {
37 schemes: BTreeMap<String, SchemeEntry>,
39 next_id: u64,
41}
42
43impl SchemeRouter {
44 const fn new() -> Self {
46 Self {
47 schemes: BTreeMap::new(),
48 next_id: 1,
49 }
50 }
51
52 pub fn register(&mut self, name: &str, scheme: DynScheme) -> Result<u64, SyscallError> {
54 if self.schemes.contains_key(name) {
55 return Err(SyscallError::AlreadyExists);
56 }
57
58 let id = self.next_id;
59 self.next_id += 1;
60
61 self.schemes.insert(
62 String::from(name),
63 SchemeEntry {
64 name: String::from(name),
65 scheme,
66 },
67 );
68
69 Ok(id)
70 }
71
72 pub fn get(&self, name: &str) -> Option<DynScheme> {
74 self.schemes.get(name).map(|e| e.scheme.clone())
75 }
76
77 pub fn list(&self) -> Vec<String> {
79 self.schemes.keys().cloned().collect()
80 }
81
82 pub fn unregister(&mut self, name: &str) -> Result<(), SyscallError> {
84 self.schemes
85 .remove(name)
86 .map(|_| ())
87 .ok_or(SyscallError::BadHandle)
88 }
89}
90
91pub fn register_scheme(name: &str, scheme: DynScheme) -> Result<u64, SyscallError> {
93 SCHEME_ROUTER.write().register(name, scheme)
94}
95
96pub fn get_scheme(name: &str) -> Option<DynScheme> {
98 SCHEME_ROUTER.read().get(name)
99}
100
101pub fn mount_scheme(name: &str, path: &str) -> Result<(), SyscallError> {
103 let scheme = get_scheme(name).ok_or(SyscallError::BadHandle)?;
104 crate::vfs::mount::mount(path, scheme)
105}
106
107pub fn init_builtin_schemes() -> Result<(), SyscallError> {
109 let kernel_scheme = Arc::new(KernelScheme::new());
111 register_scheme("kernel", kernel_scheme.clone())?;
112 mount_scheme("kernel", "/initfs")?;
113 *INITFS_KERNEL_SCHEME.lock() = Some(kernel_scheme);
114
115 log::info!("[SchemeRouter] Built-in schemes initialized");
116 Ok(())
117}
118
119pub fn register_initfs_file(path: &str, base: *const u8, len: usize) -> Result<(), SyscallError> {
121 let scheme = INITFS_KERNEL_SCHEME
122 .lock()
123 .clone()
124 .ok_or(SyscallError::BadHandle)?;
125 scheme.register(path, base, len);
126 Ok(())
127}
128
129pub fn register_ipc_scheme(name: &str, port_id: PortId) -> Result<u64, SyscallError> {
131 let ipc_scheme = Arc::new(IpcScheme::new(port_id));
132 register_scheme(name, ipc_scheme)
133}
134
135pub fn list_schemes() -> Vec<String> {
137 SCHEME_ROUTER.read().list()
138}