From 95d8d84eef645b52d92fd3fb8fdea7aed1f6d474 Mon Sep 17 00:00:00 2001 From: Chuyan Zhang Date: Fri, 17 Nov 2023 11:40:33 -0800 Subject: Layer 1 incomplete --- src/disk/bitmap.rs | 13 ++-- src/disk/data_block.rs | 94 +++++++++++++++++++++++++ src/disk/inode.rs | 184 ++++++++++++++++++++++++++----------------------- src/disk/mod.rs | 4 +- 4 files changed, 205 insertions(+), 90 deletions(-) create mode 100644 src/disk/data_block.rs (limited to 'src/disk') diff --git a/src/disk/bitmap.rs b/src/disk/bitmap.rs index a5a9cc4..d5a8fe9 100644 --- a/src/disk/bitmap.rs +++ b/src/disk/bitmap.rs @@ -19,20 +19,25 @@ impl Bitmap { dirty_blocks: Vec::new(), } } - pub fn allocate(&mut self) -> usize { + pub fn allocate(&mut self) -> Option { for (i, byte) in self.data.iter_mut().enumerate() { let leading_ones = byte.leading_ones(); if leading_ones != 8 { *byte |= (1 << (7 - leading_ones)) as u8; self.dirty_blocks.push(i / BLOCK_SIZE); - return i * 8 + leading_ones as usize; + return Some(i * 8 + leading_ones as usize); } } - panic!("No more space for allocation!") + None + // panic!("No more space for allocation!") } pub fn query(&self, index: usize) -> bool { - self.data[index / 8] & ((1 << (7 - index % 8)) as u8) != 0 + if index == 0 { + false + } else { + self.data[index / 8] & ((1 << (7 - index % 8)) as u8) != 0 + } } fn write_back(&mut self) { diff --git a/src/disk/data_block.rs b/src/disk/data_block.rs new file mode 100644 index 0000000..2160b91 --- /dev/null +++ b/src/disk/data_block.rs @@ -0,0 +1,94 @@ +pub trait Block: Default {} + +#[derive(Default)] +pub struct DataBlock([u8; 4096]); +impl Block for DataBlock {} + +const FULL_MAP: u32 = 0b111_111_111_111_111; + +#[derive(Default)] +pub struct DirectoryBlock { + entries: [[u8; 256]; 15], + inode_ids: [usize; 15], + occupancy_map: u32, + reserved: [u8; 132], +} + +impl Block for DirectoryBlock {} + +impl DirectoryBlock { + fn vacant(&self) -> bool { + self.occupancy_map & FULL_MAP != FULL_MAP + } + + fn first_free(&self) -> Option { + todo!() + } + + fn mark_busy(&mut self, entry_id: usize) { + todo!() + } + + /// 需要判断 entry_name.len() <= 255 + pub fn write_entry(&mut self, entry_name: &[u8], entry_inode_id: usize) -> Option { + if let Some(entry_id) = self.first_free() { + self.mark_busy(entry_id); + self.entries[entry_id].copy_from_slice(entry_name); + self.inode_ids[entry_id] = entry_inode_id; + Some(entry_id) + } else { + None + } + } +} + +#[derive(Default)] +pub struct IndirectBlock { + pub entries: [u32; 1024], +} + +impl Block for IndirectBlock {} + +impl IndirectBlock { + pub fn full(&self) -> bool { + todo!() + } + + pub fn allocate(&mut self) -> Option { + todo!() + } +} + +#[derive(Default)] +pub struct DoubleIndirectBlock { + pub indirect: [u32; 1024], +} + +impl Block for DoubleIndirectBlock {} + +impl DoubleIndirectBlock { + pub fn full(&self) -> bool { + todo!() + } + + pub fn allocate(&mut self) -> Option { + todo!() + } +} + +#[derive(Default)] +pub struct TripleIndirectBlock { + pub double_indirect: [u32; 1024], +} + +impl Block for TripleIndirectBlock {} + +impl TripleIndirectBlock { + pub fn full(&self) -> bool { + todo!() + } + + pub fn allocate(&mut self) -> Option { + todo!() + } +} diff --git a/src/disk/inode.rs b/src/disk/inode.rs index f38508a..6adc75d 100644 --- a/src/disk/inode.rs +++ b/src/disk/inode.rs @@ -42,111 +42,125 @@ pub struct Inode { mode: InodeMode, uid: u32, size: u32, - atime: u32, // time in seconds - ctime: u32, - mtime: u32, - dtime: u32, + atime: u32, // access time, in seconds + ctime: u32, // change time, in seconds + mtime: u32, // modify time, in seconds + crtime: u32, // create time, in seconds gid: u32, - n_links: u16, - n_blocks: u32, + pub n_links: u16, + pub n_blocks: u32, flags: u32, // TODO: do we actually need this? maybe just return 0 - direct: [u32; DIRECT_NUMBER], - single_indirect: u32, - double_indirect: u32, - triple_indirect: u32, + pub direct: [u32; DIRECT_NUMBER], + pub single_indirect: u32, + pub double_indirect: u32, + pub triple_indirect: u32, generation: u32, file_acl: u32, dir_acl: u32, // TODO do we have to implement ACL......? } impl Inode { - pub fn directory() -> Self { + fn new( + mode: InodeMode, + uid: u32, + gid: u32, + time: u32, + flags: u32, + generation: u32, + file_acl: u32, + dir_acl: u32, + ) -> Self { Self { - mode: InodeMode::IFDIR - | InodeMode::IRUSR - | InodeMode::IWUSR - | InodeMode::IXUSR - | InodeMode::IRGRP - | InodeMode::IXGRP - | InodeMode::IROTH - | InodeMode::IXOTH, - // Directory, 755 permissions - uid: 0, + mode, + uid, size: 0, - atime: 0, - ctime: 0, - mtime: 0, - dtime: 0, - gid: 0, + atime: time, + ctime: time, + mtime: time, + crtime: time, + gid, n_links: 0, n_blocks: 0, - flags: 0, + flags, direct: [0; DIRECT_NUMBER], single_indirect: 0, double_indirect: 0, triple_indirect: 0, - generation: 0, - file_acl: 0, - dir_acl: 0, + generation, + file_acl, + dir_acl, } } - pub fn file() -> Self { - Self { - mode: InodeMode::IFREG - | InodeMode::IRUSR - | InodeMode::IWUSR - | InodeMode::IXUSR - | InodeMode::IRGRP - | InodeMode::IXGRP - | InodeMode::IROTH - | InodeMode::IXOTH, - // RegularFile, 755 permissions - uid: 0, - size: 0, - atime: 0, - ctime: 0, - mtime: 0, - dtime: 0, - gid: 0, - n_links: 0, - n_blocks: 0, - flags: 0, - direct: [0; DIRECT_NUMBER], - single_indirect: 0, - double_indirect: 0, - triple_indirect: 0, - generation: 0, - file_acl: 0, - dir_acl: 0, - } + pub fn make_inode( + permissions: u16, + mode: InodeMode, + uid: u32, + gid: u32, + time: u32, + flags: u32, + generation: u32, + file_acl: u32, + dir_acl: u32, + ) -> Self { + Self::new( + InodeMode(permissions) | mode, + uid, + gid, + time, + flags, + generation, + file_acl, + dir_acl, + ) } -} -// -// #[repr(C)] -// #[derive(Debug, Default)] -// pub struct FileInode { -// file_size: u32, -// direct_blocks: [u32; DIRECT_NUMBER], -// indirect_block: u32, -// doubly_indirect_block: u32, -// } // sizeof(FileInode) == 124 bytes -// -// #[repr(C)] -// #[derive(Debug, Default)] -// pub struct DirectoryInode { -// child_number: u32, -// direct_blocks: [u32; DIRECT_NUMBER], -// indirect_block: u32, -// doubly_indirect_block: u32, -// } // sizeof(FileInode) == 124 bytes -// -// #[repr(C)] -// #[derive(Debug)] -// pub enum Inode { -// File(FileInode), -// Directory(DirectoryInode), -// } // sizeof(Inode) == 128 bytes + pub fn directory( + permissions: u16, + uid: u32, + gid: u32, + time: u32, + flags: u32, + generation: u32, + file_acl: u32, + dir_acl: u32, + ) -> Self { + Self::new( + InodeMode(permissions) | InodeMode::IFDIR, + uid, + gid, + time, + flags, + generation, + file_acl, + dir_acl, + ) + } + pub fn file( + permissions: u16, + uid: u32, + gid: u32, + time: u32, + flags: u32, + generation: u32, + file_acl: u32, + dir_acl: u32, + ) -> Self { + Self::new( + InodeMode(permissions) | InodeMode::IFREG, + uid, + gid, + time, + flags, + generation, + file_acl, + dir_acl, + ) + } + + pub fn empty() -> Self { + Self::new(InodeMode(0), 0, 0, 0, 0, 0, 0, 0) + } +} pub const INODE_SIZE: usize = std::mem::size_of::(); diff --git a/src/disk/mod.rs b/src/disk/mod.rs index e4e4216..404c6ab 100644 --- a/src/disk/mod.rs +++ b/src/disk/mod.rs @@ -1,2 +1,4 @@ -pub mod inode; pub mod bitmap; +pub mod inode; + +pub mod data_block; -- cgit v1.2.3-70-g09d2