Skip to main content

starnix_core/vfs/
fs_registry.rs

1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use 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(&current_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}