diff options
author | Chuyan Zhang <me@zcy.moe> | 2023-11-29 03:29:34 -0800 |
---|---|---|
committer | Chuyan Zhang <me@zcy.moe> | 2023-11-29 03:29:34 -0800 |
commit | 7af0771f9a3031acc36a6990d07bdb92a61c0c75 (patch) | |
tree | 3db3c79b8d385bc949c8486d97def8dadd4323e6 /src/disk | |
parent | ceb83a7214000ccd048857b40cc0ebfc54290731 (diff) | |
download | myfs-7af0771f9a3031acc36a6990d07bdb92a61c0c75.tar.gz myfs-7af0771f9a3031acc36a6990d07bdb92a61c0c75.zip |
symlink, probably not working
Diffstat (limited to 'src/disk')
-rw-r--r-- | src/disk/allocation.rs | 14 | ||||
-rw-r--r-- | src/disk/block.rs | 63 | ||||
-rw-r--r-- | src/disk/inode.rs | 42 |
3 files changed, 103 insertions, 16 deletions
diff --git a/src/disk/allocation.rs b/src/disk/allocation.rs index a4bb3f7..d4ad397 100644 --- a/src/disk/allocation.rs +++ b/src/disk/allocation.rs @@ -5,6 +5,7 @@ use crate::disk::inode::{Inode, DIRECT_NUMBER}; use crate::memory::cached_block::{convert, CachedBlock}; use crate::{AyaFS, INODE_PER_BLOCK}; use libc::c_int; +use log::debug; impl AyaFS { /// 为 Inode 分配新 block, 返回 block 的编号和它在 inode 内的编号 @@ -403,12 +404,16 @@ impl AyaFS { inode: &Inode, mut block_index_within_inode: usize, ) -> Option<usize> { + debug!("get_block_index(block_index_within_inode: {})", block_index_within_inode); // direct block if block_index_within_inode < DIRECT_NUMBER { let block_index = inode.direct[block_index_within_inode] as usize; + debug!(" get_block_index -> direct"); return if self.data_bitmap.query(block_index) { + debug!(" get_block_index -> direct -> ✓"); Some(block_index) } else { + debug!(" get_block_index -> direct -> ×"); None }; } else { @@ -416,18 +421,22 @@ impl AyaFS { } // indirect block - let indirect_number = INODE_PER_BLOCK; + let indirect_number = 1024; if block_index_within_inode < indirect_number { return if let Some(indirect_block) = self.get_block::<IndirectBlock>(inode.single_indirect as usize) { + debug!(" get_block_index -> indirect"); let block_index = indirect_block.block.entries[block_index_within_inode] as usize; if self.data_bitmap.query(block_index) { + debug!(" get_block_index -> indirect -> direct -> ✓"); Some(block_index) } else { + debug!(" get_block_index -> indirect -> direct -> ×"); None } } else { + debug!(" get_block_index -> indirect -> ×"); None }; } else { @@ -435,7 +444,7 @@ impl AyaFS { } // double indirect block - let double_indirect_number = INODE_PER_BLOCK * INODE_PER_BLOCK; + let double_indirect_number = 1024 * 1024; if block_index_within_inode < double_indirect_number { if let Some(double_indirect_block) = self.get_block::<DoubleIndirectBlock>(inode.double_indirect as usize) @@ -516,6 +525,7 @@ impl AyaFS { ) -> Option<&mut CachedBlock<T>> { self.get_block_index(inode, block_index_within_inode) .map(|block_index| { + debug!("access_block_mut(index: {}) found", block_index_within_inode); self.get_block_mut::<T>(block_index).unwrap() // 可以 unwrap 吧这里 ?? }) } diff --git a/src/disk/block.rs b/src/disk/block.rs index 26a7ec5..73819e2 100644 --- a/src/disk/block.rs +++ b/src/disk/block.rs @@ -19,7 +19,7 @@ impl Block for DataBlock {} #[repr(C)] #[derive(Clone)] pub struct InodeBlock { - pub(crate) inodes: [Inode; 16], + pub(crate) inodes: [Inode; 32], } impl Default for InodeBlock { @@ -42,6 +42,22 @@ impl Default for InodeBlock { 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(), ], } } @@ -49,8 +65,6 @@ impl Default for InodeBlock { impl Block for InodeBlock {} -const FULL_MAP: u16 = 0b111_111_111_111_111; - #[repr(C)] #[derive(Clone)] pub struct DirectoryEntry { @@ -115,6 +129,7 @@ impl Default for DirectoryBlock { } impl DirectoryBlock { + #[allow(unused)] pub(crate) fn is_full(&self) -> bool { self.occupancy[0] == 0xFF && self.occupancy[1] == 0xFF } @@ -133,20 +148,42 @@ impl DirectoryBlock { } } - 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) + 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 { - None + 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; diff --git a/src/disk/inode.rs b/src/disk/inode.rs index 6f9d338..1f5e54e 100644 --- a/src/disk/inode.rs +++ b/src/disk/inode.rs @@ -1,6 +1,6 @@ use crate::utils; use bitflags::bitflags; -use fuser::{FileAttr, FileType}; +use fuser::FileType; pub const DIRECT_NUMBER: usize = 15; @@ -33,30 +33,39 @@ bitflags! { } impl InodeMode { + #[allow(unused)] pub(crate) fn exec_other(&self) -> bool { self.0 & Self::IXOTH.0 != 0 } + #[allow(unused)] pub(crate) fn write_other(&self) -> bool { self.0 & Self::IWOTH.0 != 0 } + #[allow(unused)] pub(crate) fn read_other(&self) -> bool { self.0 & Self::IROTH.0 != 0 } + #[allow(unused)] pub(crate) fn exec_group(&self) -> bool { self.0 & Self::IXGRP.0 != 0 } + #[allow(unused)] pub(crate) fn write_group(&self) -> bool { self.0 & Self::IWGRP.0 != 0 } + #[allow(unused)] pub(crate) fn read_group(&self) -> bool { self.0 & Self::IRGRP.0 != 0 } + #[allow(unused)] pub(crate) fn exec_user(&self) -> bool { self.0 & Self::IXUSR.0 != 0 } + #[allow(unused)] pub(crate) fn write_user(&self) -> bool { self.0 & Self::IWUSR.0 != 0 } + #[allow(unused)] pub(crate) fn read_user(&self) -> bool { self.0 & Self::IRUSR.0 != 0 } @@ -73,6 +82,8 @@ impl InodeMode { (self.0 & 0xF000) == Self::IFDIR.0 } + pub(crate) fn is_symlink(&self) -> bool { self.0 & 0xF000 == Self::IFLNK.0 } + pub(crate) fn validate(mode_value: u16) -> Option<Self> { let valid_flags: [u16; 7] = [0x1000, 0x2000, 0x4000, 0x6000, 0x8000, 0xA000, 0xC000]; valid_flags @@ -165,6 +176,7 @@ impl Inode { } } + #[allow(unused)] pub fn make_inode( permissions: u16, mode: InodeMode, @@ -232,6 +244,28 @@ impl Inode { ) } + pub fn symlink( + permissions: u16, + uid: u32, + gid: u32, + time: u32, + flags: u32, + generation: u32, + file_acl: u32, + dir_acl: u32, + ) -> Self { + Self::new( + InodeMode(permissions) | InodeMode::IFLNK, + uid, + gid, + time, + flags, + generation, + file_acl, + dir_acl, + ) + } + pub(crate) fn is_file(&self) -> bool { self.mode.is_file() } @@ -240,6 +274,12 @@ impl Inode { self.mode.is_dir() } + pub(crate) fn is_symlink(&self) -> bool { self.mode.is_symlink() } + + pub(crate) fn file_type(&self) -> FileType { + self.mode.into() + } + pub fn empty() -> Self { Self { mode: InodeMode(0), |