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