From b8afa7cfb02b32278e268924e189170496f81c1b Mon Sep 17 00:00:00 2001 From: Chuyan Zhang Date: Thu, 23 Nov 2023 02:11:16 -0800 Subject: Add some callback (not finished) --- src/disk/allocation.rs | 16 ++++++------ src/disk/inode.rs | 71 +++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 67 insertions(+), 20 deletions(-) (limited to 'src/disk') diff --git a/src/disk/allocation.rs b/src/disk/allocation.rs index bfdba46..5643dd3 100644 --- a/src/disk/allocation.rs +++ b/src/disk/allocation.rs @@ -194,11 +194,8 @@ impl AyaFS { { let mut triple_indirect_block = triple_indirect_block.clone(); let mut block_modified = false; - for double_indirect_entry in triple_indirect_block - .block - .double_indirect - .iter_mut() - .rev() + for double_indirect_entry in + triple_indirect_block.block.double_indirect.iter_mut().rev() { // 如果这个位置的 double indirect 存在 if self.data_bitmap.query(*double_indirect_entry as usize) { @@ -212,8 +209,10 @@ impl AyaFS { return Some(block_index); // 成功则直接返回 } else { // 失败则把这个 double indirect 销毁 - let double_indirect_entry_to_deallocate = std::mem::replace(double_indirect_entry, 0); - self.data_bitmap.deallocate(double_indirect_entry_to_deallocate as usize); + let double_indirect_entry_to_deallocate = + std::mem::replace(double_indirect_entry, 0); + self.data_bitmap + .deallocate(double_indirect_entry_to_deallocate as usize); triple_indirect_block.dirty = true; block_modified = true; } @@ -246,7 +245,8 @@ impl AyaFS { } else { // 失败则把这个 indirect 销毁 let indirect_entry_to_deallocate = std::mem::replace(indirect_entry, 0); - self.data_bitmap.deallocate(indirect_entry_to_deallocate as usize); + self.data_bitmap + .deallocate(indirect_entry_to_deallocate as usize); double_indirect_block.dirty = true; block_modified = true; } diff --git a/src/disk/inode.rs b/src/disk/inode.rs index 48085d8..1095aca 100644 --- a/src/disk/inode.rs +++ b/src/disk/inode.rs @@ -1,4 +1,6 @@ use bitflags::bitflags; +use fuser::{FileAttr, FileType}; +use std::fs::File; const DIRECT_NUMBER: usize = 15; @@ -30,6 +32,43 @@ bitflags! { } } +impl InodeMode { + pub(crate) fn perm(&self) -> u16 { + self.0 & 0x0FFF + } + + pub(crate) fn is_file(&self) -> bool { + (self.0 & 0xF000) == Self::IFREG.0 + } + + pub(crate) fn is_dir(&self) -> bool { + (self.0 & 0xF000) == Self::IFDIR.0 + } + + pub(crate) fn validate(mode_value: u16) -> Option { + let valid_flags: [u16; 7] = [0x1000, 0x2000, 0x4000, 0x6000, 0x8000, 0xA000, 0xC000]; + valid_flags + .contains(&(mode_value & 0xF000)) + .then(|| Self(mode_value)) + } +} + +impl From for FileType { + fn from(value: InodeMode) -> Self { + let type_flag = value.0 & 0xF000; + match type_flag { + 0x1000 => FileType::NamedPipe, + 0x2000 => FileType::CharDevice, + 0x4000 => FileType::Directory, + 0x6000 => FileType::BlockDevice, + 0x8000 => FileType::RegularFile, + 0xA000 => FileType::Symlink, + 0xC000 => FileType::Socket, + _ => panic!("Invalid inode mode {:x}", type_flag), + } + } +} + /// Pretty much the same with ext2, with minor changes: /// - removed OS dependent attributes (osd1 & osd2) /// - removed i_faddr since fragmentation is not supported @@ -39,24 +78,24 @@ bitflags! { #[repr(C)] #[derive(Debug, Clone)] pub struct Inode { - mode: InodeMode, - uid: u32, - size: 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, + pub mode: InodeMode, + pub uid: u32, + pub size: u32, + pub atime: u32, // access time, in seconds + pub ctime: u32, // change time, in seconds + pub mtime: u32, // modify time, in seconds + pub crtime: u32, // create time, in seconds + pub gid: u32, pub n_links: u16, pub n_blocks: u32, - flags: u32, // TODO: do we actually need this? maybe just return 0 + pub flags: u32, // TODO: do we actually need this? maybe just return 0 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......? + pub generation: u32, + pub file_acl: u32, + pub dir_acl: u32, // TODO do we have to implement ACL......? } impl Inode { @@ -159,6 +198,14 @@ impl Inode { ) } + pub(crate) fn is_file(&self) -> bool { + self.mode.is_file() + } + + pub(crate) fn is_dir(&self) -> bool { + self.mode.is_dir() + } + pub fn empty() -> Self { Self::new(InodeMode(0), 0, 0, 0, 0, 0, 0, 0) } -- cgit v1.2.3-70-g09d2