axfs_vfs/
lib.rs

1//! Virtual filesystem interfaces used by [ArceOS](https://github.com/arceos-org/arceos).
2//!
3//! A filesystem is a set of files and directories (symbol links are not
4//! supported currently), collectively referred to as **nodes**, which are
5//! conceptually similar to [inodes] in Linux. A file system needs to implement
6//! the [`VfsOps`] trait, its files and directories need to implement the
7//! [`VfsNodeOps`] trait.
8//!
9//! The [`VfsOps`] trait provides the following operations on a filesystem:
10//!
11//! - [`mount()`](VfsOps::mount): Do something when the filesystem is mounted.
12//! - [`umount()`](VfsOps::umount): Do something when the filesystem is unmounted.
13//! - [`format()`](VfsOps::format): Format the filesystem.
14//! - [`statfs()`](VfsOps::statfs): Get the attributes of the filesystem.
15//! - [`root_dir()`](VfsOps::root_dir): Get root directory of the filesystem.
16//!
17//! The [`VfsNodeOps`] trait provides the following operations on a file or a
18//! directory:
19//!
20//! | Operation | Description | file/directory |
21//! | --- | --- | --- |
22//! | [`open()`](VfsNodeOps::open) | Do something when the node is opened | both |
23//! | [`release()`](VfsNodeOps::release) | Do something when the node is closed | both |
24//! | [`get_attr()`](VfsNodeOps::get_attr) | Get the attributes of the node | both |
25//! | [`read_at()`](VfsNodeOps::read_at) | Read data from the file | file |
26//! | [`write_at()`](VfsNodeOps::write_at) | Write data to the file | file |
27//! | [`fsync()`](VfsNodeOps::fsync) | Synchronize the file data to disk | file |
28//! | [`truncate()`](VfsNodeOps::truncate) | Truncate the file | file |
29//! | [`parent()`](VfsNodeOps::parent) | Get the parent directory | directory |
30//! | [`lookup()`](VfsNodeOps::lookup) | Lookup the node with the given path | directory |
31//! | [`create()`](VfsNodeOps::create) | Create a new node with the given path | directory |
32//! | [`remove()`](VfsNodeOps::remove) | Remove the node with the given path | directory |
33//! | [`read_dir()`](VfsNodeOps::read_dir) | Read directory entries | directory |
34//!
35//! [inodes]: https://en.wikipedia.org/wiki/Inode
36
37#![no_std]
38
39extern crate alloc;
40
41mod macros;
42mod structs;
43
44pub mod path;
45
46use alloc::sync::Arc;
47use axerrno::{ax_err, AxError, AxResult};
48
49pub use self::structs::{FileSystemInfo, VfsDirEntry, VfsNodeAttr, VfsNodePerm, VfsNodeType};
50
51/// A wrapper of [`Arc<dyn VfsNodeOps>`].
52pub type VfsNodeRef = Arc<dyn VfsNodeOps>;
53
54/// Alias of [`AxError`].
55pub type VfsError = AxError;
56
57/// Alias of [`AxResult`].
58pub type VfsResult<T = ()> = AxResult<T>;
59
60/// Filesystem operations.
61pub trait VfsOps: Send + Sync {
62    /// Do something when the filesystem is mounted.
63    fn mount(&self, _path: &str, _mount_point: VfsNodeRef) -> VfsResult {
64        Ok(())
65    }
66
67    /// Do something when the filesystem is unmounted.
68    fn umount(&self) -> VfsResult {
69        Ok(())
70    }
71
72    /// Format the filesystem.
73    fn format(&self) -> VfsResult {
74        ax_err!(Unsupported)
75    }
76
77    /// Get the attributes of the filesystem.
78    fn statfs(&self) -> VfsResult<FileSystemInfo> {
79        ax_err!(Unsupported)
80    }
81
82    /// Get the root directory of the filesystem.
83    fn root_dir(&self) -> VfsNodeRef;
84}
85
86/// Node (file/directory) operations.
87pub trait VfsNodeOps: Send + Sync {
88    /// Do something when the node is opened.
89    fn open(&self) -> VfsResult {
90        Ok(())
91    }
92
93    /// Do something when the node is closed.
94    fn release(&self) -> VfsResult {
95        Ok(())
96    }
97
98    /// Get the attributes of the node.
99    fn get_attr(&self) -> VfsResult<VfsNodeAttr> {
100        ax_err!(Unsupported)
101    }
102
103    // file operations:
104
105    /// Read data from the file at the given offset.
106    fn read_at(&self, _offset: u64, _buf: &mut [u8]) -> VfsResult<usize> {
107        ax_err!(InvalidInput)
108    }
109
110    /// Write data to the file at the given offset.
111    fn write_at(&self, _offset: u64, _buf: &[u8]) -> VfsResult<usize> {
112        ax_err!(InvalidInput)
113    }
114
115    /// Flush the file, synchronize the data to disk.
116    fn fsync(&self) -> VfsResult {
117        ax_err!(InvalidInput)
118    }
119
120    /// Truncate the file to the given size.
121    fn truncate(&self, _size: u64) -> VfsResult {
122        ax_err!(InvalidInput)
123    }
124
125    // directory operations:
126
127    /// Get the parent directory of this directory.
128    ///
129    /// Return `None` if the node is a file.
130    fn parent(&self) -> Option<VfsNodeRef> {
131        None
132    }
133
134    /// Lookup the node with given `path` in the directory.
135    ///
136    /// Return the node if found.
137    fn lookup(self: Arc<Self>, _path: &str) -> VfsResult<VfsNodeRef> {
138        ax_err!(Unsupported)
139    }
140
141    /// Create a new node with the given `path` in the directory
142    ///
143    /// Return [`Ok(())`](Ok) if it already exists.
144    fn create(&self, _path: &str, _ty: VfsNodeType) -> VfsResult {
145        ax_err!(Unsupported)
146    }
147
148    /// Remove the node with the given `path` in the directory.
149    fn remove(&self, _path: &str) -> VfsResult {
150        ax_err!(Unsupported)
151    }
152
153    /// Read directory entries into `dirents`, starting from `start_idx`.
154    fn read_dir(&self, _start_idx: usize, _dirents: &mut [VfsDirEntry]) -> VfsResult<usize> {
155        ax_err!(Unsupported)
156    }
157
158    /// Renames or moves existing file or directory.
159    fn rename(&self, _src_path: &str, _dst_path: &str) -> VfsResult {
160        ax_err!(Unsupported)
161    }
162
163    /// Convert `&self` to [`&dyn Any`][1] that can use
164    /// [`Any::downcast_ref`][2].
165    ///
166    /// [1]: core::any::Any
167    /// [2]: core::any::Any#method.downcast_ref
168    fn as_any(&self) -> &dyn core::any::Any {
169        unimplemented!()
170    }
171}
172
173#[doc(hidden)]
174pub mod __priv {
175    pub use alloc::sync::Arc;
176    pub use axerrno::ax_err;
177}