feat(ext4): seek, rmdir (e2fsck-clean)

This commit is contained in:
2026-10-27 23:53:13 +01:00
parent 24b0734c73
commit eb9e3efaac
4 changed files with 93 additions and 0 deletions

View File

@@ -60,6 +60,15 @@ impl<B: BlockDevice> Ext4<B> {
}
}
/// One directory fewer in `inode`'s block group.
fn uncount_dir(&mut self, inode: u32) {
let (bg, spb) = (self.sb.inode_block_group(inode), self.sb.sectors_per_block());
if let Some(mut d) = bgd::BlockGroupDescriptor::read(&mut self.device, self.gdt_block, bg, spb) {
d.used_dirs_count = d.used_dirs_count.saturating_sub(1);
d.write_back(&mut self.device, self.gdt_block, bg, spb);
}
}
/// The disk, for a test to look at what was written.
pub fn into_device(self) -> B {
self.device
@@ -361,4 +370,40 @@ impl<B: BlockDevice> FileSystem for Ext4<B> {
true
}
fn seek(&mut self, handle: FileHandle, offset: usize) -> bool {
match self.open_files.get_mut(handle.raw() as usize).and_then(Option::as_mut) {
Some(f) if offset <= f.size => {
f.offset = offset;
true
}
_ => false,
}
}
fn rmdir(&mut self, path: &[u8]) -> bool {
let Some((parent_num, name)) = self.resolve_parent(path) else { return false };
let Some(parent) = self.read_inode(parent_num) else { return false };
let Some(child_num) = dir::find_entry(&mut self.device, &self.sb, &parent, name) else { return false };
let Some(child) = self.read_inode(child_num).filter(Inode::is_dir) else { return false };
// Empty: nothing but `.` and `..`.
let mut entries = [DirEntry::empty(); 3];
let Some(n) = dir::list_entries(&mut self.device, &self.sb, &child, &mut entries) else { return false };
if entries[..n].iter().any(|e| e.name.as_bytes() != b"." && e.name.as_bytes() != b"..") {
return false;
}
if dir::remove_entry(&mut self.device, &self.sb, &parent, name).is_none() {
return false;
}
self.free_all_blocks(&child);
self.clear_inode(child_num);
self.free_inode(child_num);
self.uncount_dir(child_num);
// Its `..` linked the parent.
if let Some(mut p) = self.read_inode(parent_num) {
p.links_count = p.links_count.saturating_sub(1);
self.write_inode(parent_num, &p);
}
true
}
}