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::string::{String, ToString};
38use alloc::collections::BTreeMap;
39use alloc::format;
40use core::any::Any;
41
42/// Core trait for filesystem parameter types
43///
44/// This trait enables type-safe filesystem configuration while maintaining
45/// backward compatibility with string-based parameter systems. All filesystem
46/// parameter structures must implement this trait to be usable with the
47/// VfsManager's structured parameter creation methods.
48///
49/// # Dynamic Dispatch Support
50///
51/// The trait includes `as_any()` to enable dynamic downcasting, which supports
52/// future dynamic filesystem module loading scenarios where parameter types
53/// may not be known at compile time.
54pub trait FileSystemParams {
55 /// Convert parameters to string map for backward compatibility
56 ///
57 /// This method serializes the structured parameters into a key-value
58 /// string map that can be consumed by legacy filesystem drivers that
59 /// haven't been updated to use structured parameters.
60 ///
61 /// # Returns
62 ///
63 /// BTreeMap containing string representations of all parameters
64 fn to_string_map(&self) -> BTreeMap<String, String>;
65
66 /// Create parameters from string map for backward compatibility
67 ///
68 /// This method deserializes parameters from a string map, enabling
69 /// legacy code to continue working while gradually migrating to
70 /// structured parameter usage.
71 ///
72 /// # Arguments
73 ///
74 /// * `map` - String map containing parameter key-value pairs
75 ///
76 /// # Returns
77 ///
78 /// * `Ok(Self)` - Successfully parsed parameters
79 /// * `Err(String)` - Parse error with description
80 fn from_string_map(map: &BTreeMap<String, String>) -> Result<Self, String>
81 where
82 Self: Sized;
83
84 /// Enable dynamic downcasting for runtime type identification
85 ///
86 /// This method supports dynamic dispatch scenarios where the exact
87 /// parameter type is not known at compile time, such as when loading
88 /// filesystem modules dynamically.
89 ///
90 /// # Returns
91 ///
92 /// Reference to self as Any trait object for downcasting
93 fn as_any(&self) -> &dyn Any;
94}
95
96/// TmpFS filesystem configuration parameters
97///
98/// Configuration structure for creating TmpFS (temporary filesystem) instances.
99/// TmpFS is a RAM-based filesystem that stores all data in memory, making it
100/// very fast but volatile (data is lost on reboot).
101///
102/// # Features
103///
104/// - **Memory Limiting**: Configurable maximum memory usage to prevent OOM
105/// - **Performance**: All operations occur in RAM for maximum speed
106/// - **Volatility**: Data exists only while mounted and system is running
107///
108/// # Memory Management
109///
110/// The memory limit prevents runaway processes from consuming all available
111/// RAM through filesystem operations. A limit of 0 means unlimited memory usage.
112#[derive(Debug, Clone, PartialEq)]
113pub struct TmpFSParams {
114 /// Maximum memory usage in bytes (0 = unlimited)
115 ///
116 /// This limit applies to the total size of all files and directories
117 /// stored in the TmpFS instance. When the limit is reached, write
118 /// operations will fail with ENOSPC (No space left on device).
119 pub memory_limit: usize,
120}
121
122impl Default for TmpFSParams {
123 /// Create TmpFS parameters with unlimited memory
124 ///
125 /// The default configuration allows unlimited memory usage, which
126 /// provides maximum flexibility but requires careful monitoring in
127 /// production environments.
128 fn default() -> Self {
129 Self {
130 memory_limit: 0, // Unlimited by default
131 }
132 }
133}
134
135impl TmpFSParams {
136 /// Create TmpFS parameters with specified memory limit
137 ///
138 /// # Arguments
139 ///
140 /// * `memory_limit` - Maximum memory usage in bytes (0 for unlimited)
141 ///
142 /// # Returns
143 ///
144 /// TmpFSParams instance with the specified memory limit
145 ///
146 /// # Example
147 ///
148 /// ```rust
149 /// // Create TmpFS with 10MB limit
150 /// let params = TmpFSParams::with_memory_limit(10 * 1024 * 1024);
151 /// ```
152 pub fn with_memory_limit(memory_limit: usize) -> Self {
153 Self {
154 memory_limit,
155 }
156 }
157}
158
159impl FileSystemParams for TmpFSParams {
160 fn to_string_map(&self) -> BTreeMap<String, String> {
161 let mut map = BTreeMap::new();
162 map.insert("memory_limit".to_string(), self.memory_limit.to_string());
163 map
164 }
165
166 fn from_string_map(map: &BTreeMap<String, String>) -> Result<Self, String> {
167 let memory_limit = if let Some(limit_str) = map.get("memory_limit") {
168 limit_str.parse::<usize>()
169 .map_err(|_| format!("Invalid memory_limit value: {}", limit_str))?
170 } else {
171 0 // Default to unlimited memory
172 };
173
174 Ok(Self { memory_limit })
175 }
176
177 fn as_any(&self) -> &dyn Any {
178 self
179 }
180}
181
182/// Parameters for CPIO filesystem creation
183#[derive(Debug, Clone, PartialEq)]
184pub struct CpioFSParams {
185}
186
187impl Default for CpioFSParams {
188 fn default() -> Self {
189 Self {
190 }
191 }
192}
193
194impl CpioFSParams {
195 /// Create CPIO parameters
196 pub fn new() -> Self {
197 Self { }
198 }
199}
200
201impl FileSystemParams for CpioFSParams {
202 fn to_string_map(&self) -> BTreeMap<String, String> {
203 BTreeMap::new()
204 }
205
206 fn from_string_map(_map: &BTreeMap<String, String>) -> Result<Self, String> {
207 Ok(Self { })
208 }
209
210 fn as_any(&self) -> &dyn Any {
211 self
212 }
213}
214
215/// Generic parameters for basic filesystem creation
216#[derive(Debug, Clone, PartialEq)]
217pub struct BasicFSParams {
218 /// Block size (for block-based filesystems)
219 pub block_size: Option<usize>,
220 /// Read-only flag
221 pub read_only: bool,
222}
223
224impl Default for BasicFSParams {
225 fn default() -> Self {
226 Self {
227 block_size: None,
228 read_only: false,
229 }
230 }
231}
232
233impl BasicFSParams {
234 /// Create basic parameters with default values
235 pub fn new() -> Self {
236 Self {
237 block_size: None,
238 read_only: false,
239 }
240 }
241
242 /// Set block size
243 pub fn with_block_size(mut self, block_size: usize) -> Self {
244 self.block_size = Some(block_size);
245 self
246 }
247
248 /// Set read-only flag
249 pub fn with_read_only(mut self, read_only: bool) -> Self {
250 self.read_only = read_only;
251 self
252 }
253}
254
255impl FileSystemParams for BasicFSParams {
256 fn to_string_map(&self) -> BTreeMap<String, String> {
257 let mut map = BTreeMap::new();
258
259 if let Some(block_size) = self.block_size {
260 map.insert("block_size".to_string(), block_size.to_string());
261 }
262
263 map.insert("read_only".to_string(), self.read_only.to_string());
264 map
265 }
266
267 fn from_string_map(map: &BTreeMap<String, String>) -> Result<Self, String> {
268 let block_size = if let Some(size_str) = map.get("block_size") {
269 Some(size_str.parse::<usize>()
270 .map_err(|_| format!("Invalid block_size value: {}", size_str))?)
271 } else {
272 None
273 };
274
275 let read_only = if let Some(ro_str) = map.get("read_only") {
276 ro_str.parse::<bool>()
277 .map_err(|_| format!("Invalid read_only value: {}", ro_str))?
278 } else {
279 false // Default to read-write
280 };
281
282 Ok(Self { block_size, read_only })
283 }
284
285 fn as_any(&self) -> &dyn Any {
286 self
287 }
288}