ext2: dedup block/inode free code
This commit is contained in:
parent
b0aab12bf3
commit
f13f756c20
@ -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(())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user