ext2: dedup block/inode free code

This commit is contained in:
Mark Poliakov 2025-01-02 17:20:24 +02:00
parent b0aab12bf3
commit f13f756c20

View File

@ -4,9 +4,38 @@ use yggdrasil_abi::io::FileType;
use crate::{BlockGroupDescriptor, Ext2Fs, ExtendedSuperblock, Inode}; use crate::{BlockGroupDescriptor, Ext2Fs, ExtendedSuperblock, Inode};
impl Ext2Fs { impl Ext2Fs {
async fn free<
F: FnOnce(&mut BlockGroupDescriptor) -> u32,
G: FnOnce(&mut ExtendedSuperblock),
>(
&self,
element_index: u32,
group_index: u32,
descriptor_mapper: F,
superblock_mapper: G,
) -> Result<(), Error> {
let bitmap = self
.with_bgdt_entry_mut(group_index, |descriptor| Ok(descriptor_mapper(descriptor)))
.await?;
self.with_block_mut(bitmap, size_of::<u32>(), |bitmap| {
let index = (element_index / 8) as usize;
let bit = 1u8 << (element_index % 8);
if bitmap[index] & bit == 0 {
log::warn!("Trying to free an unallocated element #{element_index}");
}
bitmap[index] &= !bit;
Ok(())
})
.await?;
self.with_superblock_mut(|sb| Ok(superblock_mapper(sb)))
.await?;
Ok(())
}
async fn allocate< async fn allocate<
F: Fn(&mut BlockGroupDescriptor) -> Option<(u32, u32)>, F: Fn(&mut BlockGroupDescriptor) -> Option<(u32, u32)>,
G: Fn(&mut ExtendedSuperblock), G: FnOnce(&mut ExtendedSuperblock),
>( >(
&self, &self,
descriptor_mapper: F, descriptor_mapper: F,
@ -95,38 +124,26 @@ impl Ext2Fs {
// Free inode blocks // Free inode blocks
inode.resize(self, 0).await?; inode.resize(self, 0).await?;
inode.dtime = real_time().seconds as u32; inode.dtime = real_time().seconds as u32;
self.write_inode(ino, inode).await?; self.write_inode(ino, inode).await?;
let inode_index = ino - 1; let inode_index = ino - 1;
let group_index = inode_index / self.block_group_inode_count; let group_index = inode_index / self.block_group_inode_count;
self.free(
let bitmap = self inode_index,
.with_bgdt_entry_mut(group_index, |descriptor| { group_index,
|descriptor| {
if is_directory { if is_directory {
descriptor.directories = descriptor.directories.saturating_sub(1); descriptor.directories = descriptor.directories.saturating_sub(1);
} }
descriptor.unallocated_inodes += 1; descriptor.unallocated_inodes += 1;
Ok(descriptor.inode_usage_bitmap) descriptor.inode_usage_bitmap
}) },
.await?; |superblock| {
self.with_block_mut(bitmap, size_of::<u32>(), |bitmap| { superblock.total_unallocated_inodes += 1;
let index = (inode_index / 8) as usize; },
let bit = 1u8 << (inode_index % 8); )
if bitmap[index] & bit == 0 {
log::warn!("Trying to free an unallocated inode #{ino}");
}
bitmap[index] &= !bit;
Ok(())
})
.await?;
self.with_superblock_mut(|sb| {
sb.total_unallocated_inodes += 1;
Ok(())
})
.await?; .await?;
Ok(()) Ok(())
@ -161,28 +178,17 @@ impl Ext2Fs {
} }
let group_index = block_index / self.block_group_block_count; let group_index = block_index / self.block_group_block_count;
let bitmap = self self.free(
.with_bgdt_entry_mut(group_index, |descriptor| { block_index,
group_index,
|descriptor| {
descriptor.unallocated_blocks += 1; descriptor.unallocated_blocks += 1;
Ok(descriptor.block_usage_bitmap) descriptor.block_usage_bitmap
}) },
.await?; |superblock| {
self.with_block_mut(bitmap, size_of::<u32>(), |bitmap| { superblock.total_unallocated_blocks += 1;
let index = (block_index / 8) as usize; },
let bit = 1u8 << (block_index % 8); )
if bitmap[index] & bit == 0 {
log::warn!("Freeing a block #{block_index}, but bitmap says it's not allocated");
}
bitmap[index] &= !bit;
Ok(())
})
.await?;
self.with_superblock_mut(|sb| {
sb.total_unallocated_blocks += 1;
Ok(())
})
.await?; .await?;
Ok(()) Ok(())