Serenity Operating System
at master 94 lines 3.7 kB view raw
1/* 2 * Copyright (c) 2022, Undefine <undefine@undefine.pl> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <Kernel/Debug.h> 8#include <Kernel/FileSystem/FATFS/FileSystem.h> 9#include <Kernel/FileSystem/FATFS/Inode.h> 10 11namespace Kernel { 12 13ErrorOr<NonnullLockRefPtr<FileSystem>> FATFS::try_create(OpenFileDescription& file_description) 14{ 15 return TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) FATFS(file_description))); 16} 17 18FATFS::FATFS(OpenFileDescription& file_description) 19 : BlockBasedFileSystem(file_description) 20{ 21} 22 23bool FATFS::is_initialized_while_locked() 24{ 25 VERIFY(m_lock.is_locked()); 26 return !m_root_inode.is_null(); 27} 28 29ErrorOr<void> FATFS::initialize_while_locked() 30{ 31 VERIFY(m_lock.is_locked()); 32 VERIFY(!is_initialized_while_locked()); 33 34 m_boot_record = TRY(KBuffer::try_create_with_size("FATFS: Boot Record"sv, m_logical_block_size)); 35 auto boot_record_buffer = UserOrKernelBuffer::for_kernel_buffer(m_boot_record->data()); 36 TRY(raw_read(0, boot_record_buffer)); 37 38 if constexpr (FAT_DEBUG) { 39 dbgln("FATFS: oem_identifier: {}", boot_record()->oem_identifier); 40 dbgln("FATFS: bytes_per_sector: {}", boot_record()->bytes_per_sector); 41 dbgln("FATFS: sectors_per_cluster: {}", boot_record()->sectors_per_cluster); 42 dbgln("FATFS: reserved_sector_count: {}", boot_record()->reserved_sector_count); 43 dbgln("FATFS: fat_count: {}", boot_record()->fat_count); 44 dbgln("FATFS: root_directory_entry_count: {}", boot_record()->root_directory_entry_count); 45 dbgln("FATFS: media_descriptor_type: {}", boot_record()->media_descriptor_type); 46 dbgln("FATFS: sectors_per_track: {}", boot_record()->sectors_per_track); 47 dbgln("FATFS: head_count: {}", boot_record()->head_count); 48 dbgln("FATFS: hidden_sector_count: {}", boot_record()->hidden_sector_count); 49 dbgln("FATFS: sector_count: {}", boot_record()->sector_count); 50 dbgln("FATFS: sectors_per_fat: {}", boot_record()->sectors_per_fat); 51 dbgln("FATFS: flags: {}", boot_record()->flags); 52 dbgln("FATFS: fat_version: {}", boot_record()->fat_version); 53 dbgln("FATFS: root_directory_cluster: {}", boot_record()->root_directory_cluster); 54 dbgln("FATFS: fs_info_sector: {}", boot_record()->fs_info_sector); 55 dbgln("FATFS: backup_boot_sector: {}", boot_record()->backup_boot_sector); 56 dbgln("FATFS: drive_number: {}", boot_record()->drive_number); 57 dbgln("FATFS: volume_id: {}", boot_record()->volume_id); 58 } 59 60 if (boot_record()->signature != signature_1 && boot_record()->signature != signature_2) { 61 dbgln("FATFS: Invalid signature"); 62 return EINVAL; 63 } 64 65 m_logical_block_size = boot_record()->bytes_per_sector; 66 set_block_size(m_logical_block_size); 67 68 u32 root_directory_sectors = ((boot_record()->root_directory_entry_count * sizeof(FATEntry)) + (m_logical_block_size - 1)) / m_logical_block_size; 69 m_first_data_sector = boot_record()->reserved_sector_count + (boot_record()->fat_count * boot_record()->sectors_per_fat) + root_directory_sectors; 70 71 TRY(BlockBasedFileSystem::initialize_while_locked()); 72 73 FATEntry root_entry {}; 74 75 root_entry.first_cluster_low = boot_record()->root_directory_cluster & 0xFFFF; 76 root_entry.first_cluster_high = boot_record()->root_directory_cluster >> 16; 77 78 root_entry.attributes = FATAttributes::Directory; 79 m_root_inode = TRY(FATInode::create(*this, root_entry)); 80 81 return {}; 82} 83 84Inode& FATFS::root_inode() 85{ 86 return *m_root_inode; 87} 88 89BlockBasedFileSystem::BlockIndex FATFS::first_block_of_cluster(u32 cluster) const 90{ 91 return ((cluster - first_data_cluster) * boot_record()->sectors_per_cluster) + m_first_data_sector; 92} 93 94}