summaryrefslogtreecommitdiff
path: root/src/disk
diff options
context:
space:
mode:
authorChuyan Zhang <me@zcy.moe>2023-11-29 03:29:34 -0800
committerChuyan Zhang <me@zcy.moe>2023-11-29 03:29:34 -0800
commit7af0771f9a3031acc36a6990d07bdb92a61c0c75 (patch)
tree3db3c79b8d385bc949c8486d97def8dadd4323e6 /src/disk
parentceb83a7214000ccd048857b40cc0ebfc54290731 (diff)
downloadmyfs-7af0771f9a3031acc36a6990d07bdb92a61c0c75.tar.gz
myfs-7af0771f9a3031acc36a6990d07bdb92a61c0c75.zip
symlink, probably not working
Diffstat (limited to 'src/disk')
-rw-r--r--src/disk/allocation.rs14
-rw-r--r--src/disk/block.rs63
-rw-r--r--src/disk/inode.rs42
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),