summaryrefslogtreecommitdiff
path: root/src/disk/inode.rs
diff options
context:
space:
mode:
authorChuyan Zhang <me@zcy.moe>2023-11-23 02:11:16 -0800
committerChuyan Zhang <me@zcy.moe>2023-11-23 02:11:16 -0800
commitb8afa7cfb02b32278e268924e189170496f81c1b (patch)
tree449d5ae3342e259d66fcb338217e29479f906046 /src/disk/inode.rs
parent3f2151c043177501b0c7beb580d9737e3d824ad0 (diff)
downloadmyfs-b8afa7cfb02b32278e268924e189170496f81c1b.tar.gz
myfs-b8afa7cfb02b32278e268924e189170496f81c1b.zip
Add some callback (not finished)
Diffstat (limited to 'src/disk/inode.rs')
-rw-r--r--src/disk/inode.rs71
1 files changed, 59 insertions, 12 deletions
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)
}