summaryrefslogtreecommitdiff
path: root/src/disk
diff options
context:
space:
mode:
Diffstat (limited to 'src/disk')
-rw-r--r--src/disk/allocation.rs16
-rw-r--r--src/disk/inode.rs71
2 files changed, 67 insertions, 20 deletions
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<Self> {
+ let valid_flags: [u16; 7] = [0x1000, 0x2000, 0x4000, 0x6000, 0x8000, 0xA000, 0xC000];
+ valid_flags
+ .contains(&(mode_value & 0xF000))
+ .then(|| Self(mode_value))
+ }
+}
+
+impl From<InodeMode> 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)
}