use super::{div_rounded_up, Block};
use bitflags::bitflags;
use std::fmt;
#[derive(Debug, Copy, Clone)]
#[repr(packed)]
#[allow(unused)]
pub struct SuperBlock {
pub nbr_inode: u32,
pub nbr_blocks: u32,
nbr_blocks_reserved: u32,
pub nbr_free_blocks: u32,
pub nbr_free_inodes: u32,
block_containing_superblock: Block,
log2_block_size: u32,
pub log2_fragment_size: u32,
block_per_block_grp: u32,
fragment_per_block_grp: u32,
pub inodes_per_block_grp: u32,
last_mount_time: u32,
last_written_time: u32,
nbr_of_mount_since_last_consistency_check: u16,
nbr_of_mounts_allowed_before_conistency_check: u16,
ext2_signature: u16,
file_system_state: FileSystemState,
error_handling_methods: ErrorHandlingMethods,
minor_version: u16,
last_consistency_check: u32,
interval_between_forced_consistency_checks: u32,
creator_operating_system: CreatorOperatingSystem,
major_version: u32,
user_id_reserved_blocks: u16,
group_id_reserved_blocks: u16,
first_non_reserved_inode: u32,
size_inode: u16,
block_group_of_superblock: u16,
optional_features_flag: OptionalFeaturesFlag,
required_features_flag: RequiredFeaturesFlag,
feature_must_read_only: ReadOnlyFeaturesFlag,
file_system_id: u16,
volume_name: u16,
path_volume_last_mounted: PathVolumeLastMounted,
compression_algorithms_used: u32,
number_of_blocks_to_preallocate_for_files: u8,
number_of_blocks_to_preallocate_for_directories: u8,
unused: u16,
journal_id: u16,
journal_inode: u32,
journal_device: u32,
head_of_orphan_inode_list: u32,
}
impl SuperBlock {
pub fn get_ext2_signature(&self) -> u16 {
self.ext2_signature
}
pub fn get_nbr_block_grp(&self) -> u32 {
div_rounded_up(self.nbr_blocks as u64, self.block_per_block_grp as u64) as u32
}
pub fn get_inode_block_grp(&self) -> u32 {
div_rounded_up(self.nbr_inode as u64, self.inodes_per_block_grp as u64) as u32
}
pub fn get_block_per_block_grp(&self) -> Block {
Block(self.block_per_block_grp)
}
pub fn get_log2_block_size(&self) -> u32 {
self.log2_block_size
}
pub fn get_size_inode(&self) -> u16 {
self.size_inode
}
pub fn directory_entry_contain_type_field(&self) -> bool {
let flag = self.required_features_flag;
flag.contains(RequiredFeaturesFlag::DIRECTORY_ENTRIES_CONTAIN_A_TYPE_FIELD)
}
}
#[derive(Debug, Copy, Clone)]
#[repr(u16)]
#[allow(unused)]
enum FileSystemState {
Unknown = 0,
IsClean = 1,
HasErrors = 2,
}
#[derive(Debug, Copy, Clone)]
#[repr(u16)]
#[allow(unused)]
enum ErrorHandlingMethods {
IgnoreTheError = 1,
RemountFileSystemAsReadOnly = 2,
KernelPanic = 3,
}
#[derive(Debug, Copy, Clone)]
#[repr(u32)]
#[allow(unused)]
enum CreatorOperatingSystem {
Linux = 0,
HURD,
MASIX,
FreeBSD,
Other,
}
bitflags! {
#[derive(Copy, Clone, Debug)]
struct RequiredFeaturesFlag: u32 {
const COMPRESSION_IS_USED = 0x1;
const DIRECTORY_ENTRIES_CONTAIN_A_TYPE_FIELD = 0x2;
const FILE_SYSTEM_NEEDS_TO_REPLAY_ITS_JOURNAL = 0x4;
const FILE_SYSTEM_USES_A_JOURNAL_DEVICE = 0x8;
}
}
bitflags! {
#[derive(Copy, Clone, Debug)]
struct OptionalFeaturesFlag: u32 {
const PREALLOCATE_SOME_NUMBER_OF_BLOCKS_A_DIRECTORY_WHEN_CREATING_A_NEW_ONE = 0x0001;
const AFS_SERVER_INODES_EXIST = 0x0002;
const FILE_SYSTEM_HAS_A_JOURNAL = 0x0004;
const INODES_HAVE_EXTENDED_ATTRIBUTES = 0x0008;
const FILE_SYSTEM_CAN_RESIZE_ITSELF_FOR_LARGER_PARTITIONS = 0x0010;
const DIRECTORIES_USE_HASH_INDEX = 0x0020;
}
}
bitflags! {
#[derive(Copy, Clone, Debug)]
struct ReadOnlyFeaturesFlag: u32 {
const SPARSE_SUPERBLOCKS_AND_GROUP_DESCRIPTOR_TABLES = 0x1;
const FILE_SYSTEM_USES_A_64_BIT_FILE_SIZE = 0x2;
const DIRECTORY_CONTENTS_ARE_STORED_IN_THE_FORM_OF_A_BINARY_TREE = 0x3;
}
}
#[derive(Copy, Clone)]
#[repr(transparent)]
struct PathVolumeLastMounted([u8; 64]);
impl fmt::Debug for PathVolumeLastMounted {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", "PathVolumeLastMounted")
}
}