summaryrefslogtreecommitdiff
path: root/src/disk/inode.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/disk/inode.rs')
-rw-r--r--src/disk/inode.rs152
1 files changed, 152 insertions, 0 deletions
diff --git a/src/disk/inode.rs b/src/disk/inode.rs
new file mode 100644
index 0000000..f38508a
--- /dev/null
+++ b/src/disk/inode.rs
@@ -0,0 +1,152 @@
+use bitflags::bitflags;
+
+const DIRECT_NUMBER: usize = 15;
+
+#[derive(Debug)]
+pub struct InodeMode(u16);
+
+bitflags! {
+ impl InodeMode: u16 {
+ const IXOTH = 0x0001;
+ const IWOTH = 0x0002;
+ const IROTH = 0x0004;
+ const IXGRP = 0x0008;
+ const IWGRP = 0x0010;
+ const IRGRP = 0x0020;
+ const IXUSR = 0x0040;
+ const IWUSR = 0x0080;
+ const IRUSR = 0x0100;
+ const ISVTX = 0x0200;
+ const ISGID = 0x0400;
+ const ISUID = 0x0800;
+ // These are mutually-exclusive:
+ const IFIFO = 0x1000;
+ const IFCHR = 0x2000;
+ const IFDIR = 0x4000;
+ const IFBLK = 0x6000;
+ const IFREG = 0x8000;
+ const IFLNK = 0xA000;
+ const IFSOCK = 0xC000;
+ }
+}
+
+/// Pretty much the same with ext2, with minor changes:
+/// - removed OS dependent attributes (osd1 & osd2)
+/// - removed i_faddr since fragmentation is not supported
+/// - changed uid and gid from u16 to u32
+/// - added more direct blocks for a total size of 128 bytes
+/// TODO: do we need to extend time precision?
+#[repr(C)]
+#[derive(Debug)]
+pub struct Inode {
+ mode: InodeMode,
+ uid: u32,
+ size: u32,
+ atime: u32, // time in seconds
+ ctime: u32,
+ mtime: u32,
+ dtime: u32,
+ gid: u32,
+ n_links: u16,
+ n_blocks: u32,
+ flags: u32, // TODO: do we actually need this? maybe just return 0
+ direct: [u32; DIRECT_NUMBER],
+ single_indirect: u32,
+ double_indirect: u32,
+ triple_indirect: u32,
+ generation: u32,
+ file_acl: u32,
+ dir_acl: u32, // TODO do we have to implement ACL......?
+}
+
+impl Inode {
+ pub fn directory() -> Self {
+ Self {
+ mode: InodeMode::IFDIR
+ | InodeMode::IRUSR
+ | InodeMode::IWUSR
+ | InodeMode::IXUSR
+ | InodeMode::IRGRP
+ | InodeMode::IXGRP
+ | InodeMode::IROTH
+ | InodeMode::IXOTH,
+ // Directory, 755 permissions
+ uid: 0,
+ size: 0,
+ atime: 0,
+ ctime: 0,
+ mtime: 0,
+ dtime: 0,
+ gid: 0,
+ n_links: 0,
+ n_blocks: 0,
+ flags: 0,
+ direct: [0; DIRECT_NUMBER],
+ single_indirect: 0,
+ double_indirect: 0,
+ triple_indirect: 0,
+ generation: 0,
+ file_acl: 0,
+ dir_acl: 0,
+ }
+ }
+
+ pub fn file() -> Self {
+ Self {
+ mode: InodeMode::IFREG
+ | InodeMode::IRUSR
+ | InodeMode::IWUSR
+ | InodeMode::IXUSR
+ | InodeMode::IRGRP
+ | InodeMode::IXGRP
+ | InodeMode::IROTH
+ | InodeMode::IXOTH,
+ // RegularFile, 755 permissions
+ uid: 0,
+ size: 0,
+ atime: 0,
+ ctime: 0,
+ mtime: 0,
+ dtime: 0,
+ gid: 0,
+ n_links: 0,
+ n_blocks: 0,
+ flags: 0,
+ direct: [0; DIRECT_NUMBER],
+ single_indirect: 0,
+ double_indirect: 0,
+ triple_indirect: 0,
+ generation: 0,
+ file_acl: 0,
+ dir_acl: 0,
+ }
+ }
+}
+
+//
+// #[repr(C)]
+// #[derive(Debug, Default)]
+// pub struct FileInode {
+// file_size: u32,
+// direct_blocks: [u32; DIRECT_NUMBER],
+// indirect_block: u32,
+// doubly_indirect_block: u32,
+// } // sizeof(FileInode) == 124 bytes
+//
+// #[repr(C)]
+// #[derive(Debug, Default)]
+// pub struct DirectoryInode {
+// child_number: u32,
+// direct_blocks: [u32; DIRECT_NUMBER],
+// indirect_block: u32,
+// doubly_indirect_block: u32,
+// } // sizeof(FileInode) == 124 bytes
+//
+// #[repr(C)]
+// #[derive(Debug)]
+// pub enum Inode {
+// File(FileInode),
+// Directory(DirectoryInode),
+// } // sizeof(Inode) == 128 bytes
+
+pub const INODE_SIZE: usize = std::mem::size_of::<Inode>();