kernel/fs/vfs_v2/drivers/ext2/
driver.rs

1//! ext2 Filesystem Driver Implementation
2//!
3//! This module implements the FileSystemDriver trait for ext2,
4//! enabling the filesystem to be registered with the VFS manager
5//! and created from block devices.
6
7use alloc::sync::Arc;
8
9use crate::{
10    device::block::BlockDevice,
11    fs::{
12        FileSystemDriver, FileSystemError, FileSystemErrorKind, FileSystemType,
13        params::FileSystemParams,
14    },
15};
16
17use super::super::super::core::FileSystemOperations;
18use super::{Ext2FileSystem, Ext2Params};
19
20/// ext2 filesystem driver
21///
22/// This driver implements the FileSystemDriver trait and is responsible
23/// for creating ext2 filesystem instances from block devices.
24pub struct Ext2Driver;
25
26impl FileSystemDriver for Ext2Driver {
27    fn name(&self) -> &'static str {
28        "ext2"
29    }
30
31    fn filesystem_type(&self) -> FileSystemType {
32        FileSystemType::Block
33    }
34
35    fn create(&self) -> Result<Arc<dyn FileSystemOperations>, FileSystemError> {
36        // ext2 requires a block device, cannot create without one
37        Err(FileSystemError::new(
38            FileSystemErrorKind::NotSupported,
39            "ext2 filesystem requires a block device",
40        ))
41    }
42
43    fn create_from_block(
44        &self,
45        block_device: Arc<dyn BlockDevice>,
46        _block_size: usize,
47    ) -> Result<Arc<dyn FileSystemOperations>, FileSystemError> {
48        // Create ext2 filesystem from the block device
49        let fs = Ext2FileSystem::new(block_device)?;
50        Ok(fs as Arc<dyn FileSystemOperations>)
51    }
52
53    fn create_from_memory(
54        &self,
55        _memory_area: &crate::vm::vmem::MemoryArea,
56    ) -> Result<Arc<dyn FileSystemOperations>, FileSystemError> {
57        // ext2 is a block-based filesystem, not memory-based
58        Err(FileSystemError::new(
59            FileSystemErrorKind::NotSupported,
60            "ext2 filesystem does not support memory-based creation",
61        ))
62    }
63
64    fn create_from_option_string(
65        &self,
66        options: &str,
67    ) -> Result<Arc<dyn FileSystemOperations>, FileSystemError> {
68        // Parse options into Ext2Params
69        let mut params = Ext2Params::from_option_string(options)?;
70
71        // Create filesystem using params
72        let fs = params.create_filesystem()?;
73        Ok(fs as Arc<dyn FileSystemOperations>)
74    }
75
76    fn create_from_params(
77        &self,
78        params: &dyn FileSystemParams,
79    ) -> Result<Arc<dyn FileSystemOperations>, FileSystemError> {
80        // Downcast to Ext2Params
81        let ext2_params = params
82            .as_any()
83            .downcast_ref::<Ext2Params>()
84            .ok_or_else(|| {
85                FileSystemError::new(
86                    FileSystemErrorKind::InvalidData,
87                    "Invalid parameter type for ext2 filesystem",
88                )
89            })?;
90
91        // Clone params to make them mutable for device resolution
92        let mut params = ext2_params.clone();
93
94        // Create filesystem using params
95        let fs = params.create_filesystem()?;
96        Ok(fs as Arc<dyn FileSystemOperations>)
97    }
98}
99
100#[cfg(test)]
101mod tests {
102    use super::*;
103    use crate::device::block::mockblk::MockBlockDevice;
104
105    #[test_case]
106    fn test_ext2_driver_type() {
107        let driver = Ext2Driver;
108        assert_eq!(driver.name(), "ext2");
109        assert_eq!(driver.filesystem_type(), FileSystemType::Block);
110    }
111
112    #[test_case]
113    fn test_ext2_create_without_block_device_fails() {
114        let driver = Ext2Driver;
115        let result = driver.create();
116        assert!(result.is_err());
117
118        let result = driver.create_from_option_string("");
119        assert!(result.is_err());
120    }
121
122    #[test_case]
123    fn test_ext2_create_from_mock_block_device() {
124        let driver = Ext2Driver;
125
126        // Create a mock block device with a basic ext2 superblock
127        let mock_device = MockBlockDevice::new("mock_ext2", 512, 65536);
128
129        // Note: This test might fail due to the mock implementation not having
130        // a proper ext2 superblock, but it tests the interface
131        let result = driver.create_from_block(Arc::new(mock_device), 512);
132
133        match result {
134            Ok(_fs) => {
135                // Successfully created filesystem (unlikely with empty mock device)
136            }
137            Err(e) => {
138                // Expected to fail with mock device, but error should be about
139                // filesystem format, not interface issues
140                assert!(
141                    e.kind == FileSystemErrorKind::IoError
142                        || e.kind == FileSystemErrorKind::InvalidData
143                );
144            }
145        }
146    }
147}