kernel/fs/params.rs
1//! Filesystem Parameter System
2//!
3//! This module provides a type-safe parameter system for filesystem creation,
4//! replacing the legacy BTreeMap<String, String> approach with structured
5//! configuration types that provide compile-time validation and better ergonomics.
6//!
7//! # Overview
8//!
9//! The parameter system enables:
10//! - **Type Safety**: Compile-time validation of filesystem parameters
11//! - **Backward Compatibility**: Conversion to/from string maps for legacy code
12//! - **Extensibility**: Easy addition of new parameter types for different filesystems
13//! - **Dynamic Dispatch**: Support for future dynamic filesystem module loading
14//!
15//! # Architecture
16//!
17//! All filesystem parameter types implement the `FileSystemParams` trait, which
18//! provides standardized interfaces for:
19//! - String map conversion for backward compatibility
20//! - Dynamic type identification for runtime dispatch
21//! - Structured access to typed configuration data
22//!
23//! # Usage
24//!
25//! ```rust
26//! use crate::fs::params::{TmpFSParams, BasicFSParams};
27//!
28//! // Create TmpFS with 1MB memory limit
29//! let tmpfs_params = TmpFSParams::with_memory_limit(1048576);
30//! let fs_id = vfs_manager.create_and_register_fs_with_params("tmpfs", &tmpfs_params)?;
31//!
32//! // Create basic filesystem
33//! let basic_params = BasicFSParams::with_block_size(4096);
34//! let fs_id = vfs_manager.create_and_register_fs_with_params("ext4", &basic_params)?;
35//! ```
36
37use alloc::collections::BTreeMap;
38use alloc::format;
39use alloc::string::{String, ToString};
40use core::any::Any;
41
42/// File open flags
43#[derive(Debug, Clone, Copy, PartialEq)]
44pub struct OpenFlags {
45 /// Read access
46 pub read: bool,
47 /// Write access
48 pub write: bool,
49 /// Create file if it doesn't exist
50 pub create: bool,
51 /// Truncate file to zero length
52 pub truncate: bool,
53 /// Append to end of file
54 pub append: bool,
55}
56
57impl Default for OpenFlags {
58 fn default() -> Self {
59 Self {
60 read: true,
61 write: false,
62 create: false,
63 truncate: false,
64 append: false,
65 }
66 }
67}
68
69impl OpenFlags {
70 pub fn read_only() -> Self {
71 Self {
72 read: true,
73 write: false,
74 create: false,
75 truncate: false,
76 append: false,
77 }
78 }
79
80 pub fn read_write() -> Self {
81 Self {
82 read: true,
83 write: true,
84 create: false,
85 truncate: false,
86 append: false,
87 }
88 }
89}
90
91/// Core trait for filesystem parameter types
92///
93/// This trait enables type-safe filesystem configuration while maintaining
94/// backward compatibility with string-based parameter systems. All filesystem
95/// parameter structures must implement this trait to be usable with the
96/// VfsManager's structured parameter creation methods.
97///
98/// # Dynamic Dispatch Support
99///
100/// The trait includes `as_any()` to enable dynamic downcasting, which supports
101/// future dynamic filesystem module loading scenarios where parameter types
102/// may not be known at compile time.
103pub trait FileSystemParams {
104 /// Convert parameters to string map for backward compatibility
105 ///
106 /// This method serializes the structured parameters into a key-value
107 /// string map that can be consumed by legacy filesystem drivers that
108 /// haven't been updated to use structured parameters.
109 ///
110 /// # Returns
111 ///
112 /// BTreeMap containing string representations of all parameters
113 fn to_string_map(&self) -> BTreeMap<String, String>;
114
115 /// Create parameters from string map for backward compatibility
116 ///
117 /// This method deserializes parameters from a string map, enabling
118 /// legacy code to continue working while gradually migrating to
119 /// structured parameter usage.
120 ///
121 /// # Arguments
122 ///
123 /// * `map` - String map containing parameter key-value pairs
124 ///
125 /// # Returns
126 ///
127 /// * `Ok(Self)` - Successfully parsed parameters
128 /// * `Err(String)` - Parse error with description
129 fn from_string_map(map: &BTreeMap<String, String>) -> Result<Self, String>
130 where
131 Self: Sized;
132
133 /// Enable dynamic downcasting for runtime type identification
134 ///
135 /// This method supports dynamic dispatch scenarios where the exact
136 /// parameter type is not known at compile time, such as when loading
137 /// filesystem modules dynamically.
138 ///
139 /// # Returns
140 ///
141 /// Reference to self as Any trait object for downcasting
142 fn as_any(&self) -> &dyn Any;
143}
144
145/// TmpFS filesystem configuration parameters
146///
147/// Configuration structure for creating TmpFS (temporary filesystem) instances.
148/// TmpFS is a RAM-based filesystem that stores all data in memory, making it
149/// very fast but volatile (data is lost on reboot).
150///
151/// # Features
152///
153/// - **Memory Limiting**: Configurable maximum memory usage to prevent OOM
154/// - **Performance**: All operations occur in RAM for maximum speed
155/// - **Volatility**: Data exists only while mounted and system is running
156///
157/// # Memory Management
158///
159/// The memory limit prevents runaway processes from consuming all available
160/// RAM through filesystem operations. A limit of 0 means unlimited memory usage.
161#[derive(Debug, Clone, PartialEq)]
162pub struct TmpFSParams {
163 /// Maximum memory usage in bytes (0 = unlimited)
164 ///
165 /// This limit applies to the total size of all files and directories
166 /// stored in the TmpFS instance. When the limit is reached, write
167 /// operations will fail with ENOSPC (No space left on device).
168 pub memory_limit: usize,
169}
170
171impl Default for TmpFSParams {
172 /// Create TmpFS parameters with unlimited memory
173 ///
174 /// The default configuration allows unlimited memory usage, which
175 /// provides maximum flexibility but requires careful monitoring in
176 /// production environments.
177 fn default() -> Self {
178 Self {
179 memory_limit: 0, // Unlimited by default
180 }
181 }
182}
183
184impl TmpFSParams {
185 /// Create TmpFS parameters with specified memory limit
186 ///
187 /// # Arguments
188 ///
189 /// * `memory_limit` - Maximum memory usage in bytes (0 for unlimited)
190 ///
191 /// # Returns
192 ///
193 /// TmpFSParams instance with the specified memory limit
194 ///
195 /// # Example
196 ///
197 /// ```rust
198 /// // Create TmpFS with 10MB limit
199 /// let params = TmpFSParams::with_memory_limit(10 * 1024 * 1024);
200 /// ```
201 pub fn with_memory_limit(memory_limit: usize) -> Self {
202 Self { memory_limit }
203 }
204}
205
206impl FileSystemParams for TmpFSParams {
207 fn to_string_map(&self) -> BTreeMap<String, String> {
208 let mut map = BTreeMap::new();
209 map.insert("memory_limit".to_string(), self.memory_limit.to_string());
210 map
211 }
212
213 fn from_string_map(map: &BTreeMap<String, String>) -> Result<Self, String> {
214 let memory_limit = if let Some(limit_str) = map.get("memory_limit") {
215 limit_str
216 .parse::<usize>()
217 .map_err(|_| format!("Invalid memory_limit value: {}", limit_str))?
218 } else {
219 0 // Default to unlimited memory
220 };
221
222 Ok(Self { memory_limit })
223 }
224
225 fn as_any(&self) -> &dyn Any {
226 self
227 }
228}
229
230/// Parameters for CPIO filesystem creation
231#[derive(Debug, Clone, PartialEq)]
232pub struct CpioFSParams {}
233
234impl Default for CpioFSParams {
235 fn default() -> Self {
236 Self {}
237 }
238}
239
240impl CpioFSParams {
241 /// Create CPIO parameters
242 pub fn new() -> Self {
243 Self {}
244 }
245}
246
247impl FileSystemParams for CpioFSParams {
248 fn to_string_map(&self) -> BTreeMap<String, String> {
249 BTreeMap::new()
250 }
251
252 fn from_string_map(_map: &BTreeMap<String, String>) -> Result<Self, String> {
253 Ok(Self {})
254 }
255
256 fn as_any(&self) -> &dyn Any {
257 self
258 }
259}
260
261/// Generic parameters for basic filesystem creation
262#[derive(Debug, Clone, PartialEq)]
263pub struct BasicFSParams {
264 /// Block size (for block-based filesystems)
265 pub block_size: Option<usize>,
266 /// Read-only flag
267 pub read_only: bool,
268}
269
270impl Default for BasicFSParams {
271 fn default() -> Self {
272 Self {
273 block_size: None,
274 read_only: false,
275 }
276 }
277}
278
279impl BasicFSParams {
280 /// Create basic parameters with default values
281 pub fn new() -> Self {
282 Self {
283 block_size: None,
284 read_only: false,
285 }
286 }
287
288 /// Set block size
289 pub fn with_block_size(mut self, block_size: usize) -> Self {
290 self.block_size = Some(block_size);
291 self
292 }
293
294 /// Set read-only flag
295 pub fn with_read_only(mut self, read_only: bool) -> Self {
296 self.read_only = read_only;
297 self
298 }
299}
300
301impl FileSystemParams for BasicFSParams {
302 fn to_string_map(&self) -> BTreeMap<String, String> {
303 let mut map = BTreeMap::new();
304
305 if let Some(block_size) = self.block_size {
306 map.insert("block_size".to_string(), block_size.to_string());
307 }
308
309 map.insert("read_only".to_string(), self.read_only.to_string());
310 map
311 }
312
313 fn from_string_map(map: &BTreeMap<String, String>) -> Result<Self, String> {
314 let block_size = if let Some(size_str) = map.get("block_size") {
315 Some(
316 size_str
317 .parse::<usize>()
318 .map_err(|_| format!("Invalid block_size value: {}", size_str))?,
319 )
320 } else {
321 None
322 };
323
324 let read_only = if let Some(ro_str) = map.get("read_only") {
325 ro_str
326 .parse::<bool>()
327 .map_err(|_| format!("Invalid read_only value: {}", ro_str))?
328 } else {
329 false // Default to read-write
330 };
331
332 Ok(Self {
333 block_size,
334 read_only,
335 })
336 }
337
338 fn as_any(&self) -> &dyn Any {
339 self
340 }
341}