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