kernel/fs/vfs_v2/drivers/fat32/
mod.rs

1//! FAT32 Filesystem Implementation
2//!
3//! This module implements a FAT32 filesystem driver for the VFS v2 architecture.
4//! It provides support for reading and writing FAT32 filesystems on block devices,
5//! particularly designed to work with virtio-blk devices.
6//!
7//! ## Features
8//!
9//! - Full FAT32 filesystem support
10//! - Read and write operations
11//! - Directory navigation
12//! - File creation, deletion, and modification
13//! - Integration with VFS v2 architecture
14//! - Block device compatibility
15//!
16//! ## Architecture
17//!
18//! The FAT32 implementation consists of:
19//! - `Fat32FileSystem`: Main filesystem implementation
20//! - `Fat32Node`: VFS node implementation for files and directories
21//! - `Fat32Driver`: Filesystem driver for registration
22//! - Data structures for FAT32 format (boot sector, directory entries, etc.)
23
24use alloc::{
25    boxed::Box,
26    collections::BTreeMap,
27    format,
28    string::{String, ToString},
29    sync::Arc,
30    vec,
31    vec::Vec,
32};
33use core::{any::Any, fmt::Debug, mem};
34use spin::{Mutex, rwlock::RwLock};
35
36use crate::{
37    device::block::BlockDevice,
38    driver_initcall,
39    fs::{FileObject, FileSystemError, FileSystemErrorKind, FileType, get_fs_driver_manager},
40};
41
42use super::super::core::{DirectoryEntryInternal, FileSystemId, FileSystemOperations, VfsNode};
43
44pub mod driver;
45pub mod node;
46pub mod structures;
47
48#[cfg(test)]
49pub mod tests;
50
51pub use driver::Fat32Driver;
52pub use node::{Fat32DirectoryObject, Fat32FileObject, Fat32Node};
53pub use structures::*;
54
55/// FAT32 Filesystem implementation
56///
57/// This struct implements a FAT32 filesystem that can be mounted on block devices.
58/// It maintains the block device reference and provides filesystem operations
59/// through the VFS v2 interface.
60pub struct Fat32FileSystem {
61    /// Unique filesystem identifier
62    fs_id: FileSystemId,
63    /// Reference to the underlying block device
64    block_device: Arc<dyn BlockDevice>,
65    /// Boot sector information
66    boot_sector: Fat32BootSector,
67    /// Root directory cluster
68    root_cluster: u32,
69    /// Sectors per cluster
70    sectors_per_cluster: u32,
71    /// Bytes per sector
72    bytes_per_sector: u32,
73    /// Root directory node
74    root: RwLock<Arc<Fat32Node>>,
75    /// Filesystem name
76    name: String,
77    /// Next file ID generator
78    next_file_id: Mutex<u64>,
79    /// Cached FAT table entries
80    fat_cache: Mutex<BTreeMap<u32, u32>>,
81}
82
83impl Debug for Fat32FileSystem {
84    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
85        f.debug_struct("Fat32FileSystem")
86            .field("name", &self.name)
87            .field("root_cluster", &self.root_cluster)
88            .field("sectors_per_cluster", &self.sectors_per_cluster)
89            .field("bytes_per_sector", &self.bytes_per_sector)
90            .finish()
91    }
92}
93
94impl Fat32FileSystem {
95    /// Create a new FAT32 filesystem from a block device
96    pub fn new(block_device: Arc<dyn BlockDevice>) -> Result<Arc<Self>, FileSystemError> {
97        // Read boot sector
98        let boot_sector = Self::read_boot_sector(&*block_device)?;
99
100        // Validate FAT32 filesystem
101        Self::validate_fat32(&boot_sector)?;
102
103        // Calculate filesystem parameters
104        let sectors_per_cluster = boot_sector.sectors_per_cluster as u32;
105        let bytes_per_sector = boot_sector.bytes_per_sector as u32;
106        let root_cluster = boot_sector.root_cluster;
107
108        // Create root directory node
109        let root = Arc::new(Fat32Node::new_directory("/".to_string(), 1, root_cluster));
110
111        let fs = Arc::new(Self {
112            fs_id: FileSystemId::new(),
113            block_device,
114            boot_sector,
115            root_cluster,
116            sectors_per_cluster,
117            bytes_per_sector,
118            root: RwLock::new(Arc::clone(&root)),
119            name: "fat32".to_string(),
120            next_file_id: Mutex::new(2), // Start from 2, root is 1
121            fat_cache: Mutex::new(BTreeMap::new()),
122        });
123
124        // Set filesystem reference in root node
125        let fs_weak = Arc::downgrade(&(fs.clone() as Arc<dyn FileSystemOperations>));
126        root.set_filesystem(fs_weak);
127
128        Ok(fs)
129    }
130
131    /// Read boot sector from block device
132    fn read_boot_sector(
133        block_device: &dyn BlockDevice,
134    ) -> Result<Fat32BootSector, FileSystemError> {
135        // Create read request for sector 0 (boot sector)
136        let request = Box::new(crate::device::block::request::BlockIORequest {
137            request_type: crate::device::block::request::BlockIORequestType::Read,
138            sector: 0,
139            sector_count: 1,
140            head: 0,
141            cylinder: 0,
142            buffer: vec![0u8; 512], // Boot sector is always 512 bytes
143        });
144
145        block_device.enqueue_request(request);
146        let results = block_device.process_requests();
147
148        if let Some(result) = results.first() {
149            match &result.result {
150                Ok(_) => {
151                    // Parse boot sector
152                    if result.request.buffer.len() < mem::size_of::<Fat32BootSector>() {
153                        return Err(FileSystemError::new(
154                            FileSystemErrorKind::IoError,
155                            "Boot sector read incomplete",
156                        ));
157                    }
158
159                    // Convert bytes to boot sector structure
160                    let boot_sector = unsafe {
161                        core::ptr::read(result.request.buffer.as_ptr() as *const Fat32BootSector)
162                    };
163
164                    Ok(boot_sector)
165                }
166                Err(e) => Err(FileSystemError::new(
167                    FileSystemErrorKind::IoError,
168                    format!("Failed to read boot sector: {}", e),
169                )),
170            }
171        } else {
172            Err(FileSystemError::new(
173                FileSystemErrorKind::IoError,
174                "No result from block device",
175            ))
176        }
177    }
178
179    /// Validate that this is a FAT32 filesystem
180    fn validate_fat32(boot_sector: &Fat32BootSector) -> Result<(), FileSystemError> {
181        // Check signature
182        if boot_sector.signature != 0xAA55 {
183            return Err(FileSystemError::new(
184                FileSystemErrorKind::InvalidData,
185                "Invalid boot sector signature",
186            ));
187        }
188
189        // Check bytes per sector (must be 512, 1024, 2048, or 4096)
190        match boot_sector.bytes_per_sector {
191            512 | 1024 | 2048 | 4096 => {}
192            _ => {
193                return Err(FileSystemError::new(
194                    FileSystemErrorKind::InvalidData,
195                    "Invalid bytes per sector",
196                ));
197            }
198        }
199
200        // Check sectors per cluster (must be power of 2)
201        if boot_sector.sectors_per_cluster == 0
202            || (boot_sector.sectors_per_cluster & (boot_sector.sectors_per_cluster - 1)) != 0
203        {
204            return Err(FileSystemError::new(
205                FileSystemErrorKind::InvalidData,
206                "Invalid sectors per cluster",
207            ));
208        }
209
210        Ok(())
211    }
212
213    /// Lookup a specific file in a directory cluster
214    fn lookup_file_in_directory(
215        &self,
216        cluster: u32,
217        target_name: &str,
218    ) -> Result<Fat32DirectoryEntryInternal, FileSystemError> {
219        let mut current_cluster = cluster;
220
221        loop {
222            // Read the current cluster
223            let cluster_data = self.read_cluster_data(current_cluster)?;
224
225            // Parse directory entries in this cluster
226            let entries_per_cluster = (self.sectors_per_cluster * self.bytes_per_sector) / 32;
227            let mut lfn_parts: Vec<String> = Vec::new(); // Collect LFN parts in order
228
229            for i in 0..entries_per_cluster {
230                let offset = (i * 32) as usize;
231                if offset + 32 > cluster_data.len() {
232                    break;
233                }
234
235                let entry_bytes = &cluster_data[offset..offset + 32];
236
237                // Safety: We know the slice is exactly 32 bytes (size of Fat32DirectoryEntry)
238                let dir_entry = unsafe {
239                    core::ptr::read(entry_bytes.as_ptr() as *const structures::Fat32DirectoryEntry)
240                };
241
242                // Skip free entries
243                if dir_entry.is_free() {
244                    lfn_parts.clear(); // Reset LFN accumulation
245                    continue;
246                }
247
248                // Handle LFN entries
249                if dir_entry.is_long_filename() {
250                    // Cast to LFN entry
251                    let lfn_entry =
252                        unsafe { &*(entry_bytes.as_ptr() as *const structures::Fat32LFNEntry) };
253
254                    // Extract characters from this LFN entry
255                    let chars = lfn_entry.extract_chars();
256
257                    // Convert UTF-16 to UTF-8
258                    let mut part = String::new();
259                    for &ch in &chars {
260                        if ch == 0 || ch == 0xFFFF {
261                            break; // End of string or padding
262                        }
263                        if let Some(c) = char::from_u32(ch as u32) {
264                            part.push(c);
265                        }
266                    }
267
268                    // LFN entries are stored with highest sequence number first
269                    if lfn_entry.is_last_lfn() {
270                        lfn_parts.clear(); // Start fresh for new LFN sequence
271                        lfn_parts.push(part); // Add this part to the end
272                    } else {
273                        // Add at the end, we'll reverse the entire collection later
274                        lfn_parts.push(part);
275                    }
276                    continue;
277                }
278
279                // Skip dot entries
280                if dir_entry.name[0] == b'.' {
281                    lfn_parts.clear();
282                    continue;
283                }
284
285                // Create internal entry
286                let mut internal_entry = Fat32DirectoryEntryInternal::from_raw(dir_entry);
287
288                // Assemble complete LFN if available
289                if !lfn_parts.is_empty() {
290                    // Reverse the parts since LFN entries are stored in reverse order
291                    lfn_parts.reverse();
292                    let long_filename = lfn_parts.join("");
293                    internal_entry.set_long_filename(long_filename);
294                }
295
296                let filename = internal_entry.name();
297
298                // FAT32 is case-insensitive, so compare in uppercase
299                if filename.to_uppercase() == target_name.to_uppercase() {
300                    return Ok(internal_entry);
301                }
302
303                // Clear LFN for next entry
304                lfn_parts.clear();
305            }
306
307            // Get next cluster in the chain
308            let next_cluster = self.read_fat_entry(current_cluster)?;
309            if next_cluster >= 0x0FFFFFF8 {
310                // End of cluster chain
311                break;
312            }
313            current_cluster = next_cluster;
314        }
315
316        Err(FileSystemError::new(
317            FileSystemErrorKind::NotFound,
318            &format!("File '{}' not found", target_name),
319        ))
320    }
321
322    /// Read complete cluster data
323    fn read_cluster_data(&self, cluster: u32) -> Result<Vec<u8>, FileSystemError> {
324        let cluster_size = (self.sectors_per_cluster * self.bytes_per_sector) as usize;
325        let cluster_sector = self.cluster_to_sector(cluster);
326
327        // Batch read all sectors in the cluster
328        let mut requests = Vec::new();
329        for i in 0..self.sectors_per_cluster {
330            let request = Box::new(crate::device::block::request::BlockIORequest {
331                request_type: crate::device::block::request::BlockIORequestType::Read,
332                sector: (cluster_sector + i) as usize,
333                sector_count: 1,
334                head: 0,
335                cylinder: 0,
336                buffer: vec![0u8; self.bytes_per_sector as usize],
337            });
338
339            self.block_device.enqueue_request(request);
340            requests.push(());
341        }
342
343        // Process all requests in batch
344        let results = self.block_device.process_requests();
345
346        if results.len() != requests.len() {
347            return Err(FileSystemError::new(
348                FileSystemErrorKind::IoError,
349                format!("Expected {} results, got {}", requests.len(), results.len()),
350            ));
351        }
352
353        // Assemble cluster data from results
354        let mut cluster_data = vec![0u8; cluster_size];
355        for (i, result) in results.iter().enumerate() {
356            match &result.result {
357                Ok(_) => {
358                    let start_offset = i * self.bytes_per_sector as usize;
359                    let end_offset = start_offset + self.bytes_per_sector as usize;
360                    cluster_data[start_offset..end_offset].copy_from_slice(&result.request.buffer);
361                }
362                Err(e) => {
363                    return Err(FileSystemError::new(
364                        FileSystemErrorKind::IoError,
365                        format!("Failed to read cluster sector {}: {}", i, e),
366                    ));
367                }
368            }
369        }
370
371        Ok(cluster_data)
372    }
373
374    /// Generate next unique file ID
375    fn generate_file_id(&self) -> u64 {
376        let mut next_id = self.next_file_id.lock();
377        let id = *next_id;
378        *next_id += 1;
379        id
380    }
381
382    /// Read cluster data from the block device
383    fn read_cluster(&self, cluster: u32) -> Result<Vec<u8>, FileSystemError> {
384        if cluster < 2 {
385            return Err(FileSystemError::new(
386                FileSystemErrorKind::InvalidData,
387                "Invalid cluster number",
388            ));
389        }
390
391        // Calculate sector number for this cluster
392        let first_data_sector = self.boot_sector.reserved_sectors as u32
393            + (self.boot_sector.fat_count as u32 * self.boot_sector.sectors_per_fat);
394        let cluster_sector = first_data_sector + (cluster - 2) * self.sectors_per_cluster;
395
396        // Read cluster data
397        let cluster_size = (self.sectors_per_cluster * self.bytes_per_sector) as usize;
398        let mut buffer = vec![0u8; cluster_size];
399
400        // Read all sectors of the cluster
401        for i in 0..self.sectors_per_cluster {
402            let sector_buffer = vec![0u8; self.bytes_per_sector as usize];
403            let request = Box::new(crate::device::block::request::BlockIORequest {
404                request_type: crate::device::block::request::BlockIORequestType::Read,
405                sector: (cluster_sector + i) as usize,
406                sector_count: 1,
407                head: 0,
408                cylinder: 0,
409                buffer: sector_buffer,
410            });
411
412            self.block_device.enqueue_request(request);
413            let results = self.block_device.process_requests();
414
415            if let Some(result) = results.first() {
416                match &result.result {
417                    Ok(_) => {
418                        let start_offset = (i * self.bytes_per_sector) as usize;
419                        let end_offset = start_offset + self.bytes_per_sector as usize;
420                        if end_offset <= buffer.len()
421                            && result.request.buffer.len() >= self.bytes_per_sector as usize
422                        {
423                            buffer[start_offset..end_offset].copy_from_slice(
424                                &result.request.buffer[..self.bytes_per_sector as usize],
425                            );
426                        }
427                    }
428                    Err(e) => {
429                        return Err(FileSystemError::new(
430                            FileSystemErrorKind::IoError,
431                            format!(
432                                "Failed to read cluster {} sector {}: {}",
433                                cluster,
434                                cluster_sector + i,
435                                e
436                            ),
437                        ));
438                    }
439                }
440            } else {
441                return Err(FileSystemError::new(
442                    FileSystemErrorKind::IoError,
443                    format!(
444                        "No result from block device for cluster {} sector {}",
445                        cluster,
446                        cluster_sector + i
447                    ),
448                ));
449            }
450        }
451
452        Ok(buffer)
453    }
454
455    /// Read FAT entry for a given cluster
456    fn read_fat_entry(&self, cluster: u32) -> Result<u32, FileSystemError> {
457        // Check for cached entry first
458        {
459            let cache = self.fat_cache.lock();
460            if let Some(&entry) = cache.get(&cluster) {
461                return Ok(entry);
462            }
463        }
464
465        // Calculate FAT offset and sector
466        let fat_offset = cluster * 4; // FAT32 uses 4 bytes per entry
467        let fat_sector =
468            self.boot_sector.reserved_sectors as u32 + (fat_offset / self.bytes_per_sector);
469        let sector_offset = (fat_offset % self.bytes_per_sector) as usize;
470
471        // Read FAT sector
472        let request = Box::new(crate::device::block::request::BlockIORequest {
473            request_type: crate::device::block::request::BlockIORequestType::Read,
474            sector: fat_sector as usize,
475            sector_count: 1,
476            head: 0,
477            cylinder: 0,
478            buffer: vec![0u8; self.bytes_per_sector as usize],
479        });
480
481        self.block_device.enqueue_request(request);
482        let results = self.block_device.process_requests();
483
484        if let Some(result) = results.first() {
485            match &result.result {
486                Ok(_) => {
487                    // Extract 32-bit FAT entry (only lower 28 bits are used in FAT32)
488                    if sector_offset + 4 > result.request.buffer.len() {
489                        return Err(FileSystemError::new(
490                            FileSystemErrorKind::IoError,
491                            "FAT entry spans sector boundary",
492                        ));
493                    }
494
495                    let fat_entry = u32::from_le_bytes([
496                        result.request.buffer[sector_offset],
497                        result.request.buffer[sector_offset + 1],
498                        result.request.buffer[sector_offset + 2],
499                        result.request.buffer[sector_offset + 3],
500                    ]) & 0x0FFFFFFF; // Mask to 28 bits for FAT32
501
502                    // Cache the entry
503                    {
504                        let mut cache = self.fat_cache.lock();
505                        cache.insert(cluster, fat_entry);
506                    }
507
508                    Ok(fat_entry)
509                }
510                Err(e) => Err(FileSystemError::new(
511                    FileSystemErrorKind::IoError,
512                    format!("Failed to read FAT sector: {}", e),
513                )),
514            }
515        } else {
516            Err(FileSystemError::new(
517                FileSystemErrorKind::IoError,
518                "No result from block device",
519            ))
520        }
521    }
522
523    /// Write FAT entry for a given cluster
524    fn write_fat_entry(&self, cluster: u32, value: u32) -> Result<(), FileSystemError> {
525        // Calculate FAT offset and sector
526        let fat_offset = cluster * 4; // FAT32 uses 4 bytes per entry
527        let fat_sector =
528            self.boot_sector.reserved_sectors as u32 + (fat_offset / self.bytes_per_sector);
529        let sector_offset = (fat_offset % self.bytes_per_sector) as usize;
530
531        // FAT32 has two copies of the FAT table, update both
532        for fat_copy in 0..self.boot_sector.fat_count {
533            let current_fat_sector =
534                fat_sector + (fat_copy as u32 * self.boot_sector.sectors_per_fat);
535
536            // Read current FAT sector
537            let request = Box::new(crate::device::block::request::BlockIORequest {
538                request_type: crate::device::block::request::BlockIORequestType::Read,
539                sector: current_fat_sector as usize,
540                sector_count: 1,
541                head: 0,
542                cylinder: 0,
543                buffer: vec![0u8; self.bytes_per_sector as usize],
544            });
545
546            self.block_device.enqueue_request(request);
547            let results = self.block_device.process_requests();
548
549            let mut sector_buffer = if let Some(result) = results.first() {
550                match &result.result {
551                    Ok(_) => result.request.buffer.clone(),
552                    Err(e) => {
553                        return Err(FileSystemError::new(
554                            FileSystemErrorKind::IoError,
555                            format!("Failed to read FAT sector: {}", e),
556                        ));
557                    }
558                }
559            } else {
560                return Err(FileSystemError::new(
561                    FileSystemErrorKind::IoError,
562                    "No result from block device",
563                ));
564            };
565
566            // Update FAT entry (preserve upper 4 bits, update lower 28 bits)
567            if sector_offset + 4 > sector_buffer.len() {
568                return Err(FileSystemError::new(
569                    FileSystemErrorKind::IoError,
570                    "FAT entry spans sector boundary",
571                ));
572            }
573
574            let current_entry = u32::from_le_bytes([
575                sector_buffer[sector_offset],
576                sector_buffer[sector_offset + 1],
577                sector_buffer[sector_offset + 2],
578                sector_buffer[sector_offset + 3],
579            ]);
580
581            let new_entry = (current_entry & 0xF0000000) | (value & 0x0FFFFFFF);
582            let new_bytes = new_entry.to_le_bytes();
583
584            sector_buffer[sector_offset..sector_offset + 4].copy_from_slice(&new_bytes);
585
586            // Write updated sector back
587            let write_request = Box::new(crate::device::block::request::BlockIORequest {
588                request_type: crate::device::block::request::BlockIORequestType::Write,
589                sector: current_fat_sector as usize,
590                sector_count: 1,
591                head: 0,
592                cylinder: 0,
593                buffer: sector_buffer,
594            });
595
596            self.block_device.enqueue_request(write_request);
597            let write_results = self.block_device.process_requests();
598
599            if let Some(result) = write_results.first() {
600                match &result.result {
601                    Ok(_) => {
602                        // Successfully wrote this FAT copy
603                    }
604                    Err(e) => {
605                        return Err(FileSystemError::new(
606                            FileSystemErrorKind::IoError,
607                            format!("Failed to write FAT sector: {}", e),
608                        ));
609                    }
610                }
611            } else {
612                return Err(FileSystemError::new(
613                    FileSystemErrorKind::IoError,
614                    "No result from block device for write",
615                ));
616            }
617        }
618
619        // Update cache after successfully writing all FAT copies
620        {
621            let mut cache = self.fat_cache.lock();
622            cache.insert(cluster, value);
623        }
624
625        Ok(())
626    }
627
628    /// Read file content by following cluster chain
629    pub fn read_file_content(
630        &self,
631        start_cluster: u32,
632        size: usize,
633    ) -> Result<Vec<u8>, FileSystemError> {
634        #[cfg(test)]
635        {
636            // use crate::early_println;
637            // early_println!("[FAT32] read_file_content: start_cluster={}, size={}", start_cluster, size);
638        }
639
640        if start_cluster < 2 {
641            return Ok(Vec::new()); // Empty file
642        }
643
644        let mut content = Vec::new();
645        let mut current_cluster = start_cluster;
646        let cluster_size = (self.sectors_per_cluster * self.bytes_per_sector) as usize;
647
648        loop {
649            // #[cfg(test)]
650            // {
651            //     use crate::early_println;
652            //     early_println!("[FAT32] reading cluster {}", current_cluster);
653            // }
654
655            // Read current cluster
656            let cluster_data = self.read_cluster(current_cluster)?;
657
658            // #[cfg(test)]
659            // {
660            //     use crate::early_println;
661            //     early_println!("[FAT32] read cluster {} data: {} bytes, first 8 bytes: {:?}",
662            //         current_cluster, cluster_data.len(),
663            //         &cluster_data[..core::cmp::min(8, cluster_data.len())]);
664            // }
665
666            // Add data to content (up to requested size)
667            let remaining_size = size.saturating_sub(content.len());
668            if remaining_size == 0 {
669                break;
670            }
671
672            let bytes_to_copy = core::cmp::min(cluster_data.len(), remaining_size);
673            content.extend_from_slice(&cluster_data[..bytes_to_copy]);
674
675            // Check if we've read enough
676            if content.len() >= size {
677                break;
678            }
679
680            // Get next cluster from FAT
681            let fat_entry = self.read_fat_entry(current_cluster)?;
682
683            // Check for end of chain
684            if fat_entry >= 0x0FFFFFF8 {
685                break; // End of file
686            }
687
688            current_cluster = fat_entry;
689        }
690
691        // Truncate to exact size if needed
692        content.truncate(size);
693        Ok(content)
694    }
695
696    /// Read a single page (4096 bytes) of file content into physical memory.
697    ///
698    /// This is used by the page cache manager for demand paging.
699    pub fn read_page_content(
700        &self,
701        start_cluster: u32,
702        page_index: u64,
703        paddr: usize,
704    ) -> Result<(), FileSystemError> {
705        use crate::environment::PAGE_SIZE;
706
707        if start_cluster < 2 {
708            unsafe {
709                core::ptr::write_bytes(paddr as *mut u8, 0, PAGE_SIZE);
710            }
711            return Ok(());
712        }
713
714        let cluster_size = (self.sectors_per_cluster * self.bytes_per_sector) as usize;
715        let page_offset = page_index as usize * PAGE_SIZE;
716
717        let start_cluster_index = page_offset / cluster_size;
718        let offset_in_cluster = page_offset % cluster_size;
719
720        unsafe {
721            core::ptr::write_bytes(paddr as *mut u8, 0, PAGE_SIZE);
722        }
723
724        let mut current_cluster = start_cluster;
725        for _ in 0..start_cluster_index {
726            let fat_entry = self.read_fat_entry(current_cluster)?;
727            if fat_entry >= 0x0FFFFFF8 {
728                return Ok(());
729            }
730            current_cluster = fat_entry;
731        }
732
733        let mut page_ptr = paddr as *mut u8;
734        let mut bytes_written = 0usize;
735        let mut cluster_offset = offset_in_cluster;
736
737        while bytes_written < PAGE_SIZE {
738            let cluster_data = self.read_cluster(current_cluster)?;
739
740            let bytes_to_copy = core::cmp::min(
741                cluster_data.len() - cluster_offset,
742                PAGE_SIZE - bytes_written,
743            );
744
745            unsafe {
746                core::ptr::copy_nonoverlapping(
747                    cluster_data.as_ptr().add(cluster_offset),
748                    page_ptr,
749                    bytes_to_copy,
750                );
751                page_ptr = page_ptr.add(bytes_to_copy);
752            }
753
754            bytes_written += bytes_to_copy;
755            cluster_offset = 0;
756
757            if bytes_written >= PAGE_SIZE {
758                break;
759            }
760
761            let fat_entry = self.read_fat_entry(current_cluster)?;
762            if fat_entry >= 0x0FFFFFF8 {
763                break;
764            }
765            current_cluster = fat_entry;
766        }
767
768        Ok(())
769    }
770
771    /// Write file content to disk and return the starting cluster
772    pub fn write_file_content(
773        &self,
774        current_cluster: u32,
775        content: &[u8],
776    ) -> Result<u32, FileSystemError> {
777        // Debug output for large file operations
778        // #[cfg(test)]
779        // {
780        //     use crate::early_println;
781        //     early_println!("[FAT32] write_file_content: cluster={}, content_len={}", current_cluster, content.len());
782        // }
783
784        // If content is empty, free the cluster chain
785        if content.is_empty() {
786            if current_cluster != 0 {
787                self.free_cluster_chain(current_cluster)?;
788            }
789            return Ok(0);
790        }
791
792        let cluster_size = (self.sectors_per_cluster * self.bytes_per_sector) as usize;
793        let clusters_needed = (content.len() + cluster_size - 1) / cluster_size;
794
795        // Debug output for allocation
796        // #[cfg(test)]
797        // {
798        //     use crate::early_println;
799        //     early_println!("[FAT32] clusters_needed={}, cluster_size={}", clusters_needed, cluster_size);
800        // }
801
802        // Free existing chain if we're overwriting
803        if current_cluster != 0 {
804            // #[cfg(test)]
805            // {
806            //     use crate::early_println;
807            //     early_println!("[FAT32] freeing existing cluster chain starting from cluster {}", current_cluster);
808            // }
809            self.free_cluster_chain(current_cluster)?;
810            // #[cfg(test)]
811            // {
812            //     use crate::early_println;
813            //     early_println!("[FAT32] finished freeing cluster chain");
814            // }
815        }
816
817        // Allocate new cluster chain
818        let mut clusters = Vec::new();
819        for cluster_index in 0..clusters_needed {
820            // #[cfg(test)]
821            // {
822            //     use crate::early_println;
823            //     early_println!("[FAT32] allocating cluster {} of {}", cluster_index + 1, clusters_needed);
824            // }
825            match self.allocate_cluster() {
826                Ok(new_cluster) => {
827                    // #[cfg(test)]
828                    // {
829                    //     use crate::early_println;
830                    //     // early_println!("[FAT32] allocated cluster: {}", new_cluster);
831                    // }
832                    clusters.push(new_cluster);
833                }
834                Err(e) => {
835                    #[cfg(test)]
836                    {
837                        use crate::early_println;
838                        early_println!(
839                            "[FAT32] failed to allocate cluster {} of {}: {:?}",
840                            cluster_index + 1,
841                            clusters_needed,
842                            e
843                        );
844                    }
845                    return Err(e);
846                }
847            }
848        }
849
850        // Chain the clusters together in FAT
851        // #[cfg(test)]
852        // {
853        //     use crate::early_println;
854        //     early_println!("[FAT32] setting up FAT chain for {} clusters", clusters.len());
855        // }
856        for i in 0..clusters.len() - 1 {
857            // #[cfg(test)]
858            // {
859            //     use crate::early_println;
860            //     early_println!("[FAT32] setting FAT entry: cluster {} -> {}", clusters[i], clusters[i + 1]);
861            // }
862            self.write_fat_entry(clusters[i], clusters[i + 1])?;
863        }
864        // Mark the last cluster as end of chain
865        if !clusters.is_empty() {
866            // #[cfg(test)]
867            // {
868            //     use crate::early_println;
869            //     early_println!("[FAT32] marking last cluster {} as end of chain", clusters[clusters.len() - 1]);
870            // }
871            self.write_fat_entry(clusters[clusters.len() - 1], 0x0FFFFFFF)?; // End of chain marker
872        }
873
874        // Write content to clusters
875        // #[cfg(test)]
876        // {
877        //     use crate::early_println;
878        //     early_println!("[FAT32] writing content to {} clusters", clusters.len());
879        // }
880        for (i, &cluster) in clusters.iter().enumerate() {
881            let start_offset = i * cluster_size;
882            let end_offset = core::cmp::min(start_offset + cluster_size, content.len());
883
884            if start_offset < content.len() {
885                let chunk = &content[start_offset..end_offset];
886
887                // #[cfg(test)]
888                // {
889                //     use crate::early_println;
890                //     early_println!("[FAT32] writing cluster {}: {} bytes (offset {}..{})", cluster, chunk.len(), start_offset, end_offset);
891                // }
892
893                self.write_cluster_data(cluster, chunk)?;
894            }
895        }
896
897        // #[cfg(test)]
898        // {
899        //     use crate::early_println;
900        //     early_println!("[FAT32] write_file_content completed, start_cluster={}", clusters.first().copied().unwrap_or(0));
901        // }
902
903        Ok(clusters.first().copied().unwrap_or(0))
904    }
905
906    /// Read FAT entry directly from disk without caching
907    fn read_fat_entry_direct(&self, cluster: u32) -> Result<u32, FileSystemError> {
908        // #[cfg(test)]
909        // {
910        //     use crate::early_println;
911        //     early_println!("[FAT32] reading FAT entry for cluster {} directly from disk", cluster);
912        // }
913
914        // Calculate FAT sector and offset
915        let fat_offset = cluster * 4; // 4 bytes per FAT32 entry
916        let fat_sector =
917            self.boot_sector.reserved_sectors as u32 + (fat_offset / self.bytes_per_sector);
918        let entry_offset = (fat_offset % self.bytes_per_sector) as usize;
919
920        // #[cfg(test)]
921        // {
922        //     use crate::early_println;
923        //     early_println!("[FAT32] fat_sector={}, entry_offset={}", fat_sector, entry_offset);
924        // }
925
926        // Read FAT sector
927        let buffer = vec![0u8; self.bytes_per_sector as usize];
928        let request = Box::new(crate::device::block::request::BlockIORequest {
929            request_type: crate::device::block::request::BlockIORequestType::Read,
930            sector: fat_sector as usize,
931            sector_count: 1,
932            head: 0,
933            cylinder: 0,
934            buffer,
935        });
936
937        // #[cfg(test)]
938        // {
939        //     use crate::early_println;
940        //     early_println!("[FAT32] enqueuing FAT read request for sector {}", fat_sector);
941        // }
942
943        self.block_device.enqueue_request(request);
944        let results = self.block_device.process_requests();
945
946        // #[cfg(test)]
947        // {
948        //     use crate::early_println;
949        //     early_println!("[FAT32] FAT read request completed, results.len()={}", results.len());
950        // }
951
952        if results.is_empty() || results[0].result.is_err() {
953            return Err(FileSystemError::new(
954                FileSystemErrorKind::IoError,
955                "Failed to read FAT sector",
956            ));
957        }
958
959        // Get the buffer back from the result
960        let buffer = &results[0].request.buffer;
961
962        // Extract FAT entry (little-endian, mask off top 4 bits for FAT32)
963        let entry = u32::from_le_bytes([
964            buffer[entry_offset],
965            buffer[entry_offset + 1],
966            buffer[entry_offset + 2],
967            buffer[entry_offset + 3],
968        ]) & 0x0FFFFFFF;
969
970        // #[cfg(test)]
971        // {
972        //     use crate::early_println;
973        //     early_println!("[FAT32] read FAT entry for cluster {}: {:#x}", cluster, entry);
974        // }
975
976        Ok(entry)
977    }
978
979    /// Allocate a free cluster from the FAT and mark it as allocated
980    fn allocate_cluster(&self) -> Result<u32, FileSystemError> {
981        // #[cfg(test)]
982        // {
983        //     use crate::early_println;
984        //     early_println!("[FAT32] searching for free cluster...");
985        // }
986
987        // Simple allocation: find first free cluster starting from cluster 2
988        for cluster in 2..100 {
989            // Reduced search range for faster debugging
990            // #[cfg(test)]
991            // {
992            //     use crate::early_println;
993            //     if cluster <= 10 {
994            //         early_println!("[FAT32] checking cluster {}", cluster);
995            //     }
996            // }
997
998            // Read FAT entry directly without caching to avoid stale cache issues
999            let fat_entry = self.read_fat_entry_direct(cluster)?;
1000
1001            // #[cfg(test)]
1002            // {
1003            //     use crate::early_println;
1004            //     if cluster <= 20 || fat_entry == 0 {
1005            //         early_println!("[FAT32] cluster {} has FAT entry: {:#x}", cluster, fat_entry);
1006            //     }
1007            // }
1008
1009            if fat_entry == 0 {
1010                // #[cfg(test)]
1011                // {
1012                //     use crate::early_println;
1013                //     early_println!("[FAT32] ✓ found free cluster: {}", cluster);
1014                // }
1015                // Mark as allocated immediately to prevent duplicate allocation
1016                self.write_fat_entry(cluster, 0x0FFFFFFF)?; // End of chain marker (will be updated later if part of chain)
1017
1018                // Update FS Info sector
1019                self.update_fs_info_allocated_cluster(cluster)?;
1020
1021                // #[cfg(test)]
1022                // {
1023                //     use crate::early_println;
1024                //     early_println!("[FAT32] ✓ allocated cluster: {}", cluster);
1025                // }
1026                return Ok(cluster);
1027            }
1028        }
1029
1030        Err(FileSystemError::new(
1031            FileSystemErrorKind::NoSpace,
1032            "No free clusters available",
1033        ))
1034    }
1035
1036    /// Initialize a new directory cluster with . and .. entries
1037    fn initialize_directory(
1038        &self,
1039        dir_cluster: u32,
1040        parent_cluster: u32,
1041    ) -> Result<(), FileSystemError> {
1042        use crate::fs::vfs_v2::drivers::fat32::structures::Fat32DirectoryEntry;
1043
1044        // Calculate LBA for the directory cluster
1045        let first_data_sector = self.boot_sector.reserved_sectors as u32
1046            + (self.boot_sector.fat_count as u32 * self.boot_sector.sectors_per_fat);
1047        let lba = first_data_sector + (dir_cluster - 2) * self.sectors_per_cluster;
1048
1049        // Clear the directory cluster first
1050        let cluster_size = (self.sectors_per_cluster * self.bytes_per_sector) as usize;
1051        let zero_data = vec![0u8; cluster_size];
1052
1053        for sector_offset in 0..self.sectors_per_cluster {
1054            let sector_lba = lba + sector_offset as u32;
1055            let sector_data = &zero_data[(sector_offset as usize * self.bytes_per_sector as usize)
1056                ..((sector_offset as usize + 1) * self.bytes_per_sector as usize)];
1057
1058            let request = Box::new(crate::device::block::request::BlockIORequest {
1059                request_type: crate::device::block::request::BlockIORequestType::Write,
1060                sector: sector_lba as usize,
1061                sector_count: 1,
1062                head: 0,
1063                cylinder: 0,
1064                buffer: sector_data.to_vec(),
1065            });
1066
1067            self.block_device.enqueue_request(request);
1068        }
1069        self.block_device.process_requests();
1070
1071        // Create . (current directory) entry
1072        let dot_entry = Fat32DirectoryEntry {
1073            name: [
1074                b'.', b' ', b' ', b' ', b' ', b' ', b' ', b' ', b' ', b' ', b' ',
1075            ],
1076            attributes: 0x10, // Directory attribute
1077            nt_reserved: 0,
1078            creation_time_tenths: 0,
1079            creation_time: 0,
1080            creation_date: 0,
1081            last_access_date: 0,
1082            cluster_high: ((dir_cluster >> 16) & 0xFFFF) as u16,
1083            modification_time: 0,
1084            modification_date: 0,
1085            cluster_low: (dir_cluster & 0xFFFF) as u16,
1086            file_size: 0,
1087        };
1088
1089        // Create .. (parent directory) entry
1090        // For FAT32 root directory children, '..' should point to cluster 0
1091        let actual_parent = if parent_cluster == self.root_cluster {
1092            0
1093        } else {
1094            parent_cluster
1095        };
1096        let dotdot_entry = Fat32DirectoryEntry {
1097            name: [
1098                b'.', b'.', b' ', b' ', b' ', b' ', b' ', b' ', b' ', b' ', b' ',
1099            ],
1100            attributes: 0x10, // Directory attribute
1101            nt_reserved: 0,
1102            creation_time_tenths: 0,
1103            creation_time: 0,
1104            creation_date: 0,
1105            last_access_date: 0,
1106            cluster_high: ((actual_parent >> 16) & 0xFFFF) as u16,
1107            modification_time: 0,
1108            modification_date: 0,
1109            cluster_low: (actual_parent & 0xFFFF) as u16,
1110            file_size: 0,
1111        };
1112
1113        // Write both entries to the beginning of the directory cluster
1114        let mut entry_data = Vec::new();
1115
1116        // Serialize . entry (32 bytes)
1117        entry_data.extend_from_slice(&dot_entry.name);
1118        entry_data.push(dot_entry.attributes);
1119        entry_data.push(dot_entry.nt_reserved);
1120        entry_data.push(dot_entry.creation_time_tenths);
1121        entry_data.extend_from_slice(&dot_entry.creation_time.to_le_bytes());
1122        entry_data.extend_from_slice(&dot_entry.creation_date.to_le_bytes());
1123        entry_data.extend_from_slice(&dot_entry.last_access_date.to_le_bytes());
1124        entry_data.extend_from_slice(&dot_entry.cluster_high.to_le_bytes());
1125        entry_data.extend_from_slice(&dot_entry.modification_time.to_le_bytes());
1126        entry_data.extend_from_slice(&dot_entry.modification_date.to_le_bytes());
1127        entry_data.extend_from_slice(&dot_entry.cluster_low.to_le_bytes());
1128        entry_data.extend_from_slice(&dot_entry.file_size.to_le_bytes());
1129
1130        // Serialize .. entry (32 bytes)
1131        entry_data.extend_from_slice(&dotdot_entry.name);
1132        entry_data.push(dotdot_entry.attributes);
1133        entry_data.push(dotdot_entry.nt_reserved);
1134        entry_data.push(dotdot_entry.creation_time_tenths);
1135        entry_data.extend_from_slice(&dotdot_entry.creation_time.to_le_bytes());
1136        entry_data.extend_from_slice(&dotdot_entry.creation_date.to_le_bytes());
1137        entry_data.extend_from_slice(&dotdot_entry.last_access_date.to_le_bytes());
1138        entry_data.extend_from_slice(&dotdot_entry.cluster_high.to_le_bytes());
1139        entry_data.extend_from_slice(&dotdot_entry.modification_time.to_le_bytes());
1140        entry_data.extend_from_slice(&dotdot_entry.modification_date.to_le_bytes());
1141        entry_data.extend_from_slice(&dotdot_entry.cluster_low.to_le_bytes());
1142        entry_data.extend_from_slice(&dotdot_entry.file_size.to_le_bytes());
1143
1144        // Pad to sector boundary if needed
1145        while entry_data.len() < self.bytes_per_sector as usize {
1146            entry_data.push(0);
1147        }
1148
1149        // Write the first sector with . and .. entries
1150        let request = Box::new(crate::device::block::request::BlockIORequest {
1151            request_type: crate::device::block::request::BlockIORequestType::Write,
1152            sector: lba as usize,
1153            sector_count: 1,
1154            head: 0,
1155            cylinder: 0,
1156            buffer: entry_data,
1157        });
1158
1159        self.block_device.enqueue_request(request);
1160        self.block_device.process_requests();
1161
1162        Ok(())
1163    }
1164
1165    /// Update FS Info sector when a cluster is allocated
1166    fn update_fs_info_allocated_cluster(
1167        &self,
1168        _allocated_cluster: u32,
1169    ) -> Result<(), FileSystemError> {
1170        // FS Info sector is usually at sector 1
1171        let fs_info_sector = 1;
1172        let fs_info_lba = fs_info_sector;
1173
1174        // Read the current FS Info sector
1175        let request = Box::new(crate::device::block::request::BlockIORequest {
1176            request_type: crate::device::block::request::BlockIORequestType::Read,
1177            sector: fs_info_lba as usize,
1178            sector_count: 1,
1179            head: 0,
1180            cylinder: 0,
1181            buffer: vec![0u8; self.bytes_per_sector as usize],
1182        });
1183
1184        self.block_device.enqueue_request(request);
1185        let results = self.block_device.process_requests();
1186
1187        if let Some(result) = results.get(0) {
1188            if result.result.is_ok() {
1189                let mut fs_info_data = result.request.buffer.clone();
1190
1191                // Check FS Info signature at offset 0x1e4
1192                if &fs_info_data[0x1e4..0x1e8] == b"rrAa" {
1193                    // Get current free cluster count (offset 0x1e8, little-endian)
1194                    let current_free = u32::from_le_bytes([
1195                        fs_info_data[0x1e8],
1196                        fs_info_data[0x1e9],
1197                        fs_info_data[0x1ea],
1198                        fs_info_data[0x1eb],
1199                    ]);
1200
1201                    // Decrease free cluster count by 1
1202                    let new_free = current_free.saturating_sub(1);
1203                    let new_free_bytes = new_free.to_le_bytes();
1204                    fs_info_data[0x1e8] = new_free_bytes[0];
1205                    fs_info_data[0x1e9] = new_free_bytes[1];
1206                    fs_info_data[0x1ea] = new_free_bytes[2];
1207                    fs_info_data[0x1eb] = new_free_bytes[3];
1208
1209                    // Update next free cluster hint (offset 0x1ec)
1210                    // Set it to one cluster after the allocated one
1211                    let next_free_hint = _allocated_cluster + 1;
1212                    let hint_bytes = next_free_hint.to_le_bytes();
1213                    fs_info_data[0x1ec] = hint_bytes[0];
1214                    fs_info_data[0x1ed] = hint_bytes[1];
1215                    fs_info_data[0x1ee] = hint_bytes[2];
1216                    fs_info_data[0x1ef] = hint_bytes[3];
1217
1218                    // Write back the updated FS Info sector
1219                    let write_request = Box::new(crate::device::block::request::BlockIORequest {
1220                        request_type: crate::device::block::request::BlockIORequestType::Write,
1221                        sector: fs_info_lba as usize,
1222                        sector_count: 1,
1223                        head: 0,
1224                        cylinder: 0,
1225                        buffer: fs_info_data,
1226                    });
1227
1228                    self.block_device.enqueue_request(write_request);
1229                    self.block_device.process_requests();
1230                }
1231            }
1232        }
1233
1234        Ok(())
1235    }
1236
1237    /// Update FS Info sector to increment free cluster count
1238    fn update_fs_info_freed_cluster(&self, freed_count: u32) -> Result<(), FileSystemError> {
1239        let fs_info_sector = self.boot_sector.fs_info_sector;
1240        if fs_info_sector != 0 && fs_info_sector != 0xFFFF {
1241            let fs_info_lba = fs_info_sector as usize;
1242
1243            // Read current FS Info sector
1244            let request = Box::new(crate::device::block::request::BlockIORequest {
1245                request_type: crate::device::block::request::BlockIORequestType::Read,
1246                sector: fs_info_lba,
1247                sector_count: 1,
1248                head: 0,
1249                cylinder: 0,
1250                buffer: vec![0u8; 512],
1251            });
1252
1253            self.block_device.enqueue_request(request);
1254            let results = self.block_device.process_requests();
1255
1256            if let Some(result) = results.first() {
1257                match &result.result {
1258                    Ok(_) => {
1259                        let mut buffer = result.request.buffer.clone();
1260
1261                        // Check FS Info signature
1262                        if &buffer[0..4] == b"RRaA" && &buffer[484..488] == b"rrAa" {
1263                            // Read current free cluster count
1264                            let current_free = u32::from_le_bytes([
1265                                buffer[488],
1266                                buffer[489],
1267                                buffer[490],
1268                                buffer[491],
1269                            ]);
1270
1271                            // Update free cluster count (add freed clusters)
1272                            let new_free = current_free.saturating_add(freed_count);
1273                            let new_free_bytes = new_free.to_le_bytes();
1274                            buffer[488] = new_free_bytes[0];
1275                            buffer[489] = new_free_bytes[1];
1276                            buffer[490] = new_free_bytes[2];
1277                            buffer[491] = new_free_bytes[3];
1278
1279                            // Write back to disk
1280                            let write_request =
1281                                Box::new(crate::device::block::request::BlockIORequest {
1282                                    request_type:
1283                                        crate::device::block::request::BlockIORequestType::Write,
1284                                    sector: fs_info_lba,
1285                                    sector_count: 1,
1286                                    head: 0,
1287                                    cylinder: 0,
1288                                    buffer,
1289                                });
1290
1291                            self.block_device.enqueue_request(write_request);
1292                            self.block_device.process_requests();
1293                        }
1294                    }
1295                    Err(_) => {
1296                        return Err(FileSystemError::new(
1297                            FileSystemErrorKind::IoError,
1298                            "Failed to read FS Info sector for free cluster update",
1299                        ));
1300                    }
1301                }
1302            } else {
1303                return Err(FileSystemError::new(
1304                    FileSystemErrorKind::IoError,
1305                    "No result from FS Info sector read",
1306                ));
1307            }
1308        }
1309        Ok(())
1310    }
1311
1312    /// Free a cluster chain starting from the given cluster
1313    fn free_cluster_chain(&self, start_cluster: u32) -> Result<(), FileSystemError> {
1314        // #[cfg(test)]
1315        // {
1316        //     use crate::early_println;
1317        //     early_println!("[FAT32] free_cluster_chain: starting from cluster {}", start_cluster);
1318        // }
1319
1320        let mut current = start_cluster;
1321        let mut freed_count = 0;
1322
1323        // Only process valid cluster numbers (>= 2)
1324        while current >= 2 && current < 0x0FFFFFF0 {
1325            // #[cfg(test)]
1326            // {
1327            //     use crate::early_println;
1328            //     early_println!("[FAT32] freeing cluster {}, reading next cluster...", current);
1329            // }
1330
1331            let next = self.read_fat_entry(current)?;
1332
1333            // #[cfg(test)]
1334            // {
1335            //     use crate::early_println;
1336            //     early_println!("[FAT32] cluster {} next = {:#x}, marking as free", current, next);
1337            // }
1338
1339            self.write_fat_entry(current, 0)?; // Mark as free
1340            freed_count += 1;
1341
1342            // Check if we've reached the end of chain or invalid cluster
1343            if next >= 0x0FFFFFF8 || next == 0 || next == 1 {
1344                // #[cfg(test)]
1345                // {
1346                //     use crate::early_println;
1347                //     early_println!("[FAT32] reached end of chain at cluster {} (next={:#x})", current, next);
1348                // }
1349                break; // End of chain or invalid next cluster
1350            }
1351            current = next;
1352        }
1353
1354        // #[cfg(test)]
1355        // {
1356        //     use crate::early_println;
1357        //     early_println!("[FAT32] free_cluster_chain completed");
1358        // }
1359
1360        // Update FS Info sector with number of freed clusters
1361        self.update_fs_info_freed_cluster(freed_count)?;
1362
1363        Ok(())
1364    }
1365
1366    /// Read data to a cluster
1367    fn write_cluster_data(&self, cluster: u32, data: &[u8]) -> Result<(), FileSystemError> {
1368        #[cfg(test)]
1369        {
1370            use crate::early_println;
1371            early_println!(
1372                "[FAT32] write_cluster_data: cluster={}, data_len={}, first 8 bytes: {:?}",
1373                cluster,
1374                data.len(),
1375                &data[..core::cmp::min(8, data.len())]
1376            );
1377        }
1378
1379        if cluster < 2 {
1380            return Err(FileSystemError::new(
1381                FileSystemErrorKind::InvalidData,
1382                "Invalid cluster number",
1383            ));
1384        }
1385
1386        let first_data_sector = self.boot_sector.reserved_sectors as u32
1387            + (self.boot_sector.fat_count as u32 * self.boot_sector.sectors_per_fat);
1388        let first_sector_of_cluster = first_data_sector + (cluster - 2) * self.sectors_per_cluster;
1389
1390        // #[cfg(test)]
1391        // {
1392        //     use crate::early_println;
1393        //     early_println!("[FAT32] writing cluster {} at sector {}", cluster, first_sector_of_cluster);
1394        // }
1395
1396        let cluster_size = (self.sectors_per_cluster * self.bytes_per_sector) as usize;
1397        let mut buffer = vec![0u8; cluster_size];
1398
1399        // Copy data to buffer, pad with zeros if necessary
1400        let copy_len = core::cmp::min(data.len(), cluster_size);
1401        buffer[..copy_len].copy_from_slice(&data[..copy_len]);
1402
1403        // Write cluster data in batch
1404        let mut requests = Vec::new();
1405        for sector_offset in 0..self.sectors_per_cluster {
1406            let sector = first_sector_of_cluster + sector_offset;
1407            let buffer_offset = (sector_offset * self.bytes_per_sector) as usize;
1408            let sector_data =
1409                buffer[buffer_offset..buffer_offset + self.bytes_per_sector as usize].to_vec();
1410
1411            let request = Box::new(crate::device::block::request::BlockIORequest {
1412                request_type: crate::device::block::request::BlockIORequestType::Write,
1413                sector: sector as usize,
1414                sector_count: 1,
1415                head: 0,
1416                cylinder: 0,
1417                buffer: sector_data,
1418            });
1419
1420            self.block_device.enqueue_request(request);
1421            requests.push(());
1422        }
1423
1424        // Process all requests in batch
1425        let results = self.block_device.process_requests();
1426
1427        if results.len() != requests.len() {
1428            return Err(FileSystemError::new(
1429                FileSystemErrorKind::IoError,
1430                format!("Expected {} results, got {}", requests.len(), results.len()),
1431            ));
1432        }
1433
1434        // Check all results
1435        for (i, result) in results.iter().enumerate() {
1436            if result.result.is_err() {
1437                return Err(FileSystemError::new(
1438                    FileSystemErrorKind::IoError,
1439                    format!(
1440                        "Failed to write cluster {} sector {}",
1441                        cluster,
1442                        first_sector_of_cluster + i as u32
1443                    ),
1444                ));
1445            }
1446        }
1447
1448        Ok(())
1449    }
1450
1451    /// Convert cluster number to first sector number
1452    fn cluster_to_sector(&self, cluster: u32) -> u32 {
1453        let first_data_sector = self.boot_sector.reserved_sectors as u32
1454            + (self.boot_sector.fat_count as u32 * self.boot_sector.sectors_per_fat);
1455        first_data_sector + (cluster - 2) * self.sectors_per_cluster
1456    }
1457
1458    /// Read directory entries from a cluster
1459    fn read_directory_entries(
1460        &self,
1461        cluster: u32,
1462        entries: &mut Vec<Fat32DirectoryEntryInternal>,
1463    ) -> Result<(), FileSystemError> {
1464        let data = self.read_cluster_data(cluster)?;
1465        let entry_size = 32; // Each directory entry is 32 bytes
1466        let mut lfn_parts: Vec<String> = Vec::new(); // Collect LFN parts in order
1467
1468        for chunk in data.chunks(entry_size) {
1469            if chunk.len() < entry_size {
1470                break;
1471            }
1472
1473            // Check if entry is valid (not deleted and not empty)
1474            if chunk[0] == 0x00 {
1475                break; // End of directory
1476            }
1477            if chunk[0] == 0xE5 {
1478                lfn_parts.clear(); // Clear LFN parts on deleted entry
1479                continue; // Deleted entry
1480            }
1481
1482            // Parse directory entry
1483            let attributes = chunk[11];
1484
1485            // Handle LFN entries
1486            if attributes & 0x0F == 0x0F {
1487                // This is a LFN entry
1488                let lfn_entry = unsafe { &*(chunk.as_ptr() as *const structures::Fat32LFNEntry) };
1489
1490                // Extract characters from this LFN entry
1491                let chars = lfn_entry.extract_chars();
1492
1493                // Convert UTF-16 to UTF-8
1494                let mut part = String::new();
1495                for &ch in &chars {
1496                    if ch == 0 || ch == 0xFFFF {
1497                        break; // End of string or padding
1498                    }
1499                    if let Some(c) = char::from_u32(ch as u32) {
1500                        part.push(c);
1501                    }
1502                }
1503
1504                // LFN entries are stored with highest sequence number first
1505                // We need to collect them and reverse the order when assembling
1506                if lfn_entry.is_last_lfn() {
1507                    lfn_parts.clear(); // Start fresh for new LFN sequence
1508                    lfn_parts.push(part); // Add this part to the end
1509                } else {
1510                    // Add at the end, we'll reverse the entire collection later
1511                    lfn_parts.push(part);
1512                }
1513                continue;
1514            }
1515
1516            // Skip volume labels
1517            if attributes & 0x08 != 0 {
1518                lfn_parts.clear();
1519                continue;
1520            }
1521
1522            // This is a regular SFN directory entry
1523            let mut name_bytes = [0u8; 11];
1524            name_bytes.copy_from_slice(&chunk[0..11]);
1525
1526            let cluster = ((chunk[21] as u32) << 24)
1527                | ((chunk[20] as u32) << 16)
1528                | ((chunk[27] as u32) << 8)
1529                | (chunk[26] as u32);
1530            let size = u32::from_le_bytes([chunk[28], chunk[29], chunk[30], chunk[31]]);
1531
1532            // Create Fat32DirectoryEntry structure first
1533            let raw_entry = structures::Fat32DirectoryEntry {
1534                name: name_bytes,
1535                attributes,
1536                nt_reserved: 0,
1537                creation_time_tenths: 0,
1538                creation_time: 0,
1539                creation_date: 0,
1540                last_access_date: 0,
1541                cluster_high: ((cluster >> 16) & 0xFFFF) as u16,
1542                modification_time: 0,
1543                modification_date: 0,
1544                cluster_low: (cluster & 0xFFFF) as u16,
1545                file_size: size,
1546            };
1547
1548            // Create internal entry from raw entry
1549            let mut internal_entry = Fat32DirectoryEntryInternal::from_raw(raw_entry);
1550
1551            // Assemble complete LFN if available
1552            if !lfn_parts.is_empty() {
1553                // Reverse the parts since LFN entries are stored in reverse order
1554                lfn_parts.reverse();
1555                let long_filename = lfn_parts.join("");
1556                internal_entry.set_long_filename(long_filename);
1557            }
1558
1559            entries.push(internal_entry);
1560
1561            // Clear LFN for next entry
1562            lfn_parts.clear();
1563        }
1564
1565        Ok(())
1566    }
1567
1568    /// Write a new directory entry with LFN support to the specified directory cluster
1569    fn write_directory_entry_with_name(
1570        &self,
1571        dir_cluster: u32,
1572        filename: &str,
1573        cluster: u32,
1574        size: u32,
1575        is_directory: bool,
1576    ) -> Result<(), FileSystemError> {
1577        // #[cfg(test)]
1578        // {
1579        //     use crate::early_println;
1580        //     early_println!("[FAT32] write_directory_entry_with_name: dir_cluster={}, filename='{}', cluster={}, is_directory={}",
1581        //               dir_cluster, filename, cluster, is_directory);
1582        // }
1583
1584        // Generate a unique SFN for this filename
1585        let unique_sfn = self.generate_unique_sfn(dir_cluster, filename)?;
1586
1587        #[cfg(test)]
1588        {
1589            use crate::early_println;
1590            let sfn_str = core::str::from_utf8(&unique_sfn).unwrap_or("<invalid>");
1591            early_println!(
1592                "[FAT32] generated unique SFN for '{}': '{}'",
1593                filename,
1594                sfn_str
1595            );
1596        }
1597
1598        // Create the SFN entry with the generated SFN
1599        let entry = if is_directory {
1600            structures::Fat32DirectoryEntry {
1601                name: unique_sfn,
1602                attributes: 0x10, // Directory
1603                nt_reserved: 0,
1604                creation_time_tenths: 0,
1605                creation_time: 0,
1606                creation_date: 0,
1607                last_access_date: 0,
1608                cluster_high: (cluster >> 16) as u16,
1609                modification_time: 0,
1610                modification_date: 0,
1611                cluster_low: (cluster & 0xFFFF) as u16,
1612                file_size: 0,
1613            }
1614        } else {
1615            structures::Fat32DirectoryEntry {
1616                name: unique_sfn,
1617                attributes: 0x00, // Regular file
1618                nt_reserved: 0,
1619                creation_time_tenths: 0,
1620                creation_time: 0,
1621                creation_date: 0,
1622                last_access_date: 0,
1623                cluster_high: (cluster >> 16) as u16,
1624                modification_time: 0,
1625                modification_date: 0,
1626                cluster_low: (cluster & 0xFFFF) as u16,
1627                file_size: size,
1628            }
1629        };
1630
1631        // Check if LFN is required
1632        let needs_lfn = Self::requires_lfn(filename);
1633        // #[cfg(test)]
1634        // {
1635        //     use crate::early_println;
1636        //     early_println!("[FAT32] filename='{}', needs_lfn={}", filename, needs_lfn);
1637        // }
1638
1639        let mut entries_to_write = Vec::new();
1640
1641        if needs_lfn {
1642            // Generate LFN entries
1643            let sfn_checksum = Self::calculate_sfn_checksum(&entry.name);
1644            let lfn_entries = Self::generate_lfn_entries(&filename, sfn_checksum);
1645            // #[cfg(test)]
1646            // {
1647            //     use crate::early_println;
1648            //     early_println!("[FAT32] generated {} LFN entries", lfn_entries.len());
1649            // }
1650
1651            // Add LFN entries first (they come before the SFN entry)
1652            for lfn_entry in lfn_entries {
1653                entries_to_write.push(EntryToWrite::LFN(lfn_entry));
1654            }
1655        }
1656
1657        // Add the SFN entry
1658        entries_to_write.push(EntryToWrite::SFN(entry));
1659
1660        let total_entries_needed = entries_to_write.len();
1661        // #[cfg(test)]
1662        // {
1663        //     use crate::early_println;
1664        //     early_println!("[FAT32] total entries needed: {}", total_entries_needed);
1665        // }
1666
1667        // Find space for all entries
1668        let mut current_cluster = dir_cluster;
1669
1670        // #[cfg(test)]
1671        // {
1672        //     use crate::early_println;
1673        //     early_println!("[FAT32] searching for space in cluster {} for {} entries", current_cluster, total_entries_needed);
1674        // }
1675
1676        loop {
1677            // Read the current cluster
1678            let mut cluster_data = self.read_cluster_data(current_cluster)?;
1679            // #[cfg(test)]
1680            // {
1681            //     use crate::early_println;
1682            //     early_println!("[FAT32] read directory cluster {} data: {} bytes", current_cluster, cluster_data.len());
1683            // }
1684
1685            // Look for consecutive empty slots
1686            let entries_per_cluster = (self.sectors_per_cluster * self.bytes_per_sector) / 32;
1687            // #[cfg(test)]
1688            // {
1689            //     use crate::early_println;
1690            //     early_println!("[FAT32] scanning {} directory entries for {} consecutive free slots",
1691            //                   entries_per_cluster, total_entries_needed);
1692            // }
1693
1694            for start_i in 0..entries_per_cluster {
1695                let start_offset = (start_i * 32) as usize;
1696                if start_offset + (total_entries_needed * 32) > cluster_data.len() {
1697                    break;
1698                }
1699
1700                // Check if we have enough consecutive free slots
1701                let mut all_free = true;
1702                for j in 0..total_entries_needed {
1703                    let offset = start_offset + (j * 32);
1704                    if cluster_data[offset] != 0x00 && cluster_data[offset] != 0xE5 {
1705                        all_free = false;
1706                        break;
1707                    }
1708                }
1709
1710                if all_free {
1711                    // #[cfg(test)]
1712                    // {
1713                    //     use crate::early_println;
1714                    //     early_println!("[FAT32] found {} consecutive free slots starting at entry {}, offset {}",
1715                    //                   total_entries_needed, start_i, start_offset);
1716                    // }
1717
1718                    // Write all entries
1719                    for (j, entry_to_write) in entries_to_write.iter().enumerate() {
1720                        let offset = start_offset + (j * 32);
1721
1722                        match entry_to_write {
1723                            EntryToWrite::LFN(lfn_entry) => {
1724                                let entry_bytes = unsafe {
1725                                    core::slice::from_raw_parts(
1726                                        lfn_entry as *const _ as *const u8,
1727                                        32,
1728                                    )
1729                                };
1730                                cluster_data[offset..offset + 32].copy_from_slice(entry_bytes);
1731
1732                                // #[cfg(test)]
1733                                // {
1734                                //     use crate::early_println;
1735                                //     early_println!("[FAT32] wrote LFN entry at offset {} in cluster {}", offset, current_cluster);
1736                                // }
1737                            }
1738                            EntryToWrite::SFN(sfn_entry) => {
1739                                let entry_bytes = unsafe {
1740                                    core::slice::from_raw_parts(
1741                                        sfn_entry as *const _ as *const u8,
1742                                        32,
1743                                    )
1744                                };
1745                                cluster_data[offset..offset + 32].copy_from_slice(entry_bytes);
1746
1747                                // #[cfg(test)]
1748                                // {
1749                                //     use crate::early_println;
1750                                //     early_println!("[FAT32] wrote SFN entry at offset {}, first 8 bytes: {:02x?}",
1751                                //               offset, &entry_bytes[0..8]);
1752                                // }
1753                            }
1754                        }
1755                    }
1756
1757                    // Write the modified cluster back to disk
1758
1759                    // #[cfg(test)]
1760                    // {
1761                    //     use crate::early_println;
1762                    //     early_println!("[FAT32] writing modified directory cluster back to disk");
1763                    // }
1764
1765                    self.write_cluster_data(current_cluster, &cluster_data)?;
1766
1767                    // #[cfg(test)]
1768                    // {
1769                    //     use crate::early_println;
1770                    //     early_println!("[FAT32] write_directory_entry completed successfully");
1771                    // }
1772
1773                    return Ok(());
1774                }
1775            }
1776
1777            // #[cfg(test)]
1778            // {
1779            //     use crate::early_println;
1780            //     early_println!("[FAT32] no space found in cluster {}, checking next cluster", current_cluster);
1781            // }
1782
1783            // No space found in this cluster, check next cluster in chain
1784            let next_cluster = self.read_fat_entry(current_cluster)?;
1785            if next_cluster >= 0x0FFFFFF8 {
1786                // End of cluster chain, need to allocate new cluster
1787                // #[cfg(test)]
1788                // {
1789                //     use crate::early_println;
1790                //     early_println!("[FAT32] extending directory: allocating new cluster for cluster {}", current_cluster);
1791                // }
1792
1793                // Find a free cluster
1794                let new_cluster = self.allocate_cluster()?;
1795                // #[cfg(test)]
1796                // {
1797                //     use crate::early_println;
1798                //     early_println!("[FAT32] allocated new cluster {} for directory extension", new_cluster);
1799                // }
1800                // Link the new cluster to the directory chain
1801                self.write_fat_entry(current_cluster, new_cluster)?;
1802                // #[cfg(test)]
1803                // {
1804                //     use crate::early_println;
1805                //     early_println!("[FAT32] linked cluster {} -> {}", current_cluster, new_cluster);
1806                // }
1807
1808                // Mark the new cluster as end of chain
1809                self.write_fat_entry(new_cluster, 0x0FFFFFFF)?;
1810                // #[cfg(test)]
1811                // {
1812                //     use crate::early_println;
1813                //     early_println!("[FAT32] marked cluster {} as end of chain", new_cluster);
1814                // }
1815
1816                // Clear the new cluster (fill with zeros)
1817                let cluster_size = (self.sectors_per_cluster * self.bytes_per_sector) as usize;
1818                let mut empty_cluster = vec![0u8; cluster_size];
1819
1820                // Write all entries to the new cluster
1821                for (j, entry_to_write) in entries_to_write.iter().enumerate() {
1822                    let offset = j * 32;
1823
1824                    match entry_to_write {
1825                        EntryToWrite::LFN(lfn_entry) => {
1826                            let entry_bytes = unsafe {
1827                                core::slice::from_raw_parts(lfn_entry as *const _ as *const u8, 32)
1828                            };
1829                            empty_cluster[offset..offset + 32].copy_from_slice(entry_bytes);
1830
1831                            // #[cfg(test)]
1832                            // {
1833                            //     use crate::early_println;
1834                            //     early_println!("[FAT32] wrote LFN entry at offset {} in new cluster", offset);
1835                            // }
1836                        }
1837                        EntryToWrite::SFN(sfn_entry) => {
1838                            let entry_bytes = unsafe {
1839                                core::slice::from_raw_parts(sfn_entry as *const _ as *const u8, 32)
1840                            };
1841                            empty_cluster[offset..offset + 32].copy_from_slice(entry_bytes);
1842
1843                            // #[cfg(test)]
1844                            // {
1845                            //     use crate::early_println;
1846                            //     early_println!("[FAT32] wrote SFN entry at offset {} in new cluster, first 8 bytes: {:02x?}",
1847                            //               offset, &entry_bytes[0..8]);
1848                            // }
1849                        }
1850                    }
1851                }
1852
1853                // Write the entries to the new cluster
1854                self.write_cluster_data(new_cluster, &empty_cluster)?;
1855                // early_println!("[FAT32] wrote directory entries to new cluster {}", new_cluster);
1856
1857                return Ok(());
1858            }
1859            current_cluster = next_cluster;
1860        }
1861    }
1862
1863    /// Update an existing directory entry in the specified directory cluster
1864    /// Supports both LFN and SFN matching
1865    pub fn update_directory_entry(
1866        &self,
1867        dir_cluster: u32,
1868        filename: &str,
1869        entry: &structures::Fat32DirectoryEntry,
1870    ) -> Result<(), FileSystemError> {
1871        // early_println!("[FAT32] update_directory_entry: searching for '{}' in cluster {}", filename, dir_cluster);
1872
1873        let mut current_cluster = dir_cluster;
1874
1875        loop {
1876            // Read the current cluster
1877            let mut cluster_data = self.read_cluster_data(current_cluster)?;
1878
1879            // Parse directory entries in this cluster
1880            let entries_per_cluster = (self.sectors_per_cluster * self.bytes_per_sector) / 32;
1881            let mut lfn_parts: Vec<String> = Vec::new();
1882            let mut found_entry_offset: Option<usize> = None;
1883            let mut lfn_start_offset: Option<usize> = None;
1884
1885            for i in 0..entries_per_cluster {
1886                let offset = (i * 32) as usize;
1887                if offset + 32 > cluster_data.len() {
1888                    break;
1889                }
1890
1891                let entry_bytes = &cluster_data[offset..offset + 32];
1892
1893                // Safety: We know the slice is exactly 32 bytes (size of Fat32DirectoryEntry)
1894                let existing_entry = unsafe {
1895                    core::ptr::read(entry_bytes.as_ptr() as *const structures::Fat32DirectoryEntry)
1896                };
1897
1898                // Skip free entries
1899                if existing_entry.is_free() {
1900                    lfn_parts.clear();
1901                    lfn_start_offset = None;
1902                    continue;
1903                }
1904
1905                // Handle LFN entries
1906                if existing_entry.is_long_filename() {
1907                    let lfn_entry =
1908                        unsafe { &*(entry_bytes.as_ptr() as *const structures::Fat32LFNEntry) };
1909
1910                    // Extract characters from this LFN entry
1911                    let chars = lfn_entry.extract_chars();
1912
1913                    // Convert UTF-16 to UTF-8
1914                    let mut part = String::new();
1915                    for &ch in &chars {
1916                        if ch == 0 || ch == 0xFFFF {
1917                            break;
1918                        }
1919                        if let Some(c) = char::from_u32(ch as u32) {
1920                            part.push(c);
1921                        }
1922                    }
1923
1924                    // LFN entries are stored with highest sequence number first
1925                    if lfn_entry.is_last_lfn() {
1926                        // This is the first LFN entry we encounter (which contains the last part)
1927                        lfn_parts.clear();
1928                        lfn_parts.push(part);
1929                        lfn_start_offset = Some(offset);
1930                    } else {
1931                        // This is a subsequent LFN entry (which contains earlier parts)
1932                        lfn_parts.push(part);
1933                        if lfn_start_offset.is_none() {
1934                            lfn_start_offset = Some(offset);
1935                        }
1936                    }
1937                    continue;
1938                }
1939
1940                // Skip dot entries
1941                if existing_entry.name[0] == b'.' {
1942                    lfn_parts.clear();
1943                    lfn_start_offset = None;
1944                    continue;
1945                }
1946
1947                // This is a regular directory entry (SFN)
1948                let sfn_filename = existing_entry.filename();
1949                let full_filename = if !lfn_parts.is_empty() {
1950                    // Reverse the parts since LFN entries are stored in reverse order
1951                    lfn_parts.reverse();
1952                    lfn_parts.join("")
1953                } else {
1954                    sfn_filename.clone()
1955                };
1956
1957                // #[cfg(test)]
1958                // {
1959                //     use crate::early_println;
1960                //     early_println!("[FAT32] checking entry: sfn='{}', lfn='{}', looking_for='{}'",
1961                //                   sfn_filename, full_filename, filename);
1962                // }
1963
1964                // Check if this matches the filename we're looking for
1965                let matches = full_filename == filename
1966                    || sfn_filename == filename
1967                    || full_filename.to_lowercase() == filename.to_lowercase()
1968                    || sfn_filename.to_lowercase() == filename.to_lowercase();
1969
1970                if matches {
1971                    // early_println!("[FAT32] found matching entry at offset {}, updating cluster and size", offset);
1972
1973                    // Parse the existing entry to preserve its SFN and other metadata
1974                    let mut existing_entry = existing_entry; // Use the already parsed entry
1975
1976                    // Update only the cluster and file size fields
1977                    existing_entry.update_cluster_and_size(entry.cluster(), entry.file_size);
1978
1979                    // Write the updated entry back
1980                    let updated_entry_bytes = unsafe {
1981                        core::slice::from_raw_parts(&existing_entry as *const _ as *const u8, 32)
1982                    };
1983                    cluster_data[offset..offset + 32].copy_from_slice(updated_entry_bytes);
1984                    found_entry_offset = Some(offset);
1985                    break;
1986                }
1987
1988                // Clear LFN accumulation for next entry
1989                lfn_parts.clear();
1990                lfn_start_offset = None;
1991            }
1992
1993            if found_entry_offset.is_some() {
1994                // Write the modified cluster back to disk
1995                self.write_cluster_data(current_cluster, &cluster_data)?;
1996                // early_println!("[FAT32] directory entry updated successfully");
1997                return Ok(());
1998            }
1999
2000            // Get next cluster in the chain
2001            let next_cluster = self.read_fat_entry(current_cluster)?;
2002            if next_cluster >= 0x0FFFFFF8 {
2003                // End of cluster chain
2004                break;
2005            }
2006            current_cluster = next_cluster;
2007        }
2008
2009        // early_println!("[FAT32] directory entry for '{}' not found for update", filename);
2010        Err(FileSystemError::new(
2011            FileSystemErrorKind::NotFound,
2012            &format!("Directory entry for '{}' not found for update", filename),
2013        ))
2014    }
2015
2016    /// Check if a filename requires LFN (Long File Name) entries
2017    fn requires_lfn(filename: &str) -> bool {
2018        // LFN is required if:
2019        // 1. Filename is longer than 8.3 format
2020        // 2. Filename contains invalid SFN characters
2021        // 3. Extension is longer than 3 characters
2022        // 4. Filename contains spaces or other special characters not allowed in SFN
2023
2024        // #[cfg(test)]
2025        // {
2026        //     use crate::early_println;
2027        //     early_println!("[FAT32] checking requires_lfn for '{}'", filename);
2028        // }
2029
2030        // Quick check for obvious LFN cases
2031        if filename.contains(' ') || filename.contains('+') || filename.contains(',') {
2032            // #[cfg(test)]
2033            // {
2034            //     use crate::early_println;
2035            //     early_println!("[FAT32] requires_lfn('{}') = true (contains special chars)", filename);
2036            // }
2037            return true;
2038        }
2039
2040        if let Some(dot_pos) = filename.rfind('.') {
2041            let name_part = &filename[..dot_pos];
2042            let ext_part = &filename[dot_pos + 1..];
2043
2044            // Check name part and extension length
2045            if name_part.len() > 8 || ext_part.len() > 3 {
2046                // #[cfg(test)]
2047                // {
2048                //     use crate::early_println;
2049                //     early_println!("[FAT32] requires_lfn('{}') = true (length: name={}, ext={})", filename, name_part.len(), ext_part.len());
2050                // }
2051                return true;
2052            }
2053
2054            // Check for invalid SFN characters (valid: A-Z, a-z, 0-9, ! # $ % & ' ( ) - @ ^ _ ` { } ~)
2055            if name_part.chars().any(|c| !Self::is_valid_sfn_char(c))
2056                || ext_part.chars().any(|c| !Self::is_valid_sfn_char(c))
2057            {
2058                // #[cfg(test)]
2059                // {
2060                //     use crate::early_println;
2061                //     early_println!("[FAT32] requires_lfn('{}') = true (invalid SFN chars)", filename);
2062                // }
2063                return true;
2064            }
2065        } else {
2066            // No extension - just check name length and characters
2067            if filename.len() > 8 {
2068                // #[cfg(test)]
2069                // {
2070                //     use crate::early_println;
2071                //     early_println!("[FAT32] requires_lfn('{}') = true (no ext, length={})", filename, filename.len());
2072                // }
2073                return true;
2074            }
2075
2076            // Check for invalid SFN characters (valid: A-Z, a-z, 0-9, ! # $ % & ' ( ) - @ ^ _ ` { } ~)
2077            if filename.chars().any(|c| !Self::is_valid_sfn_char(c)) {
2078                // #[cfg(test)]
2079                // {
2080                //     use crate::early_println;
2081                //     early_println!("[FAT32] requires_lfn('{}') = true (invalid SFN chars)", filename);
2082                // }
2083                return true;
2084            }
2085        }
2086
2087        // #[cfg(test)]
2088        // {
2089        //     use crate::early_println;
2090        //     early_println!("[FAT32] requires_lfn('{}') = false (valid 8.3 format)", filename);
2091        // }
2092
2093        false
2094    }
2095
2096    /// Generate LFN entries for a given filename
2097    fn generate_lfn_entries(filename: &str, sfn_checksum: u8) -> Vec<structures::Fat32LFNEntry> {
2098        let mut entries = Vec::new();
2099        let chars: Vec<u16> = filename.encode_utf16().collect();
2100
2101        // Each LFN entry can hold 13 characters
2102        let entries_needed = (chars.len() + 12) / 13; // Round up division
2103
2104        for entry_num in 0..entries_needed {
2105            let start_idx = entry_num * 13;
2106
2107            let mut lfn_entry = structures::Fat32LFNEntry {
2108                sequence: (entry_num + 1) as u8,
2109                name1: [0xFFFF; 5],
2110                attributes: 0x0F, // LFN attribute
2111                entry_type: 0,
2112                checksum: sfn_checksum,
2113                name2: [0xFFFF; 6],
2114                cluster: 0,
2115                name3: [0xFFFF; 2],
2116            };
2117
2118            // Mark last entry
2119            if entry_num == entries_needed - 1 {
2120                lfn_entry.sequence |= 0x40; // Last LFN entry flag
2121            }
2122
2123            // Fill in characters
2124            let mut char_idx = start_idx;
2125
2126            // Fill name1 (5 characters)
2127            for i in 0..5 {
2128                if char_idx < chars.len() {
2129                    lfn_entry.name1[i] = chars[char_idx];
2130                    char_idx += 1;
2131                } else if char_idx == chars.len() {
2132                    lfn_entry.name1[i] = 0x0000; // Null terminator
2133                    char_idx += 1;
2134                } else {
2135                    lfn_entry.name1[i] = 0xFFFF; // Padding
2136                }
2137            }
2138
2139            // Fill name2 (6 characters)
2140            for i in 0..6 {
2141                if char_idx < chars.len() {
2142                    lfn_entry.name2[i] = chars[char_idx];
2143                    char_idx += 1;
2144                } else if char_idx == chars.len() {
2145                    lfn_entry.name2[i] = 0x0000; // Null terminator
2146                    char_idx += 1;
2147                } else {
2148                    lfn_entry.name2[i] = 0xFFFF; // Padding
2149                }
2150            }
2151
2152            // Fill name3 (2 characters)
2153            for i in 0..2 {
2154                if char_idx < chars.len() {
2155                    lfn_entry.name3[i] = chars[char_idx];
2156                    char_idx += 1;
2157                } else if char_idx == chars.len() {
2158                    lfn_entry.name3[i] = 0x0000; // Null terminator
2159                    char_idx += 1;
2160                } else {
2161                    lfn_entry.name3[i] = 0xFFFF; // Padding
2162                }
2163            }
2164
2165            entries.push(lfn_entry);
2166        }
2167
2168        // LFN entries need to be in reverse order (last entry first)
2169        entries.reverse();
2170        entries
2171    }
2172
2173    /// Calculate checksum for SFN (used in LFN entries)
2174    fn calculate_sfn_checksum(sfn: &[u8; 11]) -> u8 {
2175        let mut checksum = 0u8;
2176        for &byte in sfn {
2177            checksum = ((checksum & 1) << 7)
2178                .wrapping_add(checksum >> 1)
2179                .wrapping_add(byte);
2180        }
2181        checksum
2182    }
2183
2184    /// Remove a directory entry from the specified directory cluster
2185    fn remove_directory_entry(
2186        &self,
2187        dir_cluster: u32,
2188        filename: &str,
2189    ) -> Result<(), FileSystemError> {
2190        let entries_per_cluster = (self.sectors_per_cluster * self.bytes_per_sector) / 32;
2191        let mut current_cluster = dir_cluster;
2192
2193        // #[cfg(test)]
2194        // {
2195        //     use crate::early_println;
2196        //     early_println!("[FAT32] remove_directory_entry: searching for '{}' in cluster {}", filename, dir_cluster);
2197        // }
2198
2199        loop {
2200            let mut cluster_data = self.read_cluster_data(current_cluster)?;
2201            let mut entries_to_remove = Vec::new();
2202            let mut i = 0;
2203
2204            while i < entries_per_cluster {
2205                let entry_offset = (i * 32) as usize;
2206                if entry_offset + 32 > cluster_data.len() {
2207                    break;
2208                }
2209
2210                let entry_bytes = &cluster_data[entry_offset..entry_offset + 32];
2211
2212                // Check if this is the end of directory
2213                if entry_bytes[0] == 0x00 {
2214                    break;
2215                }
2216
2217                // Skip free entries
2218                if entry_bytes[0] == 0xE5 {
2219                    i += 1;
2220                    continue;
2221                }
2222
2223                // Check if this is an LFN entry
2224                if entry_bytes[11] == 0x0F {
2225                    // This is an LFN entry - we'll need to handle LFN chains later
2226                    i += 1;
2227                    continue;
2228                }
2229
2230                // This is a regular SFN entry
2231                let dir_entry = unsafe {
2232                    core::ptr::read_unaligned(
2233                        entry_bytes.as_ptr() as *const structures::Fat32DirectoryEntry
2234                    )
2235                };
2236
2237                let entry_filename = dir_entry.filename().to_lowercase();
2238
2239                // Also check if this entry has LFN entries and read the long filename
2240                let mut full_filename = entry_filename.clone();
2241
2242                // Look backwards for LFN entries that belong to this SFN
2243                let mut lfn_start = i;
2244                let mut lfn_name = String::new();
2245
2246                // Find the start of LFN entries
2247                for j in (0..i).rev() {
2248                    let lfn_offset = (j * 32) as usize;
2249                    let lfn_bytes = &cluster_data[lfn_offset..lfn_offset + 32];
2250
2251                    // Check if this is an LFN entry
2252                    if lfn_bytes[11] == 0x0F {
2253                        lfn_start = j;
2254                    } else {
2255                        break;
2256                    }
2257                }
2258
2259                // If we found LFN entries, reconstruct the full filename
2260                if lfn_start < i {
2261                    let mut lfn_entries = Vec::new();
2262
2263                    // Collect all LFN entries
2264                    for j in lfn_start..i {
2265                        let lfn_offset = (j * 32) as usize;
2266                        let lfn_bytes = &cluster_data[lfn_offset..lfn_offset + 32];
2267
2268                        if lfn_bytes[11] == 0x0F {
2269                            let lfn_entry = unsafe {
2270                                core::ptr::read_unaligned(
2271                                    lfn_bytes.as_ptr() as *const structures::Fat32LFNEntry
2272                                )
2273                            };
2274                            lfn_entries.push(lfn_entry);
2275                        }
2276                    }
2277
2278                    // Sort LFN entries by their sequence number (ascending order)
2279                    lfn_entries.sort_by(|a, b| {
2280                        let seq_a = a.sequence & 0x1F; // Remove last entry flag
2281                        let seq_b = b.sequence & 0x1F;
2282                        seq_a.cmp(&seq_b) // Ascending order (lowest sequence first)
2283                    });
2284
2285                    // Reconstruct the filename from sorted LFN entries
2286                    for lfn_entry in lfn_entries {
2287                        // Extract characters from name1, name2, name3
2288                        for k in 0..5 {
2289                            let ch = lfn_entry.name1[k];
2290                            if ch != 0x0000 && ch != 0xFFFF {
2291                                if let Some(c) = char::from_u32(ch as u32) {
2292                                    lfn_name.push(c);
2293                                }
2294                            } else {
2295                                break;
2296                            }
2297                        }
2298                        for k in 0..6 {
2299                            let ch = lfn_entry.name2[k];
2300                            if ch != 0x0000 && ch != 0xFFFF {
2301                                if let Some(c) = char::from_u32(ch as u32) {
2302                                    lfn_name.push(c);
2303                                }
2304                            } else {
2305                                break;
2306                            }
2307                        }
2308                        for k in 0..2 {
2309                            let ch = lfn_entry.name3[k];
2310                            if ch != 0x0000 && ch != 0xFFFF {
2311                                if let Some(c) = char::from_u32(ch as u32) {
2312                                    lfn_name.push(c);
2313                                }
2314                            } else {
2315                                break;
2316                            }
2317                        }
2318                    }
2319
2320                    if !lfn_name.is_empty() {
2321                        full_filename = lfn_name;
2322                    }
2323                }
2324
2325                #[cfg(test)]
2326                {
2327                    use crate::early_println;
2328                    early_println!(
2329                        "[FAT32] checking entry: sfn='{}', lfn='{}', looking_for='{}'",
2330                        entry_filename,
2331                        full_filename,
2332                        filename
2333                    );
2334                }
2335
2336                // Check both SFN and LFN
2337                if entry_filename == filename.to_lowercase() || full_filename == filename {
2338                    // #[cfg(test)]
2339                    // {
2340                    //     use crate::early_println;
2341                    //     early_println!("[FAT32] found matching entry at offset {}", entry_offset);
2342                    // }
2343
2344                    // Mark all entries (LFN + SFN) for removal
2345                    for remove_i in lfn_start..=i {
2346                        entries_to_remove.push(remove_i);
2347                    }
2348
2349                    break;
2350                }
2351
2352                i += 1;
2353            }
2354
2355            // Remove the entries by marking them as deleted (0xE5)
2356            if !entries_to_remove.is_empty() {
2357                for &remove_i in &entries_to_remove {
2358                    let entry_offset = (remove_i * 32) as usize;
2359                    cluster_data[entry_offset] = 0xE5; // Mark as deleted
2360
2361                    // #[cfg(test)]
2362                    // {
2363                    //     use crate::early_println;
2364                    //     early_println!("[FAT32] marked entry {} as deleted at offset {}", remove_i, entry_offset);
2365                    // }
2366                }
2367
2368                // Write the modified cluster back to disk
2369                self.write_cluster_data(current_cluster, &cluster_data)?;
2370
2371                // #[cfg(test)]
2372                // {
2373                //     use crate::early_println;
2374                //     early_println!("[FAT32] remove_directory_entry completed successfully");
2375                // }
2376
2377                return Ok(());
2378            }
2379
2380            // Move to next cluster in chain
2381            let next_cluster = self.read_fat_entry(current_cluster)?;
2382            if next_cluster >= 0x0FFFFFF8 || next_cluster == 0 {
2383                break;
2384            }
2385            current_cluster = next_cluster;
2386        }
2387
2388        // File not found
2389        Err(FileSystemError::new(
2390            FileSystemErrorKind::NotFound,
2391            format!("Directory entry '{}' not found", filename),
2392        ))
2393    }
2394
2395    /// Generate a FAT32-compliant SFN (Short File Name) from a long filename
2396    /// This implementation follows the Microsoft FAT32 specification
2397    fn generate_sfn(filename: &str, numeric_tail: Option<u32>) -> [u8; 11] {
2398        let mut sfn = [b' '; 11];
2399
2400        // Convert to uppercase and filter invalid characters
2401        let clean_filename = filename.to_uppercase();
2402
2403        // Split into name and extension
2404        let (name_part, ext_part) = if let Some(dot_pos) = clean_filename.rfind('.') {
2405            (
2406                &clean_filename[..dot_pos],
2407                Some(&clean_filename[dot_pos + 1..]),
2408            )
2409        } else {
2410            (clean_filename.as_str(), None)
2411        };
2412
2413        // Generate the name part (first 8 characters)
2414        let mut name_chars = Vec::new();
2415        for ch in name_part.chars() {
2416            if Self::is_valid_sfn_char(ch) {
2417                name_chars.push(ch as u8);
2418            } else if ch == ' ' {
2419                // Skip spaces
2420                continue;
2421            } else {
2422                // Replace invalid characters with underscore
2423                name_chars.push(b'_');
2424            }
2425        }
2426
2427        // Handle numeric tail for duplicate names (~1, ~2, etc.)
2428        let base_name_len = if let Some(tail) = numeric_tail {
2429            let tail_str = format!("~{}", tail);
2430            let max_base_len = 8 - tail_str.len();
2431            core::cmp::min(name_chars.len(), max_base_len)
2432        } else {
2433            core::cmp::min(name_chars.len(), 8)
2434        };
2435
2436        // Copy base name
2437        for i in 0..base_name_len {
2438            sfn[i] = name_chars[i];
2439        }
2440
2441        // Add numeric tail if present
2442        if let Some(tail) = numeric_tail {
2443            let tail_str = format!("~{}", tail);
2444            let tail_bytes = tail_str.as_bytes();
2445            for (i, &byte) in tail_bytes.iter().enumerate() {
2446                if base_name_len + i < 8 {
2447                    sfn[base_name_len + i] = byte;
2448                }
2449            }
2450        }
2451
2452        // Handle extension part
2453        if let Some(ext) = ext_part {
2454            let mut ext_chars = Vec::new();
2455            for ch in ext.chars().take(3) {
2456                // Max 3 characters for extension
2457                if Self::is_valid_sfn_char(ch) {
2458                    ext_chars.push(ch as u8);
2459                } else if ch != ' ' {
2460                    ext_chars.push(b'_');
2461                }
2462            }
2463
2464            // Copy extension
2465            for (i, &byte) in ext_chars.iter().enumerate() {
2466                if i < 3 {
2467                    sfn[8 + i] = byte;
2468                }
2469            }
2470        }
2471
2472        sfn
2473    }
2474
2475    /// Check if a character is valid for SFN according to FAT32 specification
2476    fn is_valid_sfn_char(ch: char) -> bool {
2477        match ch {
2478            'A'..='Z' | 'a'..='z' | '0'..='9' => true,
2479            '!' | '#' | '$' | '%' | '&' | '\'' | '(' | ')' | '-' | '@' | '^' | '_' | '`' | '{'
2480            | '}' | '~' => true,
2481            _ => false,
2482        }
2483    }
2484
2485    /// Check if filename needs numeric tail (Linux-style behavior)
2486    /// Returns true ONLY for filenames that cannot fit in 8.3 format or contain invalid characters
2487    fn filename_needs_numeric_tail(&self, filename: &str) -> bool {
2488        // Find the last dot to separate name and extension
2489        if let Some(dot_pos) = filename.rfind('.') {
2490            let main_name = &filename[..dot_pos];
2491            let extension = &filename[dot_pos + 1..];
2492
2493            // #[cfg(test)]
2494            // {
2495            //     use crate::early_println;
2496            //     early_println!("[FAT32] analyzing filename: '{}' -> name='{}' ({} chars), ext='{}' ({} chars)",
2497            //         filename, main_name, main_name.len(), extension, extension.len());
2498            // }
2499
2500            // Check if main name is longer than 8 chars or extension longer than 3 chars
2501            if main_name.len() > 8 || extension.len() > 3 {
2502                // #[cfg(test)]
2503                // {
2504                //     use crate::early_println;
2505                //     early_println!("[FAT32] filename_needs_numeric_tail: '{}' -> true (length exceeded)", filename);
2506                // }
2507                return true;
2508            }
2509
2510            // Check main name for invalid characters
2511            for ch in main_name.chars() {
2512                if ch == ' '
2513                    || ch == '+'
2514                    || ch == '='
2515                    || ch == '['
2516                    || ch == ']'
2517                    || ch == ','
2518                    || ch == ';'
2519                {
2520                    #[cfg(test)]
2521                    {
2522                        use crate::early_println;
2523                        early_println!(
2524                            "[FAT32] filename_needs_numeric_tail: '{}' -> true (invalid char in name: '{}')",
2525                            filename,
2526                            ch
2527                        );
2528                    }
2529                    return true;
2530                }
2531            }
2532
2533            // Check extension for invalid characters
2534            for ch in extension.chars() {
2535                if ch == ' '
2536                    || ch == '+'
2537                    || ch == '='
2538                    || ch == '['
2539                    || ch == ']'
2540                    || ch == ','
2541                    || ch == ';'
2542                {
2543                    #[cfg(test)]
2544                    {
2545                        use crate::early_println;
2546                        early_println!(
2547                            "[FAT32] filename_needs_numeric_tail: '{}' -> true (invalid char in ext: '{}')",
2548                            filename,
2549                            ch
2550                        );
2551                    }
2552                    return true;
2553                }
2554            }
2555        } else {
2556            // No extension - check if name is longer than 8 chars
2557            if filename.len() > 8 {
2558                // #[cfg(test)]
2559                // {
2560                //     use crate::early_println;
2561                //     early_println!("[FAT32] filename_needs_numeric_tail: '{}' -> true (no ext, length={})", filename, filename.len());
2562                // }
2563                return true;
2564            }
2565
2566            // Check for invalid characters
2567            for ch in filename.chars() {
2568                if ch == ' '
2569                    || ch == '+'
2570                    || ch == '='
2571                    || ch == '['
2572                    || ch == ']'
2573                    || ch == ','
2574                    || ch == ';'
2575                {
2576                    #[cfg(test)]
2577                    {
2578                        use crate::early_println;
2579                        early_println!(
2580                            "[FAT32] filename_needs_numeric_tail: '{}' -> true (invalid char: '{}')",
2581                            filename,
2582                            ch
2583                        );
2584                    }
2585                    return true;
2586                }
2587            }
2588        }
2589
2590        #[cfg(test)]
2591        {
2592            use crate::early_println;
2593            early_println!(
2594                "[FAT32] filename_needs_numeric_tail: '{}' -> false (fits in 8.3)",
2595                filename
2596            );
2597        }
2598        false
2599    }
2600
2601    /// Generate a unique SFN by checking for duplicates in the directory
2602    fn generate_unique_sfn(
2603        &self,
2604        dir_cluster: u32,
2605        desired_filename: &str,
2606    ) -> Result<[u8; 11], FileSystemError> {
2607        // Check if the filename needs numeric tail (Linux-style: long names get ~1 from start)
2608        let needs_tail = self.filename_needs_numeric_tail(desired_filename);
2609
2610        if !needs_tail {
2611            // Short filename that fits in 8.3 - try without tail first
2612            let base_sfn = Self::generate_sfn(desired_filename, None);
2613            if !self.sfn_exists_in_directory(dir_cluster, &base_sfn)? {
2614                return Ok(base_sfn);
2615            }
2616        }
2617
2618        // Try with numeric tails ~1, ~2, ..., ~999999 (Linux-style)
2619        for tail in 1..=999999 {
2620            let sfn_with_tail = Self::generate_sfn(desired_filename, Some(tail));
2621
2622            if !self.sfn_exists_in_directory(dir_cluster, &sfn_with_tail)? {
2623                return Ok(sfn_with_tail);
2624            }
2625        }
2626
2627        Err(FileSystemError::new(
2628            FileSystemErrorKind::NoSpace,
2629            "Cannot generate unique SFN: too many similar filenames",
2630        ))
2631    }
2632
2633    /// Check if an SFN already exists in the specified directory
2634    fn sfn_exists_in_directory(
2635        &self,
2636        dir_cluster: u32,
2637        sfn: &[u8; 11],
2638    ) -> Result<bool, FileSystemError> {
2639        let mut current_cluster = dir_cluster;
2640        let entries_per_cluster = (self.sectors_per_cluster * self.bytes_per_sector / 32) as usize;
2641
2642        loop {
2643            let cluster_data = self.read_cluster_data(current_cluster)?;
2644
2645            for i in 0..entries_per_cluster {
2646                let entry_offset = i * 32;
2647                if entry_offset + 32 > cluster_data.len() {
2648                    break;
2649                }
2650
2651                let entry_bytes = &cluster_data[entry_offset..entry_offset + 32];
2652
2653                // End of directory
2654                if entry_bytes[0] == 0x00 {
2655                    return Ok(false);
2656                }
2657
2658                // Skip free entries and LFN entries
2659                if entry_bytes[0] == 0xE5 || entry_bytes[11] == 0x0F {
2660                    continue;
2661                }
2662
2663                // Compare SFN
2664                let existing_sfn = &entry_bytes[0..11];
2665                if existing_sfn == sfn {
2666                    return Ok(true);
2667                }
2668            }
2669
2670            // Move to next cluster in chain
2671            let next_cluster = self.read_fat_entry(current_cluster)?;
2672            if next_cluster >= 0x0FFFFFF8 {
2673                break;
2674            }
2675            current_cluster = next_cluster;
2676        }
2677
2678        Ok(false)
2679    }
2680}
2681
2682impl FileSystemOperations for Fat32FileSystem {
2683    fn fs_id(&self) -> FileSystemId {
2684        self.fs_id
2685    }
2686
2687    fn lookup(
2688        &self,
2689        parent: &Arc<dyn VfsNode>,
2690        name: &String,
2691    ) -> Result<Arc<dyn VfsNode>, FileSystemError> {
2692        let fat32_parent = parent.as_any().downcast_ref::<Fat32Node>().ok_or_else(|| {
2693            FileSystemError::new(
2694                FileSystemErrorKind::NotSupported,
2695                "Invalid node type for FAT32",
2696            )
2697        })?;
2698
2699        // Check if it's a directory
2700        match fat32_parent.file_type() {
2701            Ok(FileType::Directory) => {}
2702            Ok(_) => {
2703                return Err(FileSystemError::new(
2704                    FileSystemErrorKind::NotADirectory,
2705                    "Parent is not a directory",
2706                ));
2707            }
2708            Err(e) => return Err(e),
2709        }
2710
2711        // Get the starting cluster for the directory
2712        let parent_cluster = *fat32_parent.cluster.read();
2713        let starting_cluster = if parent_cluster == 0 {
2714            self.boot_sector.root_cluster
2715        } else {
2716            parent_cluster
2717        };
2718
2719        // Search for the file in the directory
2720        let found_entry = self.lookup_file_in_directory(starting_cluster, name)?;
2721        // Create a new Fat32Node for the found entry
2722        let node = if found_entry.is_directory() {
2723            let dir_node = Fat32Node::new_directory(
2724                found_entry.name(),
2725                found_entry.cluster() as u64,
2726                found_entry.cluster(),
2727            );
2728            // Set filesystem reference from parent
2729            if let Some(fs_ref) = fat32_parent.filesystem() {
2730                dir_node.set_filesystem(fs_ref);
2731            }
2732            dir_node
2733        } else {
2734            let file_node = Fat32Node::new_file(
2735                found_entry.name(),
2736                found_entry.cluster() as u64,
2737                found_entry.cluster(),
2738            );
2739            // Update file size
2740            {
2741                let mut metadata = file_node.metadata.write();
2742                metadata.size = found_entry.size() as usize;
2743            }
2744            // Set filesystem reference from parent
2745            if let Some(fs_ref) = fat32_parent.filesystem() {
2746                file_node.set_filesystem(fs_ref);
2747            }
2748            file_node
2749        };
2750
2751        Ok(Arc::new(node))
2752    }
2753
2754    fn open(
2755        &self,
2756        node: &Arc<dyn VfsNode>,
2757        _flags: u32,
2758    ) -> Result<Arc<dyn FileObject>, FileSystemError> {
2759        let fat32_node = node.as_any().downcast_ref::<Fat32Node>().ok_or_else(|| {
2760            FileSystemError::new(
2761                FileSystemErrorKind::NotSupported,
2762                "Invalid node type for FAT32",
2763            )
2764        })?;
2765
2766        match fat32_node.file_type() {
2767            Ok(FileType::RegularFile) => {
2768                // Get parent from parent node
2769                let parent_cluster = if let Some(parent_ref) = fat32_node.parent.read().as_ref() {
2770                    if let Some(parent_node) = parent_ref.upgrade() {
2771                        *parent_node.cluster.read()
2772                    } else {
2773                        0 // Default to 0 if parent is not available
2774                    }
2775                } else {
2776                    0 // Default to 0 if no parent reference
2777                };
2778
2779                Ok(Arc::new(Fat32FileObject::new(
2780                    Arc::new(fat32_node.clone()),
2781                    parent_cluster,
2782                )))
2783            }
2784            Ok(FileType::Directory) => Ok(Arc::new(Fat32DirectoryObject::new(Arc::new(
2785                fat32_node.clone(),
2786            )))),
2787            Ok(_) => Err(FileSystemError::new(
2788                FileSystemErrorKind::NotSupported,
2789                "Unsupported file type",
2790            )),
2791            Err(e) => Err(e),
2792        }
2793    }
2794
2795    fn create(
2796        &self,
2797        parent: &Arc<dyn VfsNode>,
2798        name: &String,
2799        file_type: FileType,
2800        _mode: u32,
2801    ) -> Result<Arc<dyn VfsNode>, FileSystemError> {
2802        let fat32_parent = parent.as_any().downcast_ref::<Fat32Node>().ok_or_else(|| {
2803            FileSystemError::new(
2804                FileSystemErrorKind::NotSupported,
2805                "Invalid node type for FAT32",
2806            )
2807        })?;
2808
2809        // Check if it's a directory
2810        match fat32_parent.file_type() {
2811            Ok(FileType::Directory) => {}
2812            Ok(_) => {
2813                return Err(FileSystemError::new(
2814                    FileSystemErrorKind::NotADirectory,
2815                    "Parent is not a directory",
2816                ));
2817            }
2818            Err(e) => return Err(e),
2819        }
2820
2821        // Check if file already exists (FAT32 is case-insensitive)
2822        let parent_cluster = *fat32_parent.cluster.read();
2823        let actual_parent_cluster = if parent_cluster == 0 {
2824            self.root_cluster // Use root cluster for root directory
2825        } else {
2826            parent_cluster
2827        };
2828
2829        // Check on disk for case-insensitive duplicates
2830        if let Ok(_existing_entry) = self.lookup_file_in_directory(actual_parent_cluster, name) {
2831            return Err(FileSystemError::new(
2832                FileSystemErrorKind::AlreadyExists,
2833                format!("File '{}' already exists (case-insensitive)", name),
2834            ));
2835        }
2836
2837        // Create new node
2838        let file_id = self.generate_file_id();
2839        let new_node = match file_type {
2840            FileType::RegularFile => {
2841                Arc::new(Fat32Node::new_file(name.clone(), file_id, 0)) // No cluster allocated yet
2842            }
2843            FileType::Directory => {
2844                // Allocate cluster for directory
2845                let dir_cluster = self.allocate_cluster().map_err(|e| {
2846                    FileSystemError::new(
2847                        FileSystemErrorKind::NoSpace,
2848                        format!("Failed to allocate cluster for directory: {:?}", e),
2849                    )
2850                })?;
2851
2852                // Initialize directory with . and .. entries
2853                self.initialize_directory(dir_cluster, actual_parent_cluster)?;
2854
2855                Arc::new(Fat32Node::new_directory(name.clone(), file_id, dir_cluster))
2856            }
2857            _ => {
2858                return Err(FileSystemError::new(
2859                    FileSystemErrorKind::NotSupported,
2860                    "Unsupported file type for FAT32",
2861                ));
2862            }
2863        };
2864
2865        // Set filesystem reference using the parent's filesystem
2866        if let Some(fs) = fat32_parent.filesystem() {
2867            if let Some(fs_strong) = fs.upgrade() {
2868                let fs_weak = Arc::downgrade(&fs_strong);
2869                new_node.set_filesystem(fs_weak);
2870            }
2871        }
2872
2873        // Set parent reference
2874        {
2875            let parent_arc: Arc<Fat32Node> = Arc::new(fat32_parent.clone());
2876            let parent_weak = Arc::downgrade(&parent_arc);
2877            *new_node.parent.write() = Some(parent_weak);
2878        }
2879
2880        // Write directory entry to the parent directory's cluster
2881        let parent_cluster = *fat32_parent.cluster.read();
2882        let actual_parent_cluster = if parent_cluster == 0 {
2883            self.root_cluster // Use root cluster for root directory
2884        } else {
2885            parent_cluster
2886        };
2887
2888        // #[cfg(test)]
2889        // {
2890        //     use crate::early_println;
2891        //     early_println!("[FAT32] Creating file '{}' in parent cluster {} (original: {})",
2892        //                   name, actual_parent_cluster, parent_cluster);
2893        // }
2894
2895        // Write directory entry to disk
2896        let node_cluster = match file_type {
2897            FileType::Directory => {
2898                // Get the cluster number from the created directory node
2899                *new_node
2900                    .as_any()
2901                    .downcast_ref::<Fat32Node>()
2902                    .unwrap()
2903                    .cluster
2904                    .read()
2905            }
2906            FileType::RegularFile => 0, // Files get clusters when written to
2907            _ => 0,
2908        };
2909
2910        self.write_directory_entry_with_name(
2911            actual_parent_cluster,
2912            name,
2913            node_cluster,
2914            0,
2915            file_type == FileType::Directory,
2916        )?;
2917
2918        // Add to parent directory (in-memory)
2919        {
2920            let mut children = fat32_parent.children.write();
2921            children.insert(name.clone(), Arc::clone(&new_node) as Arc<dyn VfsNode>);
2922        }
2923
2924        Ok(new_node as Arc<dyn VfsNode>)
2925    }
2926
2927    fn remove(&self, parent: &Arc<dyn VfsNode>, name: &String) -> Result<(), FileSystemError> {
2928        let fat32_parent = parent.as_any().downcast_ref::<Fat32Node>().ok_or_else(|| {
2929            FileSystemError::new(
2930                FileSystemErrorKind::NotSupported,
2931                "Invalid node type for FAT32",
2932            )
2933        })?;
2934
2935        // Check if it's a directory
2936        match fat32_parent.file_type() {
2937            Ok(FileType::Directory) => {}
2938            Ok(_) => {
2939                return Err(FileSystemError::new(
2940                    FileSystemErrorKind::NotADirectory,
2941                    "Parent is not a directory",
2942                ));
2943            }
2944            Err(e) => return Err(e),
2945        }
2946
2947        // Get the file node to retrieve cluster information
2948        let file_node = {
2949            let children = fat32_parent.children.read();
2950            match children.get(name) {
2951                Some(node) => {
2952                    // Downcast to Fat32Node to get cluster information
2953                    node.as_any()
2954                        .downcast_ref::<Fat32Node>()
2955                        .ok_or_else(|| {
2956                            FileSystemError::new(
2957                                FileSystemErrorKind::NotSupported,
2958                                "Invalid node type for FAT32",
2959                            )
2960                        })?
2961                        .clone()
2962                }
2963                None => {
2964                    return Err(FileSystemError::new(
2965                        FileSystemErrorKind::NotFound,
2966                        format!("File '{}' not found", name),
2967                    ));
2968                }
2969            }
2970        };
2971
2972        // Get the starting cluster and deallocate the cluster chain
2973        let start_cluster = file_node.cluster();
2974        if start_cluster != 0 {
2975            self.free_cluster_chain(start_cluster)?;
2976        }
2977
2978        // Remove the directory entry from disk
2979        let parent_cluster = *fat32_parent.cluster.read();
2980        let actual_parent_cluster = if parent_cluster == 0 {
2981            self.root_cluster // Use root cluster for root directory
2982        } else {
2983            parent_cluster
2984        };
2985
2986        // #[cfg(test)]
2987        // {
2988        //     use crate::early_println;
2989        //     early_println!("[FAT32] Removing file '{}' from parent cluster {} (original: {})",
2990        //                   name, actual_parent_cluster, parent_cluster);
2991        // }
2992
2993        self.remove_directory_entry(actual_parent_cluster, name)?;
2994
2995        // Remove from parent directory (in-memory)
2996        {
2997            let mut children = fat32_parent.children.write();
2998            children.remove(name);
2999        }
3000
3001        // Invalidate page cache entries for this file to avoid stale data after delete/recreate
3002        {
3003            use crate::fs::vfs_v2::cache::CacheId;
3004            use crate::mem::page_cache::PageCacheManager;
3005            let fs_id = self.fs_id().get();
3006            let node_file_id = file_node.metadata.read().file_id;
3007            if node_file_id != 0 {
3008                let cid = CacheId::new((fs_id << 32) | node_file_id);
3009                PageCacheManager::global().invalidate(cid);
3010            }
3011            if start_cluster != 0 {
3012                let cid = CacheId::new((fs_id << 32) | (start_cluster as u64));
3013                PageCacheManager::global().invalidate(cid);
3014            }
3015        }
3016
3017        Ok(())
3018    }
3019
3020    fn readdir(
3021        &self,
3022        node: &Arc<dyn VfsNode>,
3023    ) -> Result<Vec<DirectoryEntryInternal>, FileSystemError> {
3024        let fat32_node = node.as_any().downcast_ref::<Fat32Node>().ok_or_else(|| {
3025            FileSystemError::new(
3026                FileSystemErrorKind::NotSupported,
3027                "Invalid node type for FAT32",
3028            )
3029        })?;
3030
3031        // Check if it's a directory
3032        match fat32_node.file_type() {
3033            Ok(FileType::Directory) => {}
3034            Ok(_) => {
3035                return Err(FileSystemError::new(
3036                    FileSystemErrorKind::NotADirectory,
3037                    "Not a directory",
3038                ));
3039            }
3040            Err(e) => return Err(e),
3041        }
3042
3043        // Load directory entries from disk if not already loaded
3044        let mut fat32_entries = Vec::new();
3045        let cluster = *fat32_node.cluster.read();
3046
3047        // #[cfg(test)]
3048        // {
3049        //     use crate::early_println;
3050        //     early_println!("[FAT32] Reading directory entries from cluster {}", cluster);
3051        // }
3052
3053        if cluster == 0 {
3054            // This is likely the root directory - handle FAT32 root directory differently
3055            // #[cfg(test)]
3056            // {
3057            //     use crate::early_println;
3058            //     early_println!("[FAT32] Reading FAT32 root directory (cluster 0, using root_cluster {})", self.root_cluster);
3059            // }
3060            self.read_directory_entries(self.root_cluster, &mut fat32_entries)?;
3061        } else {
3062            self.read_directory_entries(cluster, &mut fat32_entries)?;
3063        }
3064
3065        // Convert Fat32DirectoryEntryInternal to DirectoryEntryInternal
3066        let mut entries = Vec::new();
3067        for fat32_entry in fat32_entries {
3068            let file_type = if fat32_entry.is_directory() {
3069                FileType::Directory
3070            } else {
3071                FileType::RegularFile
3072            };
3073
3074            let entry = DirectoryEntryInternal {
3075                name: fat32_entry.name(),
3076                file_type,
3077                file_id: fat32_entry.cluster() as u64, // Use cluster as file_id
3078            };
3079            entries.push(entry);
3080        }
3081
3082        // #[cfg(test)]
3083        // {
3084        //     use crate::early_println;
3085        //     early_println!("[FAT32] Found {} directory entries", entries.len());
3086        // }
3087
3088        Ok(entries)
3089    }
3090
3091    fn root_node(&self) -> Arc<dyn VfsNode> {
3092        Arc::clone(&*self.root.read()) as Arc<dyn VfsNode>
3093    }
3094
3095    fn name(&self) -> &str {
3096        &self.name
3097    }
3098
3099    fn as_any(&self) -> &dyn Any {
3100        self
3101    }
3102}
3103
3104/// Register the FAT32 driver with the filesystem driver manager
3105fn register_driver() {
3106    let fs_driver_manager = get_fs_driver_manager();
3107    fs_driver_manager.register_driver(Box::new(Fat32Driver));
3108}
3109
3110driver_initcall!(register_driver);
3111
3112/// Helper enum for writing directory entries with LFN support
3113#[derive(Debug, Clone)]
3114enum EntryToWrite {
3115    LFN(structures::Fat32LFNEntry),
3116    SFN(structures::Fat32DirectoryEntry),
3117}