mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-11 12:06:07 +00:00
Kernel/FATFS: Keep the FSInfo sector's free cluster count in sync
This commit is contained in:
parent
bd76dd2dc2
commit
32692f032c
Notes:
sideshowbarker
2024-07-17 07:19:27 +09:00
Author: https://github.com/implicitfield
Commit: 32692f032c
Pull-request: https://github.com/SerenityOS/serenity/pull/23907
Reviewed-by: https://github.com/Hendiadyoin1
Reviewed-by: https://github.com/cqundefine
Reviewed-by: https://github.com/nico
Reviewed-by: https://github.com/timschumi ✅
3 changed files with 27 additions and 0 deletions
|
@ -371,6 +371,17 @@ u32 FATFS::end_of_chain_marker() const
|
|||
}
|
||||
}
|
||||
|
||||
ErrorOr<void> FATFS::set_free_cluster_count(u32 value)
|
||||
{
|
||||
VERIFY(m_fat_version == FATVersion::FAT32);
|
||||
|
||||
m_fs_info.last_known_free_cluster_count = value;
|
||||
auto fs_info_buffer = UserOrKernelBuffer::for_kernel_buffer(bit_cast<u8*>(&m_fs_info));
|
||||
TRY(write_block(m_parameter_block->dos7_bpb()->fs_info_sector, fs_info_buffer, sizeof(m_fs_info)));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<u32> FATFS::allocate_cluster()
|
||||
{
|
||||
u32 start_cluster;
|
||||
|
@ -393,6 +404,10 @@ ErrorOr<u32> FATFS::allocate_cluster()
|
|||
for (u32 i = start_cluster; i < m_parameter_block->sector_count() / m_parameter_block->common_bpb()->sectors_per_cluster; i++) {
|
||||
if (TRY(fat_read(i)) == 0) {
|
||||
dbgln_if(FAT_DEBUG, "FATFS: Allocating cluster {}", i);
|
||||
|
||||
if (m_fat_version == FATVersion::FAT32 && m_fs_info.last_known_free_cluster_count != fs_info_data_unknown)
|
||||
TRY(set_free_cluster_count(m_fs_info.last_known_free_cluster_count - 1));
|
||||
|
||||
TRY(fat_write(i, end_of_chain_marker()));
|
||||
return i;
|
||||
}
|
||||
|
@ -401,6 +416,14 @@ ErrorOr<u32> FATFS::allocate_cluster()
|
|||
return Error::from_errno(ENOSPC);
|
||||
}
|
||||
|
||||
ErrorOr<void> FATFS::notify_cluster_freed()
|
||||
{
|
||||
if (m_fat_version == FATVersion::FAT32 && m_fs_info.last_known_free_cluster_count != fs_info_data_unknown)
|
||||
TRY(set_free_cluster_count(m_fs_info.last_known_free_cluster_count + 1));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<u32> FATFS::fat_read(u32 cluster)
|
||||
{
|
||||
dbgln_if(FAT_DEBUG, "FATFS: Reading FAT entry for cluster {}", cluster);
|
||||
|
|
|
@ -87,7 +87,10 @@ private:
|
|||
static constexpr u32 first_data_cluster = 2;
|
||||
|
||||
FatBlockSpan first_block_of_cluster(u32 cluster) const;
|
||||
|
||||
ErrorOr<void> set_free_cluster_count(u32);
|
||||
ErrorOr<u32> allocate_cluster();
|
||||
ErrorOr<void> notify_cluster_freed();
|
||||
|
||||
size_t fat_offset_for_cluster(u32 cluster) const;
|
||||
|
||||
|
|
|
@ -346,6 +346,7 @@ ErrorOr<void> FATInode::remove_last_cluster_from_chain()
|
|||
|
||||
dbgln_if(FAT_DEBUG, "FATInode[{}]::remove_last_cluster_from_chain(): freeing cluster {}", identifier(), last_cluster);
|
||||
|
||||
TRY(fs().notify_cluster_freed());
|
||||
m_cluster_list.remove(m_cluster_list.size() - 1);
|
||||
|
||||
if (m_cluster_list.is_empty() || (m_cluster_list.size() == 1 && first_cluster() <= 1)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue