use vapfs::{Index, Timestamp}; /// # Magic /// Constant value that identifies the Superblock as a valid VapUFS filesystem pub const MAGIC: u64 = 0x766170554653; /// # Superblock /// The primary struct of a VapUFS filesystem, contains metadata about the filesystem. /// Located at byte offset 1024 of the block device. /// All values are big-endian unless otherwise specified. /// Directly after the Superblock are the free data blocks bitmap and the free inodes bitmap. /// Free data blocks bitmap is data_block_count / 8 bytes long (rounded up). /// Free inodes bitmap is inode_count / 8 bytes long (rounded up). #[repr(C)] pub struct Superblock { /// magic number that identifies the Superblock as a valid VapUFS filesystem pub magic: u64, /// size of each block in bytes pub block_size: u32, /// location of first data block in blocks pub first_data_block: Index, /// location of first inode block in blocks pub first_inode_block: Index, /// location of first journal block in blocks pub first_journal_block: Index, /// total count of inodes, including unused inodes pub inode_count: Index, /// total count of data blocks, including unused blocks pub data_block_count: Index, /// total count of blocks dedicated to journal pub journal_block_count: Index, /// total count of inodes in use pub allocated_inode_count: Index, /// total count of data blocks in use pub allocated_data_block_count: Index, /// timestamp of creation pub creation_time: Timestamp, /// timestamp of last modification pub last_modification_time: Timestamp, /// reserved values for expansion pub reserved: [u64; 8], // 156 bytes used so far // rest of the block is used by the free data blocks bitmap and the free inodes bitmap } /// # UNIXPermissions /// UNIX permissions #[repr(u16)] pub enum UNIXMode { /// Read, Other Read = 1 << 0, /// Write, Other Write = 1 << 1, /// Execute, Other Execute = 1 << 2, /// Read, Group ReadGroup = 1 << 3, /// Write, Group WriteGroup = 1 << 4, /// Execute, Group ExecuteGroup = 1 << 5, /// Read, Owner ReadOwner = 1 << 6, /// Write, Owner WriteOwner = 1 << 7, /// Execute, Owner ExecuteOwner = 1 << 8, /// Sticky bit Sticky = 1 << 9, /// Set GID SetGID = 1 << 10, /// Set UID SetUID = 1 << 11, } /// # Filetype /// Represents a file's type in the last 4 bits of the mode field of an inode. #[repr(u16)] pub enum Filetype { /// Named FIFO pipe FIFO = 0b0001 << 12, /// Character device CharDevice = 0b0010 << 12, /// Directory Directory = 0b0011 << 12, /// Block device BlockDevice = 0b0100 << 12, /// Regular file RegularFile = 0b0101 << 12, /// Symbolic link SymbolicLink = 0b0110 << 12, /// Socket Socket = 0b0111 << 12, } /// # Inode /// Usually represents a file or directory, used to store metadata and locations of data blocks. #[repr(C)] pub struct Inode { /// UNIX permissions / mode and filetype pub mode: u16, /// Number of links to this inode pub link_count: u16, /// User ID of owner pub uid: u32, /// Group ID of owner pub gid: u32, /// Size in bytes pub size: Index, /// Size in blocks pub block_count: Index, /// Timestamp of creation pub creation_time: Timestamp, /// Timestamp of last access pub last_access_time: Timestamp, /// Timestamp of last modification pub last_modification_time: Timestamp, /// Timestamp of last Inode modification pub last_inode_modification_time: Timestamp, /// Timestamp of deletion pub deletion_time: Timestamp, /// Flags field, see `InodeFlags` pub flags: u32, /// Direct-Block-Addresses, last three are indirect if `InodeFlags::INDIRECT` is set /// Indirect blocks are Indexes to other blocks, their contents are a u64 count "N" followed by N u64 indexes pub direct_block_addresses: [Index; 12], /// CRC32 checksum of this inode pub checksum: u32, } /// # InodeFlags /// Flags field of an inode #[repr(u32)] pub enum InodeFlags { /// File is corrupted CORRUPT = 1 << 0, /// File uses indirect blocks INDIRECT = 1 << 1, }