kernel/fs/
mod.rs

1//! Virtual File System (VFS) module.
2//!
3//! This module provides a flexible Virtual File System implementation that supports
4//! per-task isolated filesystems, containerization, and bind mount functionality.
5//!
6//! # Architecture Overview
7//!
8//! The VFS architecture has evolved to support containerization, process isolation,
9//! and advanced mount operations including bind mounts:
10//!
11//! ## VfsManager Distribution
12//!
13//! - **Per-Task VfsManager**: Each task can have its own isolated `VfsManager` instance
14//!   stored as `Option<Arc<VfsManager>>` in the task structure
15//! - **Shared Filesystems**: Multiple VfsManager instances can share underlying filesystem
16//!   objects while maintaining independent mount points
17//! - **Bind Mounts**: Support for mounting directories from one location to another,
18//!   including cross-VFS bind mounting for container orchestration
19//!
20//! ## Key Components
21//!
22//! - `VfsManager`: Main VFS management structure supporting both isolation and sharing
23//! - `FileSystemDriverManager`: Global singleton for filesystem driver registration
24//! - `VirtualFileSystem`: Trait combining filesystem and file operation interfaces
25//! - `MountPoint`: Associates filesystem instances with mount paths
26//! - `MountTree`: Hierarchical mount tree structure supporting bind mounts
27//!
28//! ## Bind Mount Functionality
29//!
30//! The VFS provides comprehensive bind mount support for flexible directory mapping:
31//!
32//! ### Basic Bind Mounts
33//! ```rust
34//! let mut vfs = VfsManager::new();
35//! // Mount a directory at another location
36//! vfs.bind_mount("/source/dir", "/target/dir", false)?;
37//! ```
38//!
39//! ### Read-Only Bind Mounts
40//! ```rust
41//! // Create read-only bind mount for security
42//! vfs.bind_mount("/source/dir", "/readonly/dir", true)?;
43//! ```
44//!
45//! ### Cross-VFS Bind Mounts
46//! ```rust
47//! // Share directories between isolated VFS instances
48//! let host_vfs = Arc::new(vfs_manager);
49//! container_vfs.bind_mount_from(&host_vfs, "/host/data", "/container/data", false)?;
50//! ```
51//!
52
53//! ### Thread-Safe Access
54//! Bind mount operations are thread-safe and can be called from system call context:
55//! ```rust
56//! // Use shared reference method for system calls
57//! vfs_arc.bind_mount_shared_ref("/source", "/target", false)?;
58//! ```
59//!
60//! ## Usage Patterns
61//!
62//! ### Container Isolation with Bind Mounts
63//! ```rust
64//! // Create isolated VfsManager for container
65//! let mut container_vfs = VfsManager::new();
66//! container_vfs.mount(fs_id, "/");
67//! 
68//! // Bind mount host resources into container
69//! let host_vfs = Arc::new(host_vfs_manager);
70//! container_vfs.bind_mount_from(&host_vfs, "/host/shared", "/shared", true)?;
71//! 
72//! // Assign to task
73//! task.vfs = Some(Arc::new(container_vfs));
74//! ```
75//!
76//! ### Shared Filesystem Access
77//!
78//! The VFS supports two distinct patterns for sharing filesystem resources:
79//!
80//! #### VFS Sharing via Arc
81//! ```rust
82//! // Share entire VfsManager instance including mount points
83//! let shared_vfs = Arc::new(original_vfs);
84//! let task_vfs = Arc::clone(&shared_vfs);
85//! 
86//! // All mount operations affect the shared mount tree
87//! shared_vfs.mount(tmpfs_id, "/tmp")?;  // Visible to all references
88//! 
89//! // Useful for:
90//! // - Fork-like behavior where child inherits parent's full filesystem view
91//! // - Thread-like sharing where all threads see the same mount points
92//! // - System-wide mount operations
93//! ```
94//!
95//! The design enables flexible deployment scenarios from simple shared filesystems
96//! to complete filesystem isolation with selective resource sharing for containerized
97//! applications through bind mounts.
98
99pub mod drivers;
100pub mod syscall;
101pub mod helper;
102pub mod tmpfs;
103pub mod params;
104pub mod mount_tree;
105
106use alloc::{boxed::Box, collections::BTreeMap, format, string::{String, ToString}, sync::Arc, vec::Vec};
107use alloc::vec;
108use core::fmt;
109use crate::{device::{block::{request::{BlockIORequest, BlockIORequestType}, BlockDevice}, DeviceType}, task::Task, vm::vmem::MemoryArea};
110
111use spin::{Mutex, RwLock};
112use mount_tree::{MountTree, MountPoint as TreeMountPoint, MountType, MountOptions};
113
114extern crate alloc;
115
116pub const MAX_PATH_LENGTH: usize = 1024;
117
118#[derive(Debug, Clone, Copy, PartialEq)]
119pub enum FileSystemErrorKind {
120    NotFound,
121    NoSpace,
122    PermissionDenied,
123    IoError,
124    InvalidData,
125    InvalidPath,
126    AlreadyExists,
127    NotADirectory,
128    NotAFile,
129    ReadOnly,
130    DeviceError,
131    NotSupported,
132    BrokenFileSystem,
133    Busy,
134}
135
136pub struct FileSystemError {
137    pub kind: FileSystemErrorKind,
138    pub message: String,
139}
140
141impl fmt::Debug for FileSystemError {
142    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143        write!(f, "FileSystemError {{ kind: {:?}, message: {} }}", self.kind, self.message)
144    }
145}
146
147/// Result type for file system operations
148pub type Result<T> = core::result::Result<T, FileSystemError>;
149
150/// Information about device files in the filesystem
151/// 
152/// Scarlet uses a simplified device identification system based on unique device IDs
153/// rather than the traditional Unix major/minor number pairs. This provides:
154/// 
155/// - **Simplified Management**: Single ID instead of major/minor pair reduces complexity
156/// - **Unified Namespace**: All devices share a common ID space regardless of type
157/// - **Dynamic Allocation**: Device IDs can be dynamically assigned without conflicts
158/// - **Type Safety**: Device type is explicitly specified alongside the ID
159/// 
160/// # Architecture
161/// 
162/// Each device in Scarlet is uniquely identified by:
163/// - `device_id`: A unique identifier within the system's device namespace
164/// - `device_type`: Explicit type classification (Character, Block, etc.)
165/// 
166/// This differs from traditional Unix systems where:
167/// - Major numbers identify device drivers
168/// - Minor numbers identify specific devices within a driver
169/// 
170/// # Examples
171/// 
172/// ```rust
173/// // Character device for terminal
174/// let tty_device = DeviceFileInfo {
175///     device_id: 1,
176///     device_type: DeviceType::Char,
177/// };
178/// 
179/// // Block device for storage
180/// let disk_device = DeviceFileInfo {
181///     device_id: 100,
182///     device_type: DeviceType::Block,
183/// };
184/// ```
185#[derive(Debug, Clone, Copy, PartialEq)]
186pub struct DeviceFileInfo {
187    pub device_id: usize,
188    pub device_type: DeviceType,
189}
190
191#[derive(Debug, Clone, Copy, PartialEq)]
192pub enum FileType {
193    RegularFile,
194    Directory,
195    CharDevice(DeviceFileInfo),
196    BlockDevice(DeviceFileInfo),
197    Pipe,
198    SymbolicLink,
199    Socket,
200    Unknown,
201}
202
203#[derive(Debug, Clone, Copy)]
204pub struct FilePermission {
205    pub read: bool,
206    pub write: bool,
207    pub execute: bool,
208}
209
210#[derive(Debug, Clone)]
211pub struct FileMetadata {
212    pub file_type: FileType,
213    pub size: usize,
214    pub permissions: FilePermission,
215    pub created_time: u64,
216    pub modified_time: u64,
217    pub accessed_time: u64,
218}
219
220#[derive(Clone)]
221pub struct File {
222    // pub path: String,
223    handle: Arc<dyn FileHandle>,
224}
225impl File {
226    /// Open a file using a specific VFS manager
227    /// 
228    /// # Arguments
229    /// 
230    /// * `path` - The path to the file
231    /// * `manager` - The VFS manager to use
232    /// 
233    /// # Returns
234    /// 
235    /// * `Result<File>` - The opened file object
236    /// 
237    pub fn open_with_manager(path: String, manager: &VfsManager) -> Result<Self> {
238        manager.open(&path, 0)
239    }
240
241    /// Read data from the file
242    /// 
243    /// # Arguments
244    /// 
245    /// * `buffer` - The buffer to read data into
246    /// 
247    /// # Returns
248    /// 
249    /// * `Result<usize>` - The number of bytes read
250    /// 
251    pub fn read(&mut self, buffer: &mut [u8]) -> Result<usize> {
252        self.handle.read(buffer)
253    }
254    
255    /// Write data to the file
256    /// 
257    /// # Arguments
258    /// 
259    /// * `buffer` - The buffer containing data to write
260    /// 
261    /// # Returns
262    /// 
263    /// * `Result<usize>` - The number of bytes written
264    /// 
265    pub fn write(&mut self, buffer: &[u8]) -> Result<usize> { 
266        self.handle.write(buffer)
267    }
268    
269    /// Change the position within the file
270    pub fn seek(&mut self, whence: SeekFrom) -> Result<u64> {
271        self.handle.seek(whence)
272    }
273    
274    /// Get the metadata of the file
275    pub fn metadata(&self) -> Result<FileMetadata> {
276        self.handle.metadata()
277    }
278    
279    /// Get the size of the file
280    pub fn size(&self) -> Result<usize> {
281        let metadata = self.metadata()?;
282        Ok(metadata.size)
283    }
284    
285    /// Read the entire contents of the file
286    pub fn read_all(&mut self) -> Result<Vec<u8>> {
287        let size = self.size()?;
288        let mut buffer = vec![0u8; size];
289        
290        self.seek(SeekFrom::Start(0))?;
291        let read_bytes = self.read(&mut buffer)?;
292        
293        if read_bytes != size {
294            buffer.truncate(read_bytes);
295        }
296        
297        Ok(buffer)
298    }
299}
300
301impl Drop for File {
302    fn drop(&mut self) {
303        self.handle.release().unwrap();
304    }
305}
306/// Structure representing a directory entry
307#[derive(Debug, Clone)]
308pub struct DirectoryEntry {
309    pub name: String,
310    pub file_type: FileType,
311    pub size: usize,
312    pub metadata: Option<FileMetadata>,
313}
314
315/// Structure representing a directory
316pub struct Directory<'a> {
317    pub path: String,
318    #[allow(dead_code)]
319    manager_ref: ManagerRef<'a>,
320}
321
322impl<'a> Directory<'a> {
323    pub fn open(path: String) -> Self {
324        Self {
325            path,
326            manager_ref: ManagerRef::Global,
327        }
328    }
329    
330    pub fn open_with_manager(path: String, manager: &'a mut VfsManager) -> Self {
331        Self {
332            path,
333            manager_ref: ManagerRef::Local(manager),
334        }
335    }
336}
337
338pub enum SeekFrom {
339    Start(u64),
340    Current(i64),
341    End(i64),
342}
343
344/// Trait for file handlers
345pub trait FileHandle: Send + Sync {
346    /// Read from the file
347    fn read(&self, buffer: &mut [u8]) -> Result<usize>;
348    
349    /// Write to the file
350    fn write(&self, buffer: &[u8]) -> Result<usize>;
351    
352    /// Move the position within the file
353    fn seek(&self, whence: SeekFrom) -> Result<u64>;
354    
355    /// Release the file resource
356    fn release(&self) -> Result<()>;
357    
358    /// Get the metadata
359    fn metadata(&self) -> Result<FileMetadata>;
360}
361
362/// Trait defining basic file system operations
363pub trait FileSystem: Send + Sync {
364    /// Mount operation
365    fn mount(&mut self, mount_point: &str) -> Result<()>;
366
367    /// Unmount operation
368    fn unmount(&mut self) -> Result<()>;
369    
370    /// Get the name of the file system
371    fn name(&self) -> &str;
372}
373
374/// Trait defining file operations
375pub trait FileOperations: Send + Sync {
376    /// Open a file
377    fn open(&self, path: &str, flags: u32) -> Result<Arc<dyn FileHandle>>;
378    
379    /// Read directory entries
380    fn read_dir(&self, path: &str) -> Result<Vec<DirectoryEntry>>;
381    
382    /// Create a file with the specified type.
383    /// 
384    /// # Arguments
385    /// 
386    /// * `path` - The path to the file to create.
387    /// * `file_type` - The type of file to create. This can be a regular file, a device file, or other supported types.
388    /// 
389    /// # Behavior
390    /// 
391    /// - **Regular Files**: These are standard files used for storing data. They are created in the filesystem and can be read from or written to using standard file operations.
392    /// - **Device Files**: These represent hardware devices and are typically used for interacting with device drivers. Creating a device file may involve additional steps, such as associating the file with a specific device driver or hardware resource.
393    /// 
394    /// # Side Effects
395    /// 
396    /// - Creating a device file may require elevated permissions or specific system configurations.
397    /// - If a file already exists at the specified path, the function will return an error of type `FileSystemErrorKind::AlreadyExists`.
398    /// 
399    /// # Returns
400    /// 
401    /// * `Result<()>` - `Ok` if the file was created successfully, or an error if the operation failed. Errors may include `PermissionDenied`, `InvalidPath`, or `DeviceError` for device files.
402    fn create_file(&self, path: &str, file_type: FileType) -> Result<()>;
403    
404    /// Create a directory
405    fn create_dir(&self, path: &str) -> Result<()>;
406    
407    /// Remove a file/directory
408    fn remove(&self, path: &str) -> Result<()>;
409    
410    /// Get the metadata
411    fn metadata(&self, path: &str) -> Result<FileMetadata>;
412
413    /// Get the root directory of the file system
414    fn root_dir(&self) -> Result<Directory>;
415}
416
417/// Trait combining the complete VFS interface
418pub trait VirtualFileSystem: FileSystem + FileOperations {}
419
420// Automatically implement VirtualFileSystem if both FileSystem and FileOperations are implemented
421impl<T: FileSystem + FileOperations> VirtualFileSystem for T {}
422
423/// Enum defining the type of file system
424#[derive(Debug, Clone, Copy, PartialEq)]
425pub enum FileSystemType {
426    /// File system that operates on block devices (disk-based)
427    Block,
428    /// File system that operates on memory regions (RAM-based)
429    Memory,
430    /// File system that can operate on both block devices and memory regions
431    Hybrid,
432    /// Special or virtual file systems (e.g., procfs, sysfs)
433    Virtual,
434    /// Device file system (e.g., /dev)
435    Device,
436}
437
438/// Trait for file system drivers
439/// 
440/// This trait is used to create file systems from block devices or memory areas.
441/// It is not intended to be used directly by the VFS manager.
442/// Instead, the VFS manager will use the appropriate creation method based on the source.
443pub trait FileSystemDriver: Send + Sync {
444    /// Get the name of the file system driver
445    fn name(&self) -> &'static str;
446    
447    /// Get the type of the file system
448    fn filesystem_type(&self) -> FileSystemType;
449    
450    /// Create a file system from a block device
451    /// 
452    /// When implementing this method, ensure that the file system driver can handle block device-based creation.
453    /// If the driver does not support this, return an appropriate error.
454    /// 
455    /// # Arguments
456    /// 
457    /// * `_block_device` - The block device to use for creating the file system
458    /// * `_block_size` - The block size of the device
459    /// 
460    fn create_from_block(&self, _block_device: Box<dyn BlockDevice>, _block_size: usize) -> Result<Box<dyn VirtualFileSystem>> {
461        if self.filesystem_type() == FileSystemType::Memory || self.filesystem_type() == FileSystemType::Virtual {
462            return Err(FileSystemError {
463                kind: FileSystemErrorKind::NotSupported,
464                message: "This file system driver does not support block device-based creation".to_string(),
465            });
466        }
467        
468        Err(FileSystemError {
469            kind: FileSystemErrorKind::NotSupported,
470            message: "create_from_block() not implemented for this file system driver".to_string(),
471        })
472    }
473    
474    /// Create a file system from a memory area
475    /// 
476    /// When implementing this method, ensure that the file system driver can handle memory-based creation.
477    /// If the driver does not support this, return an appropriate error.
478    /// 
479    /// # Notes
480    /// 
481    /// File system drivers must validate the provided MemoryArea to ensure it is valid.
482    /// If the MemoryArea is invalid, the driver should return an appropriate error.
483    /// 
484    /// # Arguments
485    /// 
486    /// * `_memory_area` - The memory area to use for creating the file system
487    /// 
488    /// # Returns
489    /// 
490    /// * `Result<Box<dyn VirtualFileSystem>>` - The created file system
491    /// 
492    fn create_from_memory(&self, _memory_area: &crate::vm::vmem::MemoryArea) -> Result<Box<dyn VirtualFileSystem>> {
493        if self.filesystem_type() == FileSystemType::Block {
494            return Err(FileSystemError {
495                kind: FileSystemErrorKind::NotSupported,
496                message: "This file system driver does not support memory-based creation".to_string(),
497            });
498        }
499        
500        Err(FileSystemError {
501            kind: FileSystemErrorKind::NotSupported,
502            message: "create_from_memory() not implemented for this file system driver".to_string(),
503        })
504    }
505
506    fn create(&self) -> Result<Box<dyn VirtualFileSystem>> {
507        // Default implementation that can be overridden by specific drivers
508        // This is a convenience method for drivers that do not need to handle block or memory creation
509        Err(FileSystemError {
510            kind: FileSystemErrorKind::NotSupported,
511            message: "create() not implemented for this file system driver".to_string(),
512        })
513    }
514
515    /// Create a file system with structured parameters
516    /// 
517    /// This method creates file systems using type-safe structured parameters
518    /// that implement the FileSystemParams trait. This approach replaces the
519    /// old BTreeMap<String, String> approach with better type safety.
520    /// 
521    /// # Arguments
522    /// 
523    /// * `params` - Structured parameter implementing FileSystemParams
524    /// 
525    /// # Returns
526    /// 
527    /// * `Result<Box<dyn VirtualFileSystem>>` - The created file system
528    /// 
529    /// # Note
530    /// 
531    /// This method uses dynamic dispatch for parameter handling to support
532    /// future dynamic filesystem module loading while maintaining type safety.
533    /// 
534    fn create_with_params(&self, params: &dyn crate::fs::params::FileSystemParams) -> Result<Box<dyn VirtualFileSystem>> {
535        // Default implementation falls back to create()
536        let _ = params; // Suppress unused parameter warning
537        self.create()
538    }
539}
540
541// Singleton for global access to the FileSystemDriverManager
542static mut FS_DRIVER_MANAGER: Option<FileSystemDriverManager> = None;
543
544/// Global filesystem driver manager singleton
545/// 
546/// Provides global access to the FileSystemDriverManager instance.
547/// This function ensures thread-safe initialization of the singleton
548/// and returns a mutable reference for driver registration and filesystem creation.
549/// 
550/// # Returns
551/// 
552/// Mutable reference to the global FileSystemDriverManager instance
553/// 
554/// # Thread Safety
555/// 
556/// This function is marked as unsafe due to static mutable access, but
557/// the returned manager uses internal synchronization for thread safety.
558#[allow(static_mut_refs)]
559pub fn get_fs_driver_manager() -> &'static mut FileSystemDriverManager {
560    unsafe {
561        if FS_DRIVER_MANAGER.is_none() {
562            FS_DRIVER_MANAGER = Some(FileSystemDriverManager::new());
563        }
564        FS_DRIVER_MANAGER.as_mut().unwrap()
565    }
566}
567
568/// Global filesystem driver manager singleton
569/// 
570/// Provides global access to the FileSystemDriverManager instance.
571/// This function ensures thread-safe initialization of the singleton
572/// and returns a mutable reference for driver registration and filesystem creation.
573/// 
574/// # Returns
575/// 
576/// Mutable reference to the global FileSystemDriverManager instance
577/// 
578/// # Thread Safety
579/// 
580/// This function is marked as unsafe due to static mutable access, but
581/// Filesystem driver manager for centralized driver registration and management
582/// 
583/// The FileSystemDriverManager provides a centralized system for managing filesystem
584/// drivers in the kernel. It separates driver management responsibilities from individual
585/// VfsManager instances, enabling shared driver access across multiple VFS namespaces.
586/// 
587/// # Features
588/// 
589/// - **Driver Registration**: Register filesystem drivers for system-wide use
590/// - **Type-Safe Creation**: Create filesystems with structured parameter validation
591/// - **Multi-Source Support**: Support for block device, memory, and virtual filesystems
592/// - **Thread Safety**: All operations are thread-safe using RwLock protection
593/// - **Future Extensibility**: Designed for dynamic filesystem module loading
594/// 
595/// # Architecture
596/// 
597/// The manager maintains a registry of drivers identified by name, with each driver
598/// implementing the FileSystemDriver trait. Drivers specify their supported source
599/// types (block, memory, virtual) and provide creation methods for each type.
600/// 
601/// # Usage
602/// 
603/// ```rust
604/// // Register a filesystem driver
605/// let manager = get_fs_driver_manager();
606/// manager.register_driver(Box::new(MyFSDriver));
607/// 
608/// // Create filesystem from block device
609/// let device = get_block_device();
610/// let fs = manager.create_from_block("myfs", device, 512)?;
611/// 
612/// // Create filesystem with structured parameters
613/// let params = MyFSParams::new();
614/// let fs = manager.create_with_params("myfs", &params)?;
615/// ```
616pub struct FileSystemDriverManager {
617    /// Registered file system drivers indexed by name
618    drivers: RwLock<BTreeMap<String, Box<dyn FileSystemDriver>>>,
619}
620
621impl FileSystemDriverManager {
622    /// Create a new filesystem driver manager
623    /// 
624    /// Initializes an empty driver manager with no registered drivers.
625    /// Drivers must be registered using register_driver() before they
626    /// can be used to create filesystems.
627    /// 
628    /// # Returns
629    /// 
630    /// A new FileSystemDriverManager instance
631    pub fn new() -> Self {
632        Self {
633            drivers: RwLock::new(BTreeMap::new()),
634        }
635    }
636
637    /// Register a filesystem driver
638    /// 
639    /// Adds a new filesystem driver to the manager's registry. The driver
640    /// will be indexed by its name() method return value. If a driver with
641    /// the same name already exists, it will be replaced.
642    /// 
643    /// # Arguments
644    /// 
645    /// * `driver` - The filesystem driver to register, implementing FileSystemDriver trait
646    /// 
647    /// # Example
648    /// 
649    /// ```rust
650    /// let manager = get_fs_driver_manager();
651    /// manager.register_driver(Box::new(MyFileSystemDriver));
652    /// ```
653    pub fn register_driver(&mut self, driver: Box<dyn FileSystemDriver>) {
654        self.drivers.write().insert(driver.name().to_string(), driver);
655    }
656
657    /// Get a list of registered driver names
658    /// 
659    /// Returns the names of all currently registered filesystem drivers.
660    /// This is useful for debugging and system introspection.
661    /// 
662    /// # Returns
663    /// 
664    /// Vector of driver names in alphabetical order
665    pub fn list_drivers(&self) -> Vec<String> {
666        self.drivers.read().keys().cloned().collect()
667    }
668
669    /// Check if a driver with the specified name is registered
670    /// 
671    /// Performs a quick lookup to determine if a named driver exists
672    /// in the registry without attempting to use it.
673    /// 
674    /// # Arguments
675    /// 
676    /// * `driver_name` - The name of the driver to check for
677    /// 
678    /// # Returns
679    /// 
680    /// `true` if the driver is registered, `false` otherwise
681    pub fn has_driver(&self, driver_name: &str) -> bool {
682        self.drivers.read().contains_key(driver_name)
683    }
684
685    /// Create a filesystem from a block device
686    /// 
687    /// Creates a new filesystem instance using the specified driver and block device.
688    /// The driver must support block device-based filesystem creation. This method
689    /// validates that the driver supports block devices before attempting creation.
690    /// 
691    /// # Arguments
692    /// 
693    /// * `driver_name` - The name of the registered driver to use
694    /// * `block_device` - The block device that will store the filesystem data
695    /// * `block_size` - The block size for I/O operations (typically 512, 1024, or 4096 bytes)
696    /// 
697    /// # Returns
698    /// 
699    /// * `Ok(Box<dyn VirtualFileSystem>)` - Successfully created filesystem instance
700    /// * `Err(FileSystemError)` - If driver not found, doesn't support block devices, or creation fails
701    /// 
702    /// # Errors
703    /// 
704    /// - `NotFound` - Driver with the specified name is not registered
705    /// - `NotSupported` - Driver doesn't support block device-based filesystems
706    /// - Driver-specific errors during filesystem creation
707    /// 
708    /// # Example
709    /// 
710    /// ```rust
711    /// let device = get_block_device();
712    /// let fs = manager.create_from_block("ext4", device, 4096)?;
713    /// ```
714    pub fn create_from_block(
715        &self,
716        driver_name: &str,
717        block_device: Box<dyn BlockDevice>,
718        block_size: usize,
719    ) -> Result<Box<dyn VirtualFileSystem>> {
720        let binding = self.drivers.read();
721        let driver = binding.get(driver_name).ok_or(FileSystemError {
722            kind: FileSystemErrorKind::NotFound,
723            message: format!("File system driver '{}' not found", driver_name),
724        })?;
725
726        if driver.filesystem_type() == FileSystemType::Memory || driver.filesystem_type() == FileSystemType::Virtual {
727            return Err(FileSystemError {
728                kind: FileSystemErrorKind::NotSupported,
729                message: format!("File system driver '{}' does not support block devices", driver_name),
730            });
731        }
732
733        driver.create_from_block(block_device, block_size)
734    }
735
736    /// Create a filesystem from a memory area
737    /// 
738    /// Creates a new filesystem instance using the specified driver and memory region.
739    /// This is typically used for RAM-based filesystems like tmpfs or for mounting
740    /// filesystem images stored in memory (e.g., initramfs).
741    /// 
742    /// # Arguments
743    /// 
744    /// * `driver_name` - The name of the registered driver to use
745    /// * `memory_area` - The memory region containing filesystem data or available for use
746    /// 
747    /// # Returns
748    /// 
749    /// * `Ok(Box<dyn VirtualFileSystem>)` - Successfully created filesystem instance
750    /// * `Err(FileSystemError)` - If driver not found, doesn't support memory-based creation, or creation fails
751    /// 
752    /// # Errors
753    /// 
754    /// - `NotFound` - Driver with the specified name is not registered
755    /// - `NotSupported` - Driver only supports block device-based filesystems
756    /// - Driver-specific errors during filesystem creation
757    /// 
758    /// # Example
759    /// 
760    /// ```rust
761    /// let memory_area = MemoryArea::new(addr, size);
762    /// let fs = manager.create_from_memory("cpiofs", &memory_area)?;
763    /// ```
764    pub fn create_from_memory(
765        &self,
766        driver_name: &str,
767        memory_area: &MemoryArea,
768    ) -> Result<Box<dyn VirtualFileSystem>> {
769        let binding = self.drivers.read();
770        let driver = binding.get(driver_name).ok_or(FileSystemError {
771            kind: FileSystemErrorKind::NotFound,
772            message: format!("File system driver '{}' not found", driver_name),
773        })?;
774
775        if driver.filesystem_type() == FileSystemType::Block {
776            return Err(FileSystemError {
777                kind: FileSystemErrorKind::NotSupported,
778                message: format!("File system driver '{}' does not support memory-based filesystems", driver_name),
779            });
780        }
781
782        driver.create_from_memory(memory_area)
783    }
784
785    /// Create a filesystem with structured parameters
786    /// 
787    /// This method creates filesystems using type-safe structured parameters that
788    /// implement the FileSystemParams trait. This approach replaces the old BTreeMap<String, String>
789    /// configuration method with better type safety and validation.
790    /// 
791    /// The method uses dynamic dispatch to handle different parameter types, enabling
792    /// future dynamic filesystem module loading while maintaining type safety at the
793    /// driver level.
794    /// 
795    /// # Arguments
796    /// 
797    /// * `driver_name` - The name of the registered driver to use
798    /// * `params` - Parameter structure implementing FileSystemParams trait
799    /// 
800    /// # Returns
801    /// 
802    /// * `Ok(Box<dyn VirtualFileSystem>)` - Successfully created filesystem instance
803    /// * `Err(FileSystemError)` - If driver not found, parameters invalid, or creation fails
804    /// 
805    /// # Errors
806    /// 
807    /// - `NotFound` - Driver with the specified name is not registered
808    /// - `NotSupported` - Driver doesn't support the provided parameter type
809    /// - Driver-specific parameter validation errors
810    /// 
811    /// # Example
812    /// 
813    /// ```rust
814    /// use crate::fs::params::TmpFSParams;
815    /// 
816    /// let params = TmpFSParams::new(1048576, 0); // 1MB limit
817    /// let fs = manager.create_with_params("tmpfs", &params)?;
818    /// ```
819    /// 
820    /// # Note
821    /// 
822    /// This method uses dynamic dispatch for parameter handling to support
823    /// future dynamic filesystem module loading while maintaining type safety.
824    pub fn create_with_params(
825        &self, 
826        driver_name: &str, 
827        params: &dyn crate::fs::params::FileSystemParams
828    ) -> Result<Box<dyn VirtualFileSystem>> {
829        let binding = self.drivers.read();
830        let driver = binding.get(driver_name)
831            .ok_or_else(|| FileSystemError {
832                kind: FileSystemErrorKind::NotFound,
833                message: format!("File system driver '{}' not found", driver_name),
834            })?;
835
836        // Use dynamic dispatch for structured parameters
837        driver.create_with_params(params)
838    }
839
840    /// Get filesystem driver information by name
841    /// 
842    /// Retrieves the filesystem type supported by a registered driver.
843    /// This is useful for validating driver capabilities before attempting
844    /// to create filesystems.
845    /// 
846    /// # Arguments
847    /// 
848    /// * `driver_name` - The name of the driver to query
849    /// 
850    /// # Returns
851    /// 
852    /// * `Some(FileSystemType)` - The filesystem type if driver exists
853    /// * `None` - If no driver with the specified name is registered
854    /// 
855    /// # Example
856    /// 
857    /// ```rust
858    /// if let Some(fs_type) = manager.get_driver_type("tmpfs") {
859    ///     match fs_type {
860    ///         FileSystemType::Virtual => println!("TmpFS is a virtual filesystem"),
861    ///         _ => println!("Unexpected filesystem type"),
862    ///     }
863    /// }
864    /// ```
865    pub fn get_driver_type(&self, driver_name: &str) -> Option<FileSystemType> {
866        self.drivers.read().get(driver_name).map(|driver| driver.filesystem_type())
867    }
868}
869
870impl Default for FileSystemDriverManager {
871    fn default() -> Self {
872        Self::new()
873    }
874}
875
876pub type FileSystemRef = Arc<RwLock<Box<dyn VirtualFileSystem>>>;
877
878pub enum ManagerRef<'a> {
879    Global, // Use the global manager
880    Local(&'a mut VfsManager), // Use a specific manager
881}
882
883
884/// VFS manager for per-task or shared filesystem management.
885///
886/// `VfsManager` provides flexible virtual filesystem management supporting both
887/// process isolation and filesystem sharing scenarios.
888///
889/// # Architecture
890///
891/// Each `VfsManager` instance maintains:
892/// - Independent mount point namespace using hierarchical MountTree
893/// - Reference-counted filesystem objects that can be shared between managers
894/// - Thread-safe operations via RwLock protection
895/// - Security-enhanced path resolution with protection against directory traversal
896///
897/// # Usage Scenarios
898///
899/// ## 1. Container Isolation
900/// Each container gets its own `VfsManager` with completely isolated mount points:
901/// ```rust
902/// let mut container_vfs = VfsManager::new();
903/// let fs_index = container_vfs.register_fs(container_fs);
904/// container_vfs.mount(fs_index, "/");
905/// task.vfs = Some(Arc::new(container_vfs));
906/// ```
907///
908/// ## 2. Shared Filesystem Access
909/// Multiple tasks can share VfsManager objects using Arc:
910/// ```rust
911/// let shared_vfs = Arc::new(original_vfs); // Shares filesystem objects and mount points
912/// let fs_index = shared_vfs.register_fs(shared_fs);
913/// shared_vfs.mount(fs_index, "/mnt/shared"); // Shared mount points
914/// ```
915///
916/// # Performance Improvements
917///
918/// The new MountTree implementation provides:
919/// - O(log k) path resolution where k is path depth
920/// - Efficient mount point hierarchy management
921/// - Security-enhanced path normalization
922/// - Reduced memory usage through Trie structure
923///
924/// # Thread Safety
925///
926/// All internal data structures use RwLock for thread-safe concurrent access.
927/// VfsManager can be shared between threads using Arc for cases requiring
928/// shared filesystem access across multiple tasks.
929pub struct VfsManager {
930    filesystems: RwLock<BTreeMap<usize, FileSystemRef>>,
931    mount_tree: RwLock<MountTree>,
932    next_fs_id: RwLock<usize>,
933}
934
935impl VfsManager {
936    /// Create a new VFS manager instance
937    /// 
938    /// This method creates a new VfsManager with empty filesystem registry
939    /// and mount tree. Each VfsManager instance provides an isolated
940    /// filesystem namespace, making it suitable for containerization and
941    /// process isolation scenarios.
942    /// 
943    /// # Returns
944    /// 
945    /// * `Self` - A new VfsManager instance ready for filesystem registration and mounting
946    /// 
947    /// # Examples
948    /// 
949    /// ```rust
950    /// // Create isolated VFS for a container
951    /// let container_vfs = VfsManager::new();
952    /// 
953    /// // Create shared VFS for multiple tasks
954    /// let shared_vfs = Arc::new(VfsManager::new());
955    /// ```
956    pub fn new() -> Self {
957        Self {
958            filesystems: RwLock::new(BTreeMap::new()),
959            mount_tree: RwLock::new(MountTree::new()),
960            next_fs_id: RwLock::new(1), // Start from 1 to avoid zero ID
961        }
962    }
963
964    /// Register a filesystem with the VFS manager
965    /// 
966    /// This method adds a filesystem instance to the VfsManager's registry,
967    /// assigning it a unique ID for future operations. The filesystem remains
968    /// available for mounting until it's actually mounted on a mount point.
969    /// 
970    /// # Arguments
971    /// 
972    /// * `fs` - The filesystem instance to register (must implement VirtualFileSystem)
973    /// 
974    /// # Returns
975    /// 
976    /// * `usize` - Unique filesystem ID for use in mount operations
977    /// 
978    /// # Thread Safety
979    /// 
980    /// This method is thread-safe and can be called concurrently from multiple threads.
981    /// 
982    /// # Examples
983    /// 
984    /// ```rust
985    /// // Register a block-based filesystem
986    /// let device = Box::new(SomeBlockDevice::new());
987    /// let fs = Box::new(SomeFileSystem::new("myfs", device, 512));
988    /// let fs_id = vfs_manager.register_fs(fs);
989    /// 
990    /// // Later mount the filesystem
991    /// vfs_manager.mount(fs_id, "/mnt")?;
992    /// ```
993    pub fn register_fs(&mut self, fs: Box<dyn VirtualFileSystem>) -> usize {
994        let mut next_fs_id = self.next_fs_id.write();
995        let fs_id = *next_fs_id;
996        *next_fs_id += 1;
997        
998        // Do not set ID on filesystem - VfsManager manages it
999        let fs_ref = Arc::new(RwLock::new(fs));
1000        self.filesystems.write().insert(fs_id, fs_ref);
1001        
1002        fs_id
1003    }
1004
1005    /// Create and register a block device-based filesystem
1006    /// 
1007    /// This convenience method combines filesystem creation and registration in a single
1008    /// operation. It uses the global FileSystemDriverManager to create a filesystem
1009    /// from the specified block device and automatically registers it with this VfsManager.
1010    /// 
1011    /// # Arguments
1012    /// 
1013    /// * `driver_name` - The name of the registered filesystem driver to use
1014    /// * `block_device` - The block device that will store the filesystem data
1015    /// * `block_size` - The block size for I/O operations (typically 512, 1024, or 4096 bytes)
1016    /// 
1017    /// # Returns
1018    /// 
1019    /// * `Ok(usize)` - The filesystem ID assigned by this VfsManager
1020    /// * `Err(FileSystemError)` - If driver not found, creation fails, or registration fails
1021    /// 
1022    /// # Example
1023    /// 
1024    /// ```rust
1025    /// let device = get_block_device();
1026    /// let fs_id = vfs_manager.create_and_register_block_fs("ext4", device, 4096)?;
1027    /// vfs_manager.mount(fs_id, "/mnt")?;
1028    /// ```
1029    pub fn create_and_register_block_fs(
1030        &mut self,
1031        driver_name: &str,
1032        block_device: Box<dyn BlockDevice>,
1033        block_size: usize,
1034    ) -> Result<usize> {
1035        
1036        // Create the file system using the driver manager
1037        let fs = get_fs_driver_manager().create_from_block(driver_name, block_device, block_size)?;
1038
1039        Ok(self.register_fs(fs))
1040    }
1041
1042    /// Create and register a memory-based filesystem
1043    /// 
1044    /// This convenience method combines filesystem creation and registration in a single
1045    /// operation for memory-based filesystems like tmpfs or initramfs. It uses the global
1046    /// FileSystemDriverManager to create a filesystem and automatically registers it.
1047    /// 
1048    /// # Arguments
1049    /// 
1050    /// * `driver_name` - The name of the registered filesystem driver to use
1051    /// * `memory_area` - The memory region containing filesystem data or available for use
1052    /// 
1053    /// # Returns
1054    /// 
1055    /// * `Ok(usize)` - The filesystem ID assigned by this VfsManager
1056    /// * `Err(FileSystemError)` - If driver not found, creation fails, or registration fails
1057    /// 
1058    /// # Example
1059    /// 
1060    /// ```rust
1061    /// let memory_area = MemoryArea::new(initramfs_addr, initramfs_size);
1062    /// let fs_id = vfs_manager.create_and_register_memory_fs("cpiofs", &memory_area)?;
1063    /// vfs_manager.mount(fs_id, "/")?;
1064    /// ```
1065    pub fn create_and_register_memory_fs(
1066        &mut self,
1067        driver_name: &str,
1068        memory_area: &crate::vm::vmem::MemoryArea,
1069    ) -> Result<usize> {
1070        
1071        // Create the file system using the driver manager
1072        let fs = get_fs_driver_manager().create_from_memory(driver_name, memory_area)?;
1073
1074        Ok(self.register_fs(fs))
1075    }
1076
1077    /// Create and register a file system with structured parameters
1078    /// 
1079    /// This method allows creating file systems with structured configuration
1080    /// parameters. It uses dynamic dispatch to handle different parameter types,
1081    /// enabling future dynamic filesystem module loading.
1082    /// 
1083    /// # Arguments
1084    /// 
1085    /// * `driver_name` - The name of the file system driver
1086    /// * `params` - Parameter structure implementing FileSystemParams
1087    /// 
1088    /// # Returns
1089    /// 
1090    /// * `Result<usize>` - The ID of the registered file system
1091    /// 
1092    /// # Errors
1093    /// 
1094    /// * `FileSystemError` - If the driver is not found or if the file system cannot be created
1095    /// 
1096    /// # Example
1097    /// 
1098    /// ```rust
1099    /// use crate::fs::params::TmpFSParams;
1100    /// 
1101    /// let params = TmpFSParams::with_memory_limit(1048576); // 1MB limit
1102    /// let fs_id = manager.create_and_register_fs_with_params("tmpfs", &params)?;
1103    /// ```
1104    pub fn create_and_register_fs_with_params(
1105        &mut self,
1106        driver_name: &str,
1107        params: &dyn crate::fs::params::FileSystemParams,
1108    ) -> Result<usize> {
1109        
1110        // Create the file system using the driver manager with structured parameters
1111        let fs = get_fs_driver_manager().create_with_params(driver_name, params)?;
1112
1113        Ok(self.register_fs(fs))
1114    }
1115    
1116    /// Mount a file system at a specified mount point  
1117    /// 
1118    /// # Arguments
1119    /// 
1120    /// * `fs_id` - The ID of the file system to mount
1121    /// * `mount_point` - The mount point for the file system
1122    /// 
1123    /// # Returns
1124    /// 
1125    /// * `Result<()>` - Ok if the mount was successful, Err if there was an error
1126    /// 
1127    pub fn mount(&mut self, fs_id: usize, mount_point: &str) -> Result<()> {
1128        let mut filesystems = self.filesystems.write();
1129        // Remove the file system from available pool using BTreeMap
1130        let fs = filesystems.remove(&fs_id)
1131            .ok_or(FileSystemError {
1132                kind: FileSystemErrorKind::NotFound,
1133                message: format!("File system with ID {} not found", fs_id),
1134            })?;
1135            
1136        {
1137            let mut fs_write = fs.write();
1138            
1139            // Perform the mount operation
1140            fs_write.mount(mount_point)?;
1141        }
1142        
1143        // Create mount point entry with enhanced metadata
1144        let mount_point_entry = TreeMountPoint {
1145            path: mount_point.to_string(),
1146            fs: fs.clone(),
1147            fs_id,  // Store VfsManager's ID in mount point
1148            mount_type: MountType::Regular,
1149            mount_options: MountOptions::default(),
1150            parent: None,
1151            children: Vec::new(),
1152            mount_time: 0, // TODO: Get actual timestamp
1153        };
1154        
1155        // Register with MountTree
1156        self.mount_tree.write().mount(mount_point, mount_point_entry)?;
1157        
1158        Ok(())
1159    }
1160    
1161    /// Unmount a file system from a specified mount point
1162    /// 
1163    /// # Arguments
1164    /// 
1165    /// * `mount_point` - The mount point to unmount
1166    /// 
1167    /// # Returns
1168    /// 
1169    /// * `Result<()>` - Ok if the unmount was successful, Err if there was an error
1170    /// 
1171    pub fn unmount(&mut self, mount_point: &str) -> Result<()> {
1172        // Remove the mount point from MountTree
1173        let mp = self.mount_tree.write().remove(mount_point)?;
1174    
1175        match &mp.mount_type {
1176            mount_tree::MountType::Bind { .. } => {
1177                // Bind mounts do not need to unmount the underlying filesystem
1178                // They are just references to existing filesystems
1179            },
1180            _ => {
1181                // For regular mounts, we need to call unmount on the filesystem
1182                let mut fs_write = mp.fs.write();
1183                fs_write.unmount()?;
1184
1185                // Return the file system to the registration list using stored fs_id
1186                self.filesystems.write().insert(mp.fs_id, mp.fs.clone());
1187            }
1188        }
1189        
1190        
1191        Ok(())
1192    }
1193
1194    /// Bind mount a source path to a target path
1195    /// 
1196    /// This creates a bind mount where the target path will provide access to the same
1197    /// content as the source path. The bind mount can be read-only or read-write.
1198    /// 
1199    /// # Arguments
1200    /// 
1201    /// * `source_path` - The source path to bind from
1202    /// * `target_path` - The target mount point where the source will be accessible
1203    /// * `read_only` - Whether the bind mount should be read-only
1204    /// 
1205    /// # Returns
1206    /// 
1207    /// * `Result<()>` - Ok if the bind mount was successful, Err otherwise
1208    /// 
1209    /// # Example
1210    /// 
1211    /// ```rust
1212    /// // Bind mount /mnt/source to /mnt/target as read-only
1213    /// vfs_manager.bind_mount("/mnt/source", "/mnt/target", true)?;
1214    /// ```
1215    pub fn bind_mount(&mut self, source_path: &str, target_path: &str, read_only: bool) -> Result<()> {
1216        let normalized_source = Self::normalize_path(source_path);
1217        let normalized_target = Self::normalize_path(target_path);
1218
1219        // Get the source MountNode
1220        let mount_tree = self.mount_tree.read();
1221        let (source_mount_node, source_relative_path) = mount_tree.resolve(&normalized_source)?;
1222        drop(mount_tree);
1223        
1224        // Get the source filesystem (for caching)
1225        let source_mount_point = source_mount_node.get_mount_point()?;
1226        let source_fs = source_mount_point.fs.clone();
1227        
1228        // Create the bind mount point
1229        let bind_mount_point = mount_tree::MountPoint {
1230            path: normalized_target.clone(),
1231            fs: source_fs,
1232            fs_id: 0, // Special ID for bind mounts
1233            mount_type: mount_tree::MountType::Bind {
1234                source_mount_node,
1235                source_relative_path,
1236                bind_type: if read_only { mount_tree::BindType::ReadOnly } else { mount_tree::BindType::ReadWrite },
1237            },
1238            mount_options: mount_tree::MountOptions {
1239                read_only,
1240                ..Default::default()
1241            },
1242            parent: None,
1243            children: Vec::new(),
1244            mount_time: 0, // TODO: actual timestamp
1245        };
1246        
1247        // Insert the bind mount into the MountTree
1248        self.mount_tree.write().insert(&normalized_target, bind_mount_point)?;
1249        
1250        Ok(())
1251    }
1252
1253    /// Bind mount from another VFS manager
1254    /// 
1255    /// This creates a bind mount where the target path in this VFS manager
1256    /// will provide access to content from a different VFS manager instance.
1257    /// This is useful for sharing filesystem content between containers.
1258    /// 
1259    /// # Arguments
1260    /// 
1261    /// * `source_vfs` - The source VFS manager containing the source path
1262    /// * `source_path` - The source path in the source VFS manager
1263    /// * `target_path` - The target mount point in this VFS manager
1264    /// * `read_only` - Whether the bind mount should be read-only
1265    /// 
1266    /// # Returns
1267    /// 
1268    /// * `Result<()>` - Ok if the bind mount was successful, Err otherwise
1269    /// 
1270    /// # Example
1271    /// 
1272    /// ```rust
1273    /// // Bind mount /data from host_vfs to /mnt/shared in container_vfs
1274    /// container_vfs.bind_mount_from(&host_vfs, "/data", "/mnt/shared", false)?;
1275    /// ```
1276    pub fn bind_mount_from(
1277        &mut self, 
1278        source_vfs: &Arc<VfsManager>, 
1279        source_path: &str, 
1280        target_path: &str, 
1281        read_only: bool
1282    ) -> Result<()> {
1283        let normalized_source = Self::normalize_path(source_path);
1284        let normalized_target = Self::normalize_path(target_path);
1285        
1286        // Get MountNode from source VFS
1287        let source_mount_tree = source_vfs.mount_tree.read();
1288        let (source_mount_node, source_relative_path) = source_mount_tree.resolve(&normalized_source)?;
1289        drop(source_mount_tree);
1290        
1291        // Get the source filesystem
1292        let source_mount_point = source_mount_node.get_mount_point()?;
1293        let source_fs = source_mount_point.fs.clone();
1294
1295        // Create the bind mount point
1296        let bind_mount_point = mount_tree::MountPoint {
1297            path: normalized_target.clone(),
1298            fs: source_fs,
1299            fs_id: 0,
1300            mount_type: mount_tree::MountType::Bind {
1301                source_mount_node,
1302                source_relative_path,
1303                bind_type: if read_only { mount_tree::BindType::ReadOnly } else { mount_tree::BindType::ReadWrite },
1304            },
1305            mount_options: mount_tree::MountOptions {
1306                read_only,
1307                ..Default::default()
1308            },
1309            parent: None,
1310            children: Vec::new(),
1311            mount_time: 0,
1312        };
1313
1314        // Insert the bind mount into the MountTree
1315        self.mount_tree.write().insert(&normalized_target, bind_mount_point)?;
1316        
1317        Ok(())
1318    }
1319
1320    /// Create a shared bind mount
1321    /// 
1322    /// This creates a shared bind mount where changes to mount propagation
1323    /// will be shared between the source and target. This is useful for
1324    /// scenarios where you want mount events to propagate between namespaces.
1325    /// 
1326    /// # Arguments
1327    /// 
1328    /// * `source_path` - The source path to bind from
1329    /// * `target_path` - The target mount point
1330    /// 
1331    /// # Returns
1332    /// 
1333    /// * `Result<()>` - Ok if the shared bind mount was successful, Err otherwise
1334    pub fn bind_mount_shared(&mut self, source_path: &str, target_path: &str) -> Result<()> {
1335        // Normalize the source path to prevent directory traversal
1336        let normalized_source_path = Self::normalize_path(source_path);
1337        
1338        // Resolve the source path to get the mount node and relative path within that mount
1339        let (source_mount_node, source_relative_path) = self.mount_tree.read().resolve(&normalized_source_path)?;
1340        
1341        let mount_point_entry = TreeMountPoint {
1342            path: target_path.to_string(),
1343            fs: source_mount_node.get_mount_point()?.fs.clone(),
1344            fs_id: 0, // Special ID for bind mounts
1345            mount_type: MountType::Bind {
1346                source_mount_node,
1347                source_relative_path,
1348                bind_type: mount_tree::BindType::Shared,
1349            },
1350            mount_options: MountOptions::default(),
1351            parent: None,
1352            children: Vec::new(),
1353            mount_time: 0, // TODO: Get actual timestamp
1354        };
1355        
1356        self.mount_tree.write().mount(target_path, mount_point_entry)?;
1357        
1358        Ok(())
1359    }
1360
1361    /// Thread-safe bind mount for use from system calls
1362    /// 
1363    /// This method can be called on a shared VfsManager (Arc<VfsManager>)
1364    /// from system call context where &mut self is not available.
1365    /// 
1366    /// # Arguments
1367    /// 
1368    /// * `source_path` - The source path to bind from
1369    /// * `target_path` - The target mount point where the source will be accessible
1370    /// * `read_only` - Whether the bind mount should be read-only
1371    /// 
1372    /// # Returns
1373    /// 
1374    /// * `Result<()>` - Ok if the bind mount was successful, Err otherwise
1375    pub fn bind_mount_shared_ref(&self, source_path: &str, target_path: &str, read_only: bool) -> Result<()> {
1376        // Normalize the source path to prevent directory traversal
1377        let normalized_source_path = Self::normalize_path(source_path);
1378        
1379        // Resolve the source path to get the mount node and relative path within that mount
1380        let (source_mount_node, source_relative_path) = self.mount_tree.read().resolve(&normalized_source_path)?;
1381        
1382        // Create a bind mount point entry
1383        let bind_type = if read_only {
1384            mount_tree::BindType::ReadOnly
1385        } else {
1386            mount_tree::BindType::ReadWrite
1387        };
1388        
1389        let mount_point_entry = TreeMountPoint {
1390            path: target_path.to_string(),
1391            fs: source_mount_node.get_mount_point()?.fs.clone(),
1392            fs_id: 0, // Special ID for bind mounts - they don't consume fs_id
1393            mount_type: MountType::Bind {
1394                source_mount_node,
1395                source_relative_path,
1396                bind_type,
1397            },
1398            mount_options: MountOptions {
1399                read_only,
1400                ..Default::default()
1401            },
1402            parent: None,
1403            children: Vec::new(),
1404            mount_time: 0, // TODO: Get actual timestamp
1405        };
1406        
1407        // Register with MountTree
1408        self.mount_tree.write().mount(target_path, mount_point_entry)?;
1409        
1410        Ok(())
1411    }
1412
1413    /// Check if a path is a bind mount
1414    /// 
1415    /// # Arguments
1416    /// 
1417    /// * `path` - The path to check
1418    /// 
1419    /// # Returns
1420    /// 
1421    /// * `bool` - True if the path is a bind mount, false otherwise
1422    pub fn is_bind_mount(&self, path: &str) -> bool {
1423        // Use non-transparent resolution to check the mount node itself
1424        if let Ok((mount_node, _)) = self.mount_tree.read().resolve_non_transparent(path) {
1425            if let Ok(mount_point) = mount_node.get_mount_point() {
1426                matches!(mount_point.mount_type, MountType::Bind { .. })
1427            } else {
1428                false
1429            }
1430        } else {
1431            false
1432        }
1433    }
1434
1435    /// Normalize a path
1436    /// 
1437    /// # Arguments
1438    /// 
1439    /// * `path` - The path to normalize
1440    /// 
1441    /// # Returns
1442    /// 
1443    /// * `String` - The normalized path
1444    /// 
1445    fn normalize_path(path: &str) -> String {
1446        // Remember if the path is absolute
1447        let is_absolute = path.starts_with('/');
1448        
1449        // Decompose and normalize the path
1450        let mut components = Vec::new();
1451        
1452        // Split the path into components and process them
1453        for component in path.split('/') {
1454            match component {
1455                "" => continue,   // Skip empty components (consecutive slashes)
1456                "." => continue,  // Ignore current directory
1457                ".." => {
1458                    // For parent directory, remove the previous component
1459                    // However, cannot go above root for absolute paths
1460                    if !components.is_empty() && *components.last().unwrap() != ".." {
1461                        components.pop();
1462                    } else if !is_absolute {
1463                        // Keep '..' for relative paths
1464                        components.push("..");
1465                    }
1466                },
1467                _ => components.push(component), // Normal directory name
1468            }
1469        }
1470        
1471        // Construct the result
1472        let normalized = if is_absolute {
1473            // Add / to the beginning for absolute paths
1474            format!("/{}", components.join("/"))
1475        } else if components.is_empty() {
1476            // Current directory if the result is empty for a relative path
1477            ".".to_string()
1478        } else {
1479            // Normal relative path
1480            components.join("/")
1481        };
1482        
1483        // Return root for empty path
1484        if normalized.is_empty() {
1485            "/".to_string()
1486        } else {
1487            normalized
1488        }
1489    }
1490    
1491    /// Execute a function with the resolved file system and path
1492    /// 
1493    /// # Arguments
1494    /// 
1495    /// * `path` - The path to resolve
1496    /// * `f` - The function to execute with the resolved file system and path
1497    /// 
1498    /// # Returns
1499    /// 
1500    /// * `Result<T>` - The result of the function execution
1501    /// 
1502    /// # Errors
1503    /// 
1504    /// * `FileSystemError` - If no file system is mounted for the specified path
1505    /// 
1506    fn with_resolve_path<F, T>(&self, path: &str, f: F) -> Result<T>
1507    where
1508        F: FnOnce(&FileSystemRef, &str) -> Result<T>
1509    {
1510        let (fs, relative_path) = self.resolve_path(path)?;
1511        f(&fs, &relative_path)
1512    }
1513
1514    /// Resolve the path to the file system and relative path
1515    /// 
1516    /// This method performs path resolution within the VfsManager's mount tree,
1517    /// handling bind mounts, security validation, and path normalization.
1518    /// 
1519    /// # Path Resolution Process
1520    /// 
1521    /// 1. **Path Normalization**: Remove `.` and `..` components, validate against directory traversal
1522    /// 2. **Mount Point Lookup**: Find the most specific mount point for the given path
1523    /// 3. **Bind Mount Resolution**: Transparently handle bind mounts by resolving to source
1524    /// 4. **Relative Path Calculation**: Calculate the path relative to the filesystem root
1525    /// 
1526    /// # Arguments
1527    /// 
1528    /// * `path` - The absolute path to resolve (must start with `/`)
1529    /// 
1530    /// # Returns
1531    /// 
1532    /// * `Result<(FileSystemRef, String)>` - Tuple containing:
1533    ///   - `FileSystemRef`: Arc-wrapped filesystem that handles this path
1534    ///   - `String`: Path relative to the filesystem root (always starts with `/`)
1535    /// 
1536    /// # Errors
1537    /// 
1538    /// * `FileSystemErrorKind::NotFound` - No filesystem mounted for the path
1539    /// * `FileSystemErrorKind::InvalidPath` - Path validation failed (e.g., directory traversal attempt)
1540    /// 
1541    /// # Examples
1542    /// 
1543    /// ```rust
1544    /// // Mount filesystem at /mnt
1545    /// let fs_id = vfs.register_fs(filesystem);
1546    /// vfs.mount(fs_id, "/mnt")?;
1547    /// 
1548    /// // Resolve paths
1549    /// let (fs, rel_path) = vfs.resolve_path("/mnt/dir/file.txt")?;
1550    /// assert_eq!(rel_path, "/dir/file.txt");
1551    /// 
1552    /// // Bind mount example
1553    /// vfs.bind_mount("/mnt/data", "/data", false)?;
1554    /// let (fs2, rel_path2) = vfs.resolve_path("/data/file.txt")?;
1555    /// // fs2 points to the same filesystem as fs, rel_path2 is "/data/file.txt"
1556    /// ```
1557    /// 
1558    /// # Security
1559    /// 
1560    /// This method includes protection against directory traversal attacks:
1561    /// - Normalizes `..` and `.` components
1562    /// - Prevents escaping mount point boundaries
1563    /// - Validates all path components for security
1564    /// # Arguments
1565    /// 
1566    /// * `path` - The path to resolve (must be absolute)
1567    /// 
1568    /// # Returns
1569    /// 
1570    /// * `Result<(FileSystemRef, String)>` - The resolved file system and relative path
1571    /// 
1572    /// # Errors
1573    /// 
1574    /// * `FileSystemError` - If no file system is mounted for the specified path
1575    /// 
1576    fn resolve_path(&self, path: &str) -> Result<(FileSystemRef, String)> {
1577        // Check if the path is absolute
1578        if !path.starts_with('/') {
1579            return Err(FileSystemError {
1580                kind: FileSystemErrorKind::InvalidPath,
1581                message: format!("Path must be absolute: {}", path),
1582            });
1583        }
1584        
1585        // Phase 1: Get MountNode and relative path from MountTree
1586        let mount_tree = self.mount_tree.read();
1587        let (mount_node, relative_path) = mount_tree.resolve(path)?;
1588        drop(mount_tree);
1589
1590        // Phase 2: Get MountPoint from MountNode
1591        let mount_point = mount_node.get_mount_point()?;
1592
1593        // Phase 3: Get filesystem and internal path from MountPoint
1594        mount_point.resolve_fs(&relative_path)
1595    }
1596
1597    /// Get absolute path from relative path and current working directory
1598    /// 
1599    /// # Arguments
1600    /// Convert a relative path to an absolute path using the task's current working directory
1601    /// 
1602    /// This method provides path resolution for system calls that accept relative paths.
1603    /// It combines the task's current working directory with the relative path to
1604    /// create an absolute path suitable for VFS operations.
1605    /// 
1606    /// # Arguments
1607    /// 
1608    /// * `task` - The task containing the current working directory
1609    /// * `path` - The relative path to convert (if already absolute, returns as-is)
1610    /// 
1611    /// # Returns
1612    /// 
1613    /// * `Result<String>` - The absolute path ready for VFS operations
1614    /// 
1615    /// # Examples
1616    /// 
1617    /// ```rust
1618    /// // If task cwd is "/home/user" and path is "documents/file.txt"
1619    /// let abs_path = VfsManager::to_absolute_path(&task, "documents/file.txt")?;
1620    /// assert_eq!(abs_path, "/home/user/documents/file.txt");
1621    /// 
1622    /// // Absolute paths are returned unchanged
1623    /// let abs_path = VfsManager::to_absolute_path(&task, "/etc/config")?;
1624    /// assert_eq!(abs_path, "/etc/config");
1625    /// ```
1626    pub fn to_absolute_path(task: &Task, path: &str) -> Result<String> {
1627        if path.starts_with('/') {
1628            // If the path is already absolute, return it as is
1629            Ok(path.to_string())
1630        } else {
1631            let cwd = task.cwd.clone();
1632            if cwd.is_none() {
1633                return Err(FileSystemError {
1634                    kind: FileSystemErrorKind::InvalidPath,
1635                    message: "Current working directory is not set".to_string(),
1636                });
1637            }
1638            // Combine the current working directory and the relative path to create an absolute path
1639            let mut absolute_path = cwd.unwrap();
1640            if !absolute_path.ends_with('/') {
1641                absolute_path.push('/');
1642            }
1643            absolute_path.push_str(path);
1644            // Normalize and return the result
1645            Ok(Self::normalize_path(&absolute_path))
1646        }
1647    }
1648
1649    /// Open a file for reading/writing
1650    /// 
1651    /// This method opens a file through the VFS layer, automatically resolving
1652    /// the path to the appropriate filesystem and handling mount points and
1653    /// bind mounts transparently.
1654    /// 
1655    /// # Arguments
1656    /// 
1657    /// * `path` - The absolute path to the file to open
1658    /// * `flags` - File open flags (read, write, create, etc.)
1659    /// 
1660    /// # Returns
1661    /// 
1662    /// * `Result<File>` - A file handle for performing I/O operations
1663    /// 
1664    /// # Errors
1665    /// 
1666    /// * `FileSystemError` - If the file cannot be opened or the path is invalid
1667    /// 
1668    /// # Examples
1669    /// 
1670    /// ```rust
1671    /// // Open an existing file for reading
1672    /// let file = vfs.open("/etc/config.txt", OpenFlags::RDONLY)?;
1673    /// 
1674    /// // Create and open a new file for writing
1675    /// let file = vfs.open("/tmp/output.txt", OpenFlags::WRONLY | OpenFlags::CREATE)?;
1676    /// ```
1677    pub fn open(&self, path: &str, flags: u32) -> Result<File> {
1678        let handle = self.with_resolve_path(path, |fs, relative_path| fs.read().open(relative_path, flags));
1679        match handle {
1680            Ok(handle) => Ok(File { handle }),
1681            Err(e) => Err(e),
1682        }
1683    }
1684    /// Read directory entries
1685    /// 
1686    /// This method reads all entries from a directory, returning a vector of
1687    /// directory entry structures containing file names, types, and metadata.
1688    /// 
1689    /// # Arguments
1690    /// 
1691    /// * `path` - The absolute path to the directory to read
1692    /// 
1693    /// # Returns
1694    /// 
1695    /// * `Result<Vec<DirectoryEntry>>` - Vector of directory entries
1696    /// 
1697    /// # Errors
1698    /// 
1699    /// * `FileSystemError` - If the directory cannot be read or doesn't exist
1700    /// 
1701    /// # Examples
1702    /// 
1703    /// ```rust
1704    /// // List files in a directory
1705    /// let entries = vfs.read_dir("/home/user")?;
1706    /// for entry in entries {
1707    ///     println!("{}: {:?}", entry.name, entry.file_type);
1708    /// }
1709    /// ```
1710    pub fn read_dir(&self, path: &str) -> Result<Vec<DirectoryEntry>> {
1711        self.with_resolve_path(path, |fs, relative_path| fs.read().read_dir(relative_path))
1712    }
1713    
1714    /// Create a file with specified type
1715    /// 
1716    /// # Arguments
1717    /// 
1718    /// * `path` - The path to the file to create
1719    /// * `file_type` - The type of file to create
1720    /// 
1721    /// # Returns
1722    /// 
1723    /// * `Result<()>` - Ok if the file was created successfully, Err otherwise
1724    pub fn create_file(&self, path: &str, file_type: FileType) -> Result<()> {
1725        self.with_resolve_path(path, |fs, relative_path| fs.read().create_file(relative_path, file_type))
1726    }
1727    /// Create a directory at the specified path
1728    /// 
1729    /// This method creates a new directory in the filesystem, handling
1730    /// parent directory creation if necessary (depending on filesystem implementation).
1731    /// 
1732    /// # Arguments
1733    /// 
1734    /// * `path` - The absolute path where the directory should be created
1735    /// 
1736    /// # Returns
1737    /// 
1738    /// * `Result<()>` - Ok if the directory was created successfully
1739    /// 
1740    /// # Errors
1741    /// 
1742    /// * `FileSystemError` - If the directory cannot be created or already exists
1743    /// 
1744    /// # Examples
1745    /// 
1746    /// ```rust
1747    /// // Create a new directory
1748    /// vfs.create_dir("/tmp/new_directory")?;
1749    /// 
1750    /// // Create nested directories (if supported by filesystem)
1751    /// vfs.create_dir("/tmp/path/to/directory")?;
1752    /// ```
1753    pub fn create_dir(&self, path: &str) -> Result<()> {
1754        self.with_resolve_path(path, |fs, relative_path| fs.read().create_dir(relative_path))
1755    }
1756    /// Remove a file or directory
1757    /// 
1758    /// This method removes a file or directory from the filesystem.
1759    /// For directories, the behavior depends on the filesystem implementation
1760    /// (some may require the directory to be empty).
1761    /// 
1762    /// # Arguments
1763    /// 
1764    /// * `path` - The absolute path to the file or directory to remove
1765    /// 
1766    /// # Returns
1767    /// 
1768    /// * `Result<()>` - Ok if the item was removed successfully
1769    /// 
1770    /// # Errors
1771    /// 
1772    /// * `FileSystemError` - If the item cannot be removed or doesn't exist
1773    /// 
1774    /// # Examples
1775    /// 
1776    /// ```rust
1777    /// // Remove a file
1778    /// vfs.remove("/tmp/old_file.txt")?;
1779    /// 
1780    /// // Remove a directory
1781    /// vfs.remove("/tmp/empty_directory")?;
1782    /// ```
1783    pub fn remove(&self, path: &str) -> Result<()> {
1784        self.with_resolve_path(path, |fs, relative_path| fs.read().remove(relative_path))
1785    }
1786    /// Get file or directory metadata
1787    /// 
1788    /// This method retrieves metadata information about a file or directory,
1789    /// including file type, size, permissions, and timestamps.
1790    /// 
1791    /// # Arguments
1792    /// 
1793    /// * `path` - The absolute path to the file or directory
1794    /// 
1795    /// # Returns
1796    /// 
1797    /// * `Result<FileMetadata>` - Metadata structure containing file information
1798    /// 
1799    /// # Errors
1800    /// 
1801    /// * `FileSystemError` - If the file doesn't exist or metadata cannot be retrieved
1802    /// 
1803    /// # Examples
1804    /// 
1805    /// ```rust
1806    /// // Get file metadata
1807    /// let metadata = vfs.metadata("/etc/config.txt")?;
1808    /// println!("File size: {} bytes", metadata.size);
1809    /// println!("File type: {:?}", metadata.file_type);
1810    /// ```
1811    pub fn metadata(&self, path: &str) -> Result<FileMetadata> {
1812        self.with_resolve_path(path, |fs, relative_path| fs.read().metadata(relative_path))
1813    }
1814
1815    /// Create a regular file
1816    /// 
1817    /// This method creates a new regular file at the specified path.
1818    /// It's a convenience method that creates a file with FileType::RegularFile.
1819    /// 
1820    /// # Arguments
1821    /// 
1822    /// * `path` - The absolute path where the file should be created
1823    /// 
1824    /// # Returns
1825    /// 
1826    /// * `Result<()>` - Ok if the file was created successfully
1827    /// 
1828    /// # Errors
1829    /// 
1830    /// * `FileSystemError` - If the file cannot be created or already exists
1831    /// 
1832    /// # Examples
1833    /// 
1834    /// ```rust
1835    /// // Create a new regular file
1836    /// vfs.create_regular_file("/tmp/new_file.txt")?;
1837    /// ```
1838    pub fn create_regular_file(&self, path: &str) -> Result<()> {
1839        self.with_resolve_path(path, |fs, relative_path| fs.read().create_file(relative_path, FileType::RegularFile))
1840    }
1841    
1842    /// Create a character device file
1843    /// 
1844    /// This method creates a character device file in the filesystem.
1845    /// Character devices provide unbuffered access to hardware devices
1846    /// and are accessed through character-based I/O operations.
1847    /// 
1848    /// In Scarlet's device architecture, devices are identified by a unique
1849    /// device ID rather than traditional major/minor number pairs, providing
1850    /// a simplified and unified device identification system.
1851    /// 
1852    /// # Arguments
1853    /// 
1854    /// * `path` - The absolute path where the character device file should be created
1855    /// * `device_info` - Device information including unique device ID and type
1856    /// 
1857    /// # Returns
1858    /// 
1859    /// * `Result<()>` - Ok if the device file was created successfully
1860    /// 
1861    /// # Errors
1862    /// 
1863    /// * `FileSystemError` - If the device file cannot be created
1864    /// 
1865    /// # Examples
1866    /// 
1867    /// ```rust
1868    /// // Create a character device file for /dev/tty
1869    /// let device_info = DeviceFileInfo {
1870    ///     device_id: 1,
1871    ///     device_type: DeviceType::Char,
1872    /// };
1873    /// vfs.create_char_device("/dev/tty", device_info)?;
1874    /// ```
1875    pub fn create_char_device(&self, path: &str, device_info: DeviceFileInfo) -> Result<()> {
1876        self.create_file(path, FileType::CharDevice(device_info))
1877    }
1878    
1879    /// Create a block device file
1880    /// 
1881    /// This method creates a block device file in the filesystem.
1882    /// Block devices provide buffered access to hardware devices
1883    /// and are accessed through block-based I/O operations.
1884    /// 
1885    /// In Scarlet's device architecture, devices are identified by a unique
1886    /// device ID rather than traditional major/minor number pairs, enabling
1887    /// simplified device management and registration.
1888    /// 
1889    /// # Arguments
1890    /// 
1891    /// * `path` - The absolute path where the block device file should be created
1892    /// * `device_info` - Device information including unique device ID and type
1893    /// 
1894    /// # Returns
1895    /// 
1896    /// * `Result<()>` - Ok if the device file was created successfully
1897    /// 
1898    /// # Errors
1899    /// 
1900    /// * `FileSystemError` - If the device file cannot be created
1901    /// 
1902    /// # Examples
1903    /// 
1904    /// ```rust
1905    /// // Create a block device file for /dev/sda
1906    /// let device_info = DeviceFileInfo {
1907    ///     device_id: 8,
1908    ///     device_type: DeviceType::Block,
1909    /// };
1910    /// vfs.create_block_device("/dev/sda", device_info)?;
1911    /// ```
1912    pub fn create_block_device(&self, path: &str, device_info: DeviceFileInfo) -> Result<()> {
1913        self.create_file(path, FileType::BlockDevice(device_info))
1914    }
1915
1916    /// Create a named pipe (FIFO)
1917    /// 
1918    /// This method creates a named pipe in the filesystem, which provides
1919    /// inter-process communication through a FIFO queue mechanism.
1920    /// 
1921    /// # Arguments
1922    /// 
1923    /// * `path` - The absolute path where the pipe should be created
1924    /// 
1925    /// # Returns
1926    /// 
1927    /// * `Result<()>` - Ok if the pipe was created successfully
1928    /// 
1929    /// # Errors
1930    /// 
1931    /// * `FileSystemError` - If the pipe cannot be created
1932    /// 
1933    /// # Examples
1934    /// 
1935    /// ```rust
1936    /// // Create a named pipe for IPC
1937    /// vfs.create_pipe("/tmp/my_pipe")?;
1938    /// ```
1939    pub fn create_pipe(&self, path: &str) -> Result<()> {
1940        self.create_file(path, FileType::Pipe)
1941    }
1942
1943    /// Create a symbolic link
1944    /// 
1945    /// This method creates a symbolic link (symlink) in the filesystem.
1946    /// A symbolic link is a file that contains a reference to another file or directory.
1947    /// 
1948    /// # Arguments
1949    /// 
1950    /// * `path` - The absolute path where the symbolic link should be created
1951    /// 
1952    /// # Returns
1953    /// 
1954    /// * `Result<()>` - Ok if the symbolic link was created successfully
1955    /// 
1956    /// # Errors
1957    /// 
1958    /// * `FileSystemError` - If the symbolic link cannot be created
1959    /// 
1960    /// # Examples
1961    /// 
1962    /// ```rust
1963    /// // Create a symbolic link
1964    /// vfs.create_symlink("/tmp/link_to_file")?;
1965    /// ```
1966    pub fn create_symlink(&self, path: &str) -> Result<()> {
1967        self.create_file(path, FileType::SymbolicLink)
1968    }
1969
1970    /// Create a socket file
1971    /// 
1972    /// This method creates a Unix domain socket file in the filesystem.
1973    /// Socket files provide local inter-process communication endpoints.
1974    /// 
1975    /// # Arguments
1976    /// 
1977    /// * `path` - The absolute path where the socket file should be created
1978    /// 
1979    /// # Returns
1980    /// 
1981    /// * `Result<()>` - Ok if the socket file was created successfully
1982    /// 
1983    /// # Errors
1984    /// 
1985    /// * `FileSystemError` - If the socket file cannot be created
1986    /// 
1987    /// # Examples
1988    /// 
1989    /// ```rust
1990    /// // Create a Unix domain socket
1991    /// vfs.create_socket("/tmp/my_socket")?;
1992    /// ```
1993    pub fn create_socket(&self, path: &str) -> Result<()> {
1994        self.create_file(path, FileType::Socket)
1995    }
1996
1997    /// Create a device file of any type
1998    /// 
1999    /// This is a convenience method that automatically determines the appropriate
2000    /// FileType based on the DeviceType in the DeviceFileInfo.
2001    /// 
2002    /// # Arguments
2003    /// 
2004    /// * `path` - The path to the device file to create
2005    /// * `device_info` - Information about the device including its type
2006    /// 
2007    /// # Returns
2008    /// 
2009    /// * `Result<()>` - Ok if the device file was created successfully, Err otherwise
2010    /// 
2011    /// # Example
2012    /// 
2013    /// ```rust
2014    /// use crate::device::{DeviceType, DeviceFileInfo};
2015    /// 
2016    /// let device_info = DeviceFileInfo {
2017    ///     device_id: 1,
2018    ///     device_type: DeviceType::Char,
2019    /// };
2020    /// 
2021    /// vfs_manager.create_device_file("/dev/tty0", device_info)?;
2022    /// ```
2023    pub fn create_device_file(&self, path: &str, device_info: DeviceFileInfo) -> Result<()> {
2024        match device_info.device_type {
2025            crate::device::DeviceType::Char => {
2026                self.create_file(path, FileType::CharDevice(device_info))
2027            },
2028            crate::device::DeviceType::Block => {
2029                self.create_file(path, FileType::BlockDevice(device_info))
2030            },
2031            _ => {
2032                Err(FileSystemError {
2033                    kind: FileSystemErrorKind::NotSupported,
2034                    message: "Unsupported device type for file creation".to_string(),
2035                })
2036            },
2037        }
2038    }
2039
2040    /// Get the number of mount points
2041    pub fn mount_count(&self) -> usize {
2042        self.mount_tree.read().len()
2043    }
2044
2045    /// Check if a specific mount point exists
2046    pub fn has_mount_point(&self, path: &str) -> bool {
2047        self.mount_tree.read().resolve(path).is_ok()
2048    }
2049
2050    /// List all mount points
2051    pub fn list_mount_points(&self) -> Vec<String> {
2052        self.mount_tree.read().list_all()
2053    }
2054}
2055
2056
2057/// Template for a basic block device-based file system implementation
2058/// 
2059/// `GenericFileSystem` provides a foundation for implementing filesystems
2060/// that operate on block devices. It handles common filesystem operations
2061/// including mounting, block I/O, and basic filesystem state management.
2062/// 
2063/// This is primarily used as a base for filesystem drivers and testing,
2064/// not intended for direct use in production filesystems.
2065/// 
2066/// # Architecture
2067/// 
2068/// - **Block Device Integration**: Direct interface with block devices for storage
2069/// - **Mount State Management**: Tracks filesystem mount status and mount points
2070/// - **Thread-Safe Block I/O**: Mutex-protected access to the underlying block device
2071/// - **Extensible Design**: Can be extended by specific filesystem implementations
2072/// 
2073/// # Usage
2074/// 
2075/// ```rust
2076/// // Create a generic filesystem on a block device
2077/// let block_device = Box::new(SomeBlockDevice::new());
2078/// let fs = GenericFileSystem::new("myfs", block_device, 512);
2079/// 
2080/// // Register with VFS
2081/// let fs_id = vfs_manager.register_fs(Box::new(fs));
2082/// vfs_manager.mount(fs_id, "/mnt")?;
2083/// ```
2084pub struct GenericFileSystem {
2085    /// Name of the filesystem instance
2086    name: &'static str,
2087    /// Block device for storage operations (mutex-protected for thread safety)
2088    #[allow(dead_code)]
2089    block_device: Mutex<Box<dyn BlockDevice>>,
2090    /// Block size for I/O operations
2091    #[allow(dead_code)]
2092    block_size: usize,
2093    /// Mount status of the filesystem
2094    mounted: bool,
2095    /// Current mount point path
2096    mount_point: String,
2097}
2098
2099impl GenericFileSystem {
2100    /// Create a new generic filesystem instance
2101    /// 
2102    /// This method initializes a new filesystem instance that operates on a block device.
2103    /// The filesystem starts in an unmounted state and can be mounted later through
2104    /// the VFS layer.
2105    /// 
2106    /// # Arguments
2107    /// 
2108    /// * `name` - A static string identifier for this filesystem instance
2109    /// * `block_device` - The block device that will provide storage for this filesystem
2110    /// * `block_size` - The block size to use for I/O operations (typically 512, 1024, 4096)
2111    /// 
2112    /// # Returns
2113    /// 
2114    /// * `Self` - A new GenericFileSystem instance ready for registration
2115    /// 
2116    /// # Examples
2117    /// 
2118    /// ```rust
2119    /// let device = Box::new(SomeBlockDevice::new());
2120    /// let fs = GenericFileSystem::new("myfs", device, 512);
2121    /// ```
2122    pub fn new(name: &'static str, block_device: Box<dyn BlockDevice>, block_size: usize) -> Self {
2123        Self {
2124            name,
2125            block_device: Mutex::new(block_device),
2126            block_size,
2127            mounted: false,
2128            mount_point: String::new(),
2129        }
2130    }
2131    
2132    /// Internal method for reading blocks from the underlying block device
2133    /// 
2134    /// This method provides a low-level interface for reading data blocks
2135    /// from the filesystem's block device. It handles device locking and
2136    /// error conversion for filesystem operations.
2137    /// 
2138    /// # Arguments
2139    /// 
2140    /// * `block_idx` - The index of the block to read
2141    /// * `buffer` - Buffer to store the read data
2142    /// 
2143    /// # Returns
2144    /// 
2145    /// * `Result<()>` - Ok if the block was read successfully
2146    #[allow(dead_code)]
2147    fn read_block_internal(&self, block_idx: usize, buffer: &mut [u8]) -> Result<()> {
2148        let mut device = self.block_device.lock();
2149        
2150        // Create the request
2151        
2152        let request = Box::new(BlockIORequest {
2153            request_type: BlockIORequestType::Read,
2154            sector: block_idx,
2155            sector_count: 1,
2156            head: 0,
2157            cylinder: 0,
2158            buffer: vec![0; self.block_size],
2159        });
2160        
2161        // Send the request
2162        device.enqueue_request(request);
2163        
2164        // Get the result
2165        let results = device.process_requests();
2166        
2167        if results.len() != 1 {
2168            return Err(FileSystemError {
2169                kind: FileSystemErrorKind::IoError,
2170                message: format!("Failed to process block request for block index {}", block_idx), // Updated
2171            });
2172        }
2173        
2174        match &results[0].result {
2175            Ok(_) => {
2176                // Copy the data to the buffer
2177                let request = &results[0].request;
2178                buffer.copy_from_slice(&request.buffer);
2179                Ok(())
2180            },
2181            Err(msg) => Err(FileSystemError {
2182                kind: FileSystemErrorKind::IoError,
2183                message: msg.to_string(),
2184            }),
2185        }
2186    }
2187    
2188    /// Internal method for writing blocks to the underlying block device
2189    /// 
2190    /// This method provides a low-level interface for writing data blocks
2191    /// to the filesystem's block device. It handles device locking and
2192    /// error conversion for filesystem operations.
2193    /// 
2194    /// # Arguments
2195    /// 
2196    /// * `block_idx` - The index of the block to write
2197    /// * `buffer` - Buffer containing the data to write
2198    /// 
2199    /// # Returns
2200    /// 
2201    /// * `Result<()>` - Ok if the block was written successfully
2202    #[allow(dead_code)]
2203    fn write_block_internal(&self, block_idx: usize, buffer: &[u8]) -> Result<()> {
2204        let mut device = self.block_device.lock();
2205        
2206        // Create the request
2207        let request = Box::new(BlockIORequest {
2208            request_type: BlockIORequestType::Write,
2209            sector: block_idx,
2210            sector_count: 1,
2211            head: 0,
2212            cylinder: 0,
2213            buffer: buffer.to_vec(),
2214        });
2215        
2216        // Send the request
2217        device.enqueue_request(request);
2218        
2219        // Get the result
2220        let results = device.process_requests();
2221        
2222        if results.len() != 1 {
2223            return Err(FileSystemError {
2224                kind: FileSystemErrorKind::IoError,
2225                message: format!("Failed to process block write request for block index {}", block_idx), // Updated
2226            });
2227        }
2228        
2229        match &results[0].result {
2230            Ok(_) => Ok(()),
2231            Err(msg) => Err(FileSystemError {
2232                kind: FileSystemErrorKind::IoError,
2233                message: msg.to_string(),
2234            }),
2235        }
2236    }
2237}
2238
2239impl FileSystem for GenericFileSystem {
2240    fn mount(&mut self, mount_point: &str) -> Result<()> {
2241        if self.mounted {
2242            return Err(FileSystemError {
2243                kind: FileSystemErrorKind::AlreadyExists,
2244                message: "File system already mounted".to_string(),
2245            });
2246        }
2247        self.mounted = true;
2248        self.mount_point = mount_point.to_string();
2249        Ok(())
2250    }
2251
2252    fn unmount(&mut self) -> Result<()> {
2253        if !self.mounted {
2254            return Err(FileSystemError {
2255                kind: FileSystemErrorKind::NotFound,
2256                message: "File system not mounted".to_string(),
2257            });
2258        }
2259        self.mounted = false;
2260        self.mount_point = String::new();
2261        Ok(())
2262    }
2263    
2264    fn name(&self) -> &str {
2265        self.name
2266    }
2267}
2268
2269#[cfg(test)]
2270mod tests;
2271
2272#[cfg(test)]
2273pub mod testfs;