starnix_core/vfs/
fs_registry.rs1use crate::security;
6use crate::task::CurrentTask;
7use crate::vfs::{FileSystemHandle, FileSystemOptions, FsStr, FsString};
8use starnix_sync::{Locked, Mutex, Unlocked};
9use starnix_uapi::errors::Errno;
10use std::collections::BTreeMap;
11use std::sync::Arc;
12
13type CreateFs = Arc<
14 dyn Fn(
15 &mut Locked<Unlocked>,
16 &CurrentTask,
17 FileSystemOptions,
18 ) -> Result<FileSystemHandle, Errno>
19 + Send
20 + Sync
21 + 'static,
22>;
23
24#[derive(Default)]
25pub struct FsRegistry {
26 registry: Mutex<BTreeMap<FsString, CreateFs>>,
27}
28
29impl FsRegistry {
30 pub fn register<F>(&self, fs_type: &FsStr, create_fs: F)
31 where
32 F: Fn(
33 &mut Locked<Unlocked>,
34 &CurrentTask,
35 FileSystemOptions,
36 ) -> Result<FileSystemHandle, Errno>
37 + Send
38 + Sync
39 + 'static,
40 {
41 let existing = self.registry.lock().insert(fs_type.into(), Arc::new(create_fs));
42 assert!(existing.is_none());
43 }
44
45 pub fn create(
46 &self,
47 locked: &mut Locked<Unlocked>,
48 current_task: &CurrentTask,
49 fs_type: &FsStr,
50 options: FileSystemOptions,
51 ) -> Option<Result<FileSystemHandle, Errno>> {
52 let create_fs = self.registry.lock().get(fs_type).map(Arc::clone)?;
53 Some(create_fs(locked, current_task, options).and_then(|fs| {
54 assert_eq!(fs_type, fs.name(), "FileSystem::name() must match the registered name.");
55 security::file_system_resolve_security(locked, ¤t_task, &fs)?;
56 Ok(fs)
57 }))
58 }
59
60 pub fn list_all(&self) -> Vec<FsString> {
61 self.registry.lock().keys().cloned().collect()
62 }
63}