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}