From e5f19a82d8370a2935a932d369ac44f05960e4f1 Mon Sep 17 00:00:00 2001
From: pigeonmoelleux <pigeonmoelleux@crans.org>
Date: Sat, 20 May 2023 00:00:30 +0200
Subject: [PATCH] feat(fs): ext2 block group description + inodes

---
 src/fs/ext2/{superblock.rs => block.rs} |  28 ++-
 src/fs/ext2/inode.rs                    | 217 ++++++++++++++++++++++++
 src/fs/ext2/mod.rs                      |   4 +-
 src/fs/node.rs                          |  31 +++-
 4 files changed, 276 insertions(+), 4 deletions(-)
 rename src/fs/ext2/{superblock.rs => block.rs} (91%)
 create mode 100644 src/fs/ext2/inode.rs

diff --git a/src/fs/ext2/superblock.rs b/src/fs/ext2/block.rs
similarity index 91%
rename from src/fs/ext2/superblock.rs
rename to src/fs/ext2/block.rs
index 9ebe521..8ecfaeb 100644
--- a/src/fs/ext2/superblock.rs
+++ b/src/fs/ext2/block.rs
@@ -1,6 +1,6 @@
-//! Interface with the superblock
+//! Interface with the superblock and the block group descriptor table
 //!
-//! See the [OSdev wiki](https://wiki.osdev.org/Ext2#Superblock) for more informations
+//! See the [OSdev wiki](https://wiki.osdev.org/Ext2) for more informations
 
 use bitflags::bitflags;
 use log::error;
@@ -272,3 +272,27 @@ bitflags! {
         const BINARY_TREE           =   0x0004;
     }
 }
+
+/// Contains a descriptor for each block group in the file system.
+#[repr(packed)]
+#[derive(Debug)]
+#[allow(clippy::module_name_repetitions)]
+pub struct BlockGroupDescriptor {
+    /// Block address of block usage bitmap
+    pub block_usage_bitmap_block_address: u32,
+
+    /// Block address of inode usage bitmap
+    pub inode_usage_bitmap_block_address: u32,
+
+    /// Starting block address of inode table
+    pub inode_table_starting_block_address: u32,
+
+    /// Number of unallocated blocks in group
+    pub total_unallocated_blocks: u16,
+
+    /// Number of unallocated inodes in group
+    pub total_unallocated_inodes: u16,
+
+    /// Number of directories in group
+    pub total_dir: u16,
+}
diff --git a/src/fs/ext2/inode.rs b/src/fs/ext2/inode.rs
new file mode 100644
index 0000000..4673a65
--- /dev/null
+++ b/src/fs/ext2/inode.rs
@@ -0,0 +1,217 @@
+//! Interface with the Inodes
+//!
+//! See the [OSdev wiki](https://wiki.osdev.org/Ext2#Inodes) for more informations
+
+use bitflags::bitflags;
+
+/// General structure of an ext2 inode
+#[derive(Debug)]
+pub struct Inode {
+    /// Type and Permissions
+    pub type_and_permissions: u16,
+
+    /// User ID
+    pub user_id: u16,
+
+    /// Lower 32 bits of size in bytes
+    pub lower_truncation_byte_size: u32,
+
+    /// Last Access Time (in POSIX time)
+    pub last_access_time: u32,
+
+    /// Creation Time (in POSIX time)
+    pub creation_time: u32,
+
+    /// Last Modification time (in POSIX time)
+    pub last_modification_time: u32,
+
+    /// Deletion time (in POSIX time)
+    pub deletion_time: u32,
+
+    /// Group ID
+    pub group_id: u16,
+
+    /// Count of hard links (directory entries) to this inode. When this reaches 0, the data blocks are marked as unallocated.
+    pub total_hard_links: u16,
+
+    /// Count of disk sectors (not Ext2 blocks) in use by this inode, not counting the actual inode structure nor directory entries
+    /// linking to the inode.
+    pub total_disk_sectors: u32,
+
+    /// Flags
+    pub flags: u32,
+
+    /// Operating System Specific value #1
+    pub os_specific_1: u32,
+
+    /// Direct Block Pointer 0
+    pub dbp00: u32,
+
+    /// Direct Block Pointer 1
+    pub dbp01: u32,
+
+    /// Direct Block Pointer 2
+    pub dbp02: u32,
+
+    /// Direct Block Pointer 3
+    pub dbp03: u32,
+
+    /// Direct Block Pointer 4
+    pub dbp04: u32,
+
+    /// Direct Block Pointer 5
+    pub dbp05: u32,
+
+    /// Direct Block Pointer 6
+    pub dbp06: u32,
+
+    /// Direct Block Pointer 7
+    pub dbp07: u32,
+
+    /// Direct Block Pointer 8
+    pub dbp08: u32,
+
+    /// Direct Block Pointer 9
+    pub dbp09: u32,
+
+    /// Direct Block Pointer 10
+    pub dbp10: u32,
+
+    /// Direct Block Pointer 11
+    pub dbp11: u32,
+
+    /// Singly Indirect Block Pointer (Points to a block that is a list of block pointers to data)
+    pub singly_indirect_block_pointer: u32,
+
+    /// Doubly Indirect Block Pointer (Points to a block that is a list of block pointers to Singly Indirect Blocks)
+    pub doubly_indirect_block_pointer: u32,
+
+    /// Triply Indirect Block Pointer (Points to a block that is a list of block pointers to Doubly Indirect Blocks)
+    pub triply_indirect_block_pointer: u32,
+
+    /// Generation number (Primarily used for NFS)
+    pub generation_number: u32,
+
+    /// In Ext2 version 0, this field is reserved. In version >= 1, Extended attribute block (File ACL).
+    pub extended_attribute_block: u32,
+
+    /// In Ext2 version 0, this field is reserved. In version >= 1, Upper 32 bits of file size (if feature bit set) if it's a file,
+    /// Directory ACL if it's a directory
+    pub higher_truncation_byte_size_or_directory_acl: u32,
+
+    /// Block address of fragment
+    pub fragment_block_address: u32,
+
+    /// Operating System Specific value #2
+    pub os_specific_2: [u8; 12],
+}
+
+bitflags! {
+    /// Indicators of the inode type and permissions
+    ///
+    /// The type indicator occupies the top hex digit (bits 15 to 12).
+    ///
+    /// The permission indicator occupies the bottom 12 bits.
+    pub struct TypePermissions: u16 {
+        // Types
+
+        /// FIFO
+        const FIFO                  =   0x1000;
+
+        /// Character device
+        const CHARACTER_DEVICE      =   0x2000;
+
+        /// Directory
+        const DIRECTORY             =   0x4000;
+
+        /// Block device
+        const BLOCK_DEVICE          =   0x6000;
+
+        /// Regular file
+        const FILE                  =   0x8000;
+
+        /// Symbolic link
+        const SYMBOLIC_LINK         =   0xA000;
+
+        /// Unix socket
+        const SOCKET                =   0xC000;
+
+
+
+        // Permissions
+
+        /// Other - execute permission
+        const OTHER_X               =   0x0001;
+
+        /// Other - write permission
+        const OTHER_W               =   0x0002;
+
+        /// Other - read permission
+        const OTHER_R               =   0x0004;
+
+        /// Group - execute permission
+        const GROUP_X               =   0x0008;
+
+        /// Group - write permission
+        const GROUP_W               =   0x0010;
+
+        /// Group - read permission
+        const GROUP_R               =   0x0020;
+
+        /// User - execute permission
+        const USER_X                =   0x0040;
+
+        /// User - write permission
+        const USER_W                =   0x0080;
+
+        /// User - read permission
+        const USER_R                =   0x0100;
+
+        /// Sticky bit
+        const STICKY                =   0x0200;
+
+        /// Set group ID
+        const SET_GROUP_ID          =   0x0400;
+
+        /// Set user ID
+        const SET_USER_ID           =   0x0800;
+    }
+}
+
+bitflags! {
+    /// Inode Flags
+    pub struct Flags: u32 {
+        /// Secure deletion (not used)
+        const SECURE_DELETION                       =   0x00000001;
+
+        /// Keep a copy of data when deleted (not used)
+        const DELETION_KEEP_DATA_COPY               =   0x00000002;
+
+        /// File compression (not used)
+        const FILE_COMPRESSION                      =   0x00000004;
+
+        /// Synchronous updates—new data is written immediately to disk
+        const SYNCHRONOUS_UPDATES                   =   0x00000008;
+
+        /// Immutable file (content cannot be changed)
+        const IMMUTABLE_FILE                        =   0x00000010;
+
+        /// Append only
+        const APPEND_ONLY                           =   0x00000020;
+
+        /// File is not included in `dump` command
+        const DUMP_EXCLUDED                         =   0x00000040;
+
+        /// Last accessed time should not updated
+        const LAST_ACCESSED_TIME_UPDATE_DISABLE     =   0x00000080;
+
+        /// Hash indexed directory
+        const HASHED_INDEXED_DIR                    =   0x00010000;
+
+        /// AFS directory
+        const AFS_DIR                               =   0x00020000;
+
+        /// Journal file data
+        const JOURNAL_FILE_DATA                     =   0x000400000;
+    }
+}
diff --git a/src/fs/ext2/mod.rs b/src/fs/ext2/mod.rs
index 2dcff89..9f2c900 100644
--- a/src/fs/ext2/mod.rs
+++ b/src/fs/ext2/mod.rs
@@ -1,4 +1,6 @@
 //! Implementation of the Second Extended Filesystem (ext2fs) filesystem
 
 #[allow(clippy::same_name_method)]
-mod superblock;
+mod block;
+#[allow(clippy::same_name_method)]
+mod inode;
diff --git a/src/fs/node.rs b/src/fs/node.rs
index 15debe7..85d0386 100644
--- a/src/fs/node.rs
+++ b/src/fs/node.rs
@@ -18,8 +18,9 @@ use crate::kernel::device::block::Manipulation;
 /// Type alias for a thread-safe shared reference behind a mutex
 pub type Ref<T> = Arc<Mutex<T>>;
 
-/// Enumeration of possible node kinds : file, directory or symbolic link
+/// Enumeration of possible inode types
 #[derive(Debug, Clone, Copy)]
+#[allow(unused)]
 pub enum Kind {
     /// Storage unit of a filesystem
     File,
@@ -29,6 +30,18 @@ pub enum Kind {
 
     /// Node pointing towards an other node in the filesystem
     Symlink,
+
+    /// FIFO
+    Fifo,
+
+    /// An inode that refers to a device communicating by sending chars (bytes) of data
+    CharacterDevice,
+
+    /// An inode that refers to a device communicating by sending blocks of data
+    BlockDevice,
+
+    /// Communication flow between two processes
+    UnixSocket,
 }
 
 /// Enumeration of possible nodes
@@ -42,6 +55,18 @@ pub enum Node {
 
     /// A reference to a symbolic link
     Symlink(Ref<dyn Symlink>),
+
+    /// A reference to a FIFO
+    Fifo(Ref<dyn Interface>),
+
+    /// A reference to a character device
+    CharacterDevice(Ref<dyn Interface>),
+
+    /// A reference to a block device
+    BlockDevice(Ref<dyn Interface>),
+
+    /// A reference to a Unix socket
+    UnixSocket(Ref<dyn Interface>),
 }
 
 impl From<Node> for Kind {
@@ -50,6 +75,10 @@ impl From<Node> for Kind {
             Node::File(_) => Self::File,
             Node::Directory(_) => Self::Directory,
             Node::Symlink(_) => Self::Symlink,
+            Node::Fifo(_) => Self::Fifo,
+            Node::CharacterDevice(_) => Self::CharacterDevice,
+            Node::BlockDevice(_) => Self::BlockDevice,
+            Node::UnixSocket(_) => Self::UnixSocket,
         }
     }
 }
-- 
GitLab