summaryrefslogtreecommitdiff
path: root/ayafs-core/src/disk/block.rs
diff options
context:
space:
mode:
authorChuyan Zhang <me@zcy.moe>2023-11-30 12:01:11 -0800
committerChuyan Zhang <me@zcy.moe>2023-11-30 12:01:11 -0800
commitfd125947c9db0b33761414e65e919f73d9bf1815 (patch)
treec4c66d95ba85601427928aa7f23659590055d464 /ayafs-core/src/disk/block.rs
parent1eac97eea4ec0bcef0be061a2cba93a584355283 (diff)
downloadmyfs-fd125947c9db0b33761414e65e919f73d9bf1815.tar.gz
myfs-fd125947c9db0b33761414e65e919f73d9bf1815.zip
Refactor workspace
Diffstat (limited to 'ayafs-core/src/disk/block.rs')
-rw-r--r--ayafs-core/src/disk/block.rs271
1 files changed, 271 insertions, 0 deletions
diff --git a/ayafs-core/src/disk/block.rs b/ayafs-core/src/disk/block.rs
new file mode 100644
index 0000000..76769b9
--- /dev/null
+++ b/ayafs-core/src/disk/block.rs
@@ -0,0 +1,271 @@
+use crate::disk::inode::Inode;
+use std::ffi::{OsStr, OsString};
+use std::os::unix::ffi::OsStrExt;
+
+pub trait Block: Default + Clone {}
+
+#[repr(C)]
+pub struct SuperBlock {
+ pub(crate) data_bitmap_block_number: u64,
+ pub(crate) inode_bitmap_block_number: u64,
+ pub(crate) inode_block_number: u64,
+ pub(crate) data_block_number: u64,
+ padding: [u8; 4064],
+}
+
+impl SuperBlock {
+ pub(crate) fn new(
+ data_bitmap_block_number: usize,
+ inode_bitmap_block_number: usize,
+ inode_block_number: usize,
+ data_block_number: usize,
+ ) -> Self {
+ Self {
+ data_bitmap_block_number: data_bitmap_block_number as u64,
+ inode_bitmap_block_number: inode_bitmap_block_number as u64,
+ inode_block_number: inode_block_number as u64,
+ data_block_number: data_block_number as u64,
+ padding: [0; 4064],
+ }
+ }
+}
+
+#[repr(C)]
+#[derive(Clone)]
+pub struct DataBlock(pub(crate) [u8; 4096]);
+
+impl Default for DataBlock {
+ fn default() -> Self {
+ Self([0; 4096])
+ }
+}
+
+impl Block for DataBlock {}
+
+#[repr(C)]
+#[derive(Clone)]
+pub struct InodeBlock {
+ pub(crate) inodes: [Inode; 32],
+}
+
+impl Default for InodeBlock {
+ fn default() -> Self {
+ Self {
+ inodes: [
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ Inode::empty(),
+ ],
+ }
+ }
+}
+
+impl Block for InodeBlock {}
+
+#[repr(C)]
+#[derive(Clone)]
+pub struct DirectoryEntry {
+ pub inode: u32,
+ pub record_len: u16,
+ pub name_len: u8,
+ pub file_type: u8,
+ pub name: [u8; 256],
+}
+
+impl DirectoryEntry {
+ pub(crate) fn name(&self) -> OsString {
+ let name = &self.name[0..self.name_len as usize];
+ OsStr::from_bytes(name).to_os_string()
+ }
+}
+
+impl Default for DirectoryEntry {
+ fn default() -> Self {
+ Self {
+ inode: 0,
+ record_len: 0,
+ name_len: 0,
+ file_type: 0x0,
+ name: [0; 256],
+ }
+ }
+}
+
+#[repr(C)]
+#[derive(Clone)]
+pub struct DirectoryBlock {
+ pub entries: [DirectoryEntry; 15],
+ pub occupancy: [u8; 2],
+ reserved: [u8; 134],
+}
+
+impl Default for DirectoryBlock {
+ fn default() -> Self {
+ Self {
+ entries: [
+ DirectoryEntry::default(),
+ DirectoryEntry::default(),
+ DirectoryEntry::default(),
+ DirectoryEntry::default(),
+ DirectoryEntry::default(),
+ DirectoryEntry::default(),
+ DirectoryEntry::default(),
+ DirectoryEntry::default(),
+ DirectoryEntry::default(),
+ DirectoryEntry::default(),
+ DirectoryEntry::default(),
+ DirectoryEntry::default(),
+ DirectoryEntry::default(),
+ DirectoryEntry::default(),
+ DirectoryEntry::default(),
+ ],
+ occupancy: [0x80, 0x00], // 0b1000_0000
+ reserved: [0xFF; 134],
+ }
+ }
+}
+
+impl DirectoryBlock {
+ #[allow(unused)]
+ pub(crate) fn is_full(&self) -> bool {
+ self.occupancy[0] == 0xFF && self.occupancy[1] == 0xFF
+ }
+
+ pub(crate) fn query(&self, mut index: usize) -> bool {
+ if index < 7 {
+ // 0-6, first u8
+ index = index + 1;
+ self.occupancy[0] & (1 << (7 - index)) as u8 != 0
+ } else if index < 15 {
+ // 7-14, second u8
+ index = index - 7;
+ self.occupancy[1] & (1 << (7 - index)) as u8 != 0
+ } else {
+ false
+ }
+ }
+
+ pub(crate) fn allocate(&mut self, mut index: usize) -> bool {
+ if index < 7 {
+ index = index + 1;
+ let mask = (1 << (7 - index)) as u8;
+ if self.occupancy[0] & mask != 0 {
+ false
+ } else {
+ self.occupancy[0] |= mask;
+ true
+ }
+ } else {
+ index = index - 7;
+ let mask = (1 << (7 - index)) as u8;
+ if self.occupancy[1] & mask != 0 {
+ false
+ } else {
+ self.occupancy[1] |= mask;
+ true
+ }
+ }
+ }
+
+ // pub(crate) fn allocate(&mut self) -> Option<usize> {
+ // if self.occupancy[0] != 0xFF {
+ // let leading_ones = self.occupancy[0].leading_ones();
+ // self.occupancy[0] |= (1 << (7 - leading_ones)) as u8;
+ // Some(leading_ones as usize)
+ // } else if self.occupancy[1] != 0xFF {
+ // let leading_ones = self.occupancy[1].leading_ones();
+ // self.occupancy[1] |= (1 << (7 - leading_ones)) as u8;
+ // Some(7 + leading_ones as usize)
+ // } else {
+ // None
+ // }
+ // }
+
+ pub(crate) fn deallocate(&mut self, mut index: usize) {
+ if index < 7 {
+ index = index + 1;
+ self.occupancy[0] &= !((1 << (7 - index)) as u8);
+ } else if index < 15 {
+ // 7-14, second u8
+ index = index - 7;
+ self.occupancy[1] &= !((1 << (7 - index)) as u8);
+ }
+ }
+}
+
+impl Block for DirectoryBlock {}
+
+#[repr(C)]
+#[derive(Clone)]
+pub struct IndirectBlock {
+ pub entries: [u32; 1024],
+}
+
+impl Default for IndirectBlock {
+ fn default() -> Self {
+ Self { entries: [0; 1024] }
+ }
+}
+
+impl Block for IndirectBlock {}
+
+#[repr(C)]
+#[derive(Clone)]
+pub struct DoubleIndirectBlock {
+ pub indirect: [u32; 1024],
+}
+
+impl Default for DoubleIndirectBlock {
+ fn default() -> Self {
+ Self {
+ indirect: [0; 1024],
+ }
+ }
+}
+
+impl Block for DoubleIndirectBlock {}
+
+#[repr(C)]
+#[derive(Clone)]
+pub struct TripleIndirectBlock {
+ pub double_indirect: [u32; 1024],
+}
+
+impl Default for TripleIndirectBlock {
+ fn default() -> Self {
+ Self {
+ double_indirect: [0; 1024],
+ }
+ }
+}
+
+impl Block for TripleIndirectBlock {}