Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 55 additions & 18 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,22 @@ struct NullFS;
impl Filesystem for NullFS {}

// This is the total capacity of the backing storage for the file system
// this includes the space used for the superblock, free object bitmaps, and file data and metadata
const FS_SIZE_BYTES: u64 = 1u64 * (0b1 << 30) as u64; // 1 GB, toy size
// this includes the space used for the FSMetadata, free object bitmaps, and file data and metadata
const FS_SIZE_BYTES: u64 = 1u64 * (0b1 << 30) as u64; // 1 GB
const BLK_SIZE_BYTES: u64 = 4096u64;
// some blocks reserved for FSMetadata, free inode and data block bitmaps, and inode table
const RESERVED_DATA_BLKS: u32 = 3;
const NUM_DATA_BLKS: u32 = (FS_SIZE_BYTES / BLK_SIZE_BYTES) as u32;
const FREE_BLK_BMAP_SIZE_BYTES: usize = ((NUM_DATA_BLKS + 7) / 8) as usize;

// Inodes
const MAX_NUM_INODES: u32 = 10; // toy size
const MAX_NUM_INODES: u32 = 10;
const RESERVED_INODES: u32 = 2; // 0: null inode, 1: root
const FREE_INODE_BMAP_SIZE_BYTES: usize = ((MAX_NUM_INODES + 7) / 8) as usize;
const NUM_INO_DIRECT_PTR: usize = 12;

// free inode bitmap can begin right after this struct and inode table can follow immediately after
struct SuperBlock {
struct FSMetadata {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you change the name of the Superblock to FSMetadata? The traditional name is Superblock. I don't obect the change, just want to know why.

ino_count: u32,
blk_count: u32,
free_blk_count: u32,
Expand All @@ -29,20 +32,25 @@ struct SuperBlock {
wtime: u64,
}

impl Default for SuperBlock {
impl Default for FSMetadata {
fn default() -> Self {
Self {
ino_count: MAX_NUM_INODES,
blk_count: NUM_DATA_BLKS,
free_blk_count: NUM_DATA_BLKS - 3u32, // first three blocks are reserved for FS metadata
free_ino_count: MAX_NUM_INODES - 1, // first inode is reserved for the root
free_blk_count: NUM_DATA_BLKS - RESERVED_DATA_BLKS,
free_ino_count: MAX_NUM_INODES - RESERVED_INODES,
super_blk_no: 0,
mtime: 0,
wtime: 0,
}
}
}

#[derive(Clone, Copy)]
struct Block {
data: [u8; BLK_SIZE_BYTES as usize],
}

trait FreeObjectBitmap<const N: usize> {
fn map(&self) -> &BitArray<[u8; N], Lsb0>;

Expand All @@ -51,17 +59,25 @@ trait FreeObjectBitmap<const N: usize> {
}
}

#[derive(Default)]
struct FreeBlockBitmap {
map: BitArray<[u8; FREE_BLK_BMAP_SIZE_BYTES], Lsb0>,
}

impl Default for FreeBlockBitmap {
fn default() -> Self {
let mut map = BitArray::default();
map[0..(RESERVED_DATA_BLKS as usize)].fill(true);
Self { map }
}
}

impl FreeObjectBitmap<FREE_BLK_BMAP_SIZE_BYTES> for FreeBlockBitmap {
fn map(&self) -> &BitArray<[u8; FREE_BLK_BMAP_SIZE_BYTES], Lsb0> {
&self.map
}
}

#[derive(Clone, Copy)]
struct Inode {
ino_id: u64, // inode number
size: u64, // file size
Expand All @@ -75,29 +91,50 @@ struct Inode {
tri_indirect_blk: u32,
}

#[derive(Default)]
struct FreeInodeBitmap {
map: BitArray<[u8; FREE_INODE_BMAP_SIZE_BYTES], Lsb0>,
}

impl Default for FreeInodeBitmap {
fn default() -> Self {
let mut map = BitArray::default();
map[0..(RESERVED_INODES as usize)].fill(true);
Self { map }
}
}

impl FreeObjectBitmap<FREE_INODE_BMAP_SIZE_BYTES> for FreeInodeBitmap {
fn map(&self) -> &BitArray<[u8; FREE_INODE_BMAP_SIZE_BYTES], Lsb0> {
&self.map
}
}

#[derive(Default)]
struct FSState {
superblk: SuperBlock,
free_blks: FreeBlockBitmap,
inode_bitmap: FreeInodeBitmap,
inodes: Vec<Inode>,
blks: Vec<u8>,
metadata: FSMetadata,
free_inode_bitmap: FreeInodeBitmap,
inodes: [Option<Inode>; MAX_NUM_INODES as usize],
free_blk_bitmap: FreeBlockBitmap,
blks: [Option<Block>; NUM_DATA_BLKS as usize],
}

impl FSState {
fn alloc_inode(&mut self) -> Option<u64> {
None
// we have to implement Default ourselves here
// because the Default trait is not implemented for static arrays
// above a certain size
impl Default for FSState {
fn default() -> Self {
let mut metadata = FSMetadata::default();
let free_inode_bitmap = FreeInodeBitmap::default();
let mut inodes = [None; MAX_NUM_INODES as usize];
let free_blk_bitmap = FreeBlockBitmap::default();
let mut blks = [None; NUM_DATA_BLKS as usize];

Self {
metadata,
free_inode_bitmap,
inodes,
free_blk_bitmap,
blks,
}
}
}

Expand Down