From 1eac97eea4ec0bcef0be061a2cba93a584355283 Mon Sep 17 00:00:00 2001 From: Chuyan Zhang Date: Thu, 30 Nov 2023 02:15:06 -0800 Subject: Add real disk i/o, add mkfs.aya (not yet implemented) --- ayafs/src/disk/block.rs | 245 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 ayafs/src/disk/block.rs (limited to 'ayafs/src/disk/block.rs') diff --git a/ayafs/src/disk/block.rs b/ayafs/src/disk/block.rs new file mode 100644 index 0000000..73819e2 --- /dev/null +++ b/ayafs/src/disk/block.rs @@ -0,0 +1,245 @@ +use crate::disk::inode::Inode; +use std::ffi::{OsStr, OsString}; +use std::os::unix::ffi::OsStrExt; + +pub trait Block: Default + Clone {} + +#[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 { + // 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 {} -- cgit v1.2.3-70-g09d2