added superblock, group descriptors, and mmp structured

This commit is contained in:
Moritz Gmeiner 2025-07-18 13:59:34 +02:00
commit 75d23682c0
10 changed files with 824 additions and 2 deletions

View file

@ -1 +1,94 @@
use std::io::SeekFrom;
pub use crate::superblock::{SUPERBLOCK_SIZE, Superblock};
pub use crate::utils::group_has_superblock;
mod group_descriptor;
mod mmp;
mod superblock;
mod utils;
pub trait FileLike {
fn read_at_offset(&mut self, offset: u64, buf: &mut [u8]) -> anyhow::Result<()>;
fn write_at_offset(&mut self, offset: u64, bytes: &[u8]) -> anyhow::Result<()>;
fn read_at_offset_const<const N: usize>(&mut self, offset: u64) -> anyhow::Result<[u8; N]> {
let mut buf = [0; N];
self.read_at_offset(offset, &mut buf)?;
Ok(buf)
}
}
impl<F: std::io::Read + std::io::Write + std::io::Seek> FileLike for F {
fn read_at_offset(&mut self, offset: u64, buf: &mut [u8]) -> anyhow::Result<()> {
self.seek(SeekFrom::Start(offset))?;
self.read_exact(buf)?;
Ok(())
}
fn write_at_offset(&mut self, offset: u64, bytes: &[u8]) -> anyhow::Result<()> {
self.seek(SeekFrom::Start(offset))?;
self.write_all(bytes)?;
Ok(())
}
}
// impl FileLike for &mut [u8] {
// fn read_at_offset(&mut self, offset: u64, buf: &mut [u8]) -> anyhow::Result<()> {
// anyhow::ensure!(
// offset as usize + buf.len() <= self.len(),
// "reading {} bytes at offset {} is out of bounds for slice of len {}",
// buf.len(),
// offset,
// self.len()
// );
//
// buf.copy_from_slice(&self[offset as usize..][..buf.len()]);
//
// Ok(())
// }
//
// fn write_at_offset(&mut self, offset: u64, bytes: &[u8]) -> anyhow::Result<()> {
// anyhow::ensure!(
// offset as usize + bytes.len() <= self.len(),
// "writing {} bytes at offset {} is out of bounds for slice of len {}",
// bytes.len(),
// offset,
// self.len()
// );
//
// self[offset as usize..][..bytes.len()].copy_from_slice(bytes);
//
// Ok(())
// }
// }
pub struct Ext4Fs<F: FileLike> {
#[allow(dead_code)]
file: F,
superblock: superblock::Superblock,
}
impl<F: FileLike> Ext4Fs<F> {
pub fn load(file: F) -> Result<Ext4Fs<F>, anyhow::Error> {
let mut file = file;
let superblock_bytes = file.read_at_offset_const::<SUPERBLOCK_SIZE>(1024)?;
let superblock = Superblock::from_bytes(&superblock_bytes)?;
Ok(Ext4Fs { file, superblock })
}
pub fn super_block(&self) -> &Superblock {
&self.superblock
}
}