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};
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<
F: Fn(&mut BlockGroupDescriptor) -> Option<(u32, u32)>,
G: Fn(&mut ExtendedSuperblock),
G: FnOnce(&mut ExtendedSuperblock),
>(
&self,
descriptor_mapper: F,
@ -95,38 +124,26 @@ impl Ext2Fs {
// Free inode blocks
inode.resize(self, 0).await?;
inode.dtime = real_time().seconds as u32;
self.write_inode(ino, inode).await?;
let inode_index = ino - 1;
let group_index = inode_index / self.block_group_inode_count;
let bitmap = self
.with_bgdt_entry_mut(group_index, |descriptor| {
self.free(
inode_index,
group_index,
|descriptor| {
if is_directory {
descriptor.directories = descriptor.directories.saturating_sub(1);
}
descriptor.unallocated_inodes += 1;
Ok(descriptor.inode_usage_bitmap)
})
.await?;
self.with_block_mut(bitmap, size_of::<u32>(), |bitmap| {
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(())
})
descriptor.inode_usage_bitmap
},
|superblock| {
superblock.total_unallocated_inodes += 1;
},
)
.await?;
Ok(())
@ -161,28 +178,17 @@ impl Ext2Fs {
}
let group_index = block_index / self.block_group_block_count;
let bitmap = self
.with_bgdt_entry_mut(group_index, |descriptor| {
self.free(
block_index,
group_index,
|descriptor| {
descriptor.unallocated_blocks += 1;
Ok(descriptor.block_usage_bitmap)
})
.await?;
self.with_block_mut(bitmap, size_of::<u32>(), |bitmap| {
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(())
})
descriptor.block_usage_bitmap
},
|superblock| {
superblock.total_unallocated_blocks += 1;
},
)
.await?;
Ok(())