axfs_devfs/
lib.rs

1//! Device filesystem used by [ArceOS](https://github.com/arceos-org/arceos).
2//!
3//! The implementation is based on [`axfs_vfs`].
4
5#![cfg_attr(not(test), no_std)]
6
7extern crate alloc;
8
9mod dir;
10mod null;
11mod urandom;
12mod zero;
13
14#[cfg(test)]
15mod tests;
16
17pub use self::dir::DirNode;
18pub use self::null::NullDev;
19pub use self::urandom::UrandomDev;
20pub use self::zero::ZeroDev;
21
22use alloc::sync::Arc;
23use axfs_vfs::{VfsNodeRef, VfsOps, VfsResult};
24use spin::once::Once;
25
26/// A device filesystem that implements [`axfs_vfs::VfsOps`].
27pub struct DeviceFileSystem {
28    parent: Once<VfsNodeRef>,
29    root: Arc<DirNode>,
30}
31
32impl DeviceFileSystem {
33    /// Create a new instance.
34    pub fn new() -> Self {
35        Self {
36            parent: Once::new(),
37            root: DirNode::new(None),
38        }
39    }
40
41    /// Create a subdirectory at the root directory.
42    pub fn mkdir(&self, name: &'static str) -> Arc<DirNode> {
43        self.root.mkdir(name)
44    }
45
46    /// Add a node to the root directory.
47    ///
48    /// The node must implement [`axfs_vfs::VfsNodeOps`], and be wrapped in [`Arc`].
49    pub fn add(&self, name: &'static str, node: VfsNodeRef) {
50        self.root.add(name, node);
51    }
52}
53
54impl VfsOps for DeviceFileSystem {
55    fn mount(&self, _path: &str, mount_point: VfsNodeRef) -> VfsResult {
56        if let Some(parent) = mount_point.parent() {
57            self.root.set_parent(Some(self.parent.call_once(|| parent)));
58        } else {
59            self.root.set_parent(None);
60        }
61        Ok(())
62    }
63
64    fn root_dir(&self) -> VfsNodeRef {
65        self.root.clone()
66    }
67}
68
69impl Default for DeviceFileSystem {
70    fn default() -> Self {
71        Self::new()
72    }
73}