ext2/
lib.rs

1#![no_std]
2#![feature(error_in_core)]
3
4extern crate alloc;
5
6use core::fmt::{Debug, Display, Formatter};
7use core::num::NonZeroU32;
8use filesystem::BlockDevice;
9
10mod superblock;
11
12use crate::superblock::Superblock;
13pub use superblock::SuperblockDecodeError;
14
15#[derive(Debug)]
16struct Ext2InodeAddress(NonZeroU32);
17
18impl Ext2InodeAddress {
19    pub fn new(n: u32) -> Option<Self> {
20        Some(Self(NonZeroU32::new(n)?))
21    }
22}
23
24pub struct Ext2Fs<T> {
25    block_device: T,
26    superblock: Superblock,
27}
28
29#[derive(Debug, Copy, Clone, Eq, PartialEq)]
30pub enum Error {
31    InvalidSuperblock(SuperblockDecodeError),
32    UnableToReadSuperblock,
33}
34
35impl Display for Error {
36    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
37        Debug::fmt(&self, f)
38    }
39}
40
41impl core::error::Error for Error {}
42
43impl From<SuperblockDecodeError> for Error {
44    fn from(value: SuperblockDecodeError) -> Self {
45        Self::InvalidSuperblock(value)
46    }
47}
48
49impl<T> Ext2Fs<T>
50where
51    T: BlockDevice,
52{
53    pub fn try_new(block_device: T) -> Result<Self, Error> {
54        let mut superblock_data = [0_u8; 1024];
55        block_device
56            .read_at(1024, &mut superblock_data)
57            .map_err(|_| Error::UnableToReadSuperblock)?;
58
59        let superblock = Superblock::try_from(superblock_data)?;
60
61        Ok(Self {
62            block_device,
63            superblock,
64        })
65    }
66}