// /*************************************************************************** // Aaru Data Preservation Suite // ---------------------------------------------------------------------------- // // Filename : Structs.cs // Author(s) : Natalia Portillo // // Component : Linux extended filesystem 2, 3 and 4 plugin. // // --[ Description ] ---------------------------------------------------------- // // Identifies the Linux extended filesystem 2, 3 and 4 and shows information. // // --[ License ] -------------------------------------------------------------- // // This library is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 2.1 of the // License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, see . // // ---------------------------------------------------------------------------- // Copyright © 2011-2025 Natalia Portillo // ****************************************************************************/ using System; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; namespace Aaru.Filesystems; // Information from the Linux kernel /// /// Implements detection of the Linux extended filesystem v2, v3 and v4 [SuppressMessage("ReSharper", "UnusedMember.Local")] // ReSharper disable once InconsistentNaming public sealed partial class ext2FS { #region Nested type: SuperBlock /// ext2/3/4 superblock [StructLayout(LayoutKind.Sequential, Pack = 1)] [SuppressMessage("ReSharper", "InconsistentNaming")] struct SuperBlock { /// 0x000, inodes on volume public readonly uint inodes; /// 0x004, blocks on volume public readonly uint blocks; /// 0x008, reserved blocks public readonly uint reserved_blocks; /// 0x00C, free blocks count public readonly uint free_blocks; /// 0x010, free inodes count public readonly uint free_inodes; /// 0x014, first data block public readonly uint first_block; /// 0x018, block size public uint block_size; /// 0x01C, fragment size public readonly int frag_size; /// 0x020, blocks per group public readonly uint blocks_per_grp; /// 0x024, fragments per group public readonly uint flags_per_grp; /// 0x028, inodes per group public readonly uint inodes_per_grp; /// 0x02C, last mount time public readonly uint mount_t; /// 0x030, last write time public readonly uint write_t; /// 0x034, mounts count public readonly ushort mount_c; /// 0x036, max mounts public readonly short max_mount_c; /// 0x038, (little endian) public readonly ushort magic; /// 0x03A, filesystem state public readonly ushort state; /// 0x03C, behaviour on errors public readonly ushort err_behaviour; /// 0x03E, From 0.5b onward public readonly ushort minor_revision; /// 0x040, last check time public readonly uint check_t; /// 0x044, max time between checks public readonly uint check_inv; // From 0.5a onward /// 0x048, Creation OS public readonly uint creator_os; /// 0x04C, Revison level public readonly uint revision; /// 0x050, Default UID for reserved blocks public readonly ushort default_uid; /// 0x052, Default GID for reserved blocks public readonly ushort default_gid; // From 0.5b onward /// 0x054, First unreserved inode public readonly uint first_inode; /// 0x058, inode size public readonly ushort inode_size; /// 0x05A, Block group number of THIS superblock public readonly ushort block_group_no; /// 0x05C, Compatible features set public readonly uint ftr_compat; /// 0x060, Incompatible features set public readonly uint ftr_incompat; // Found on Linux 2.0.40 /// 0x064, Read-only compatible features set public readonly uint ftr_ro_compat; // Found on Linux 2.1.132 /// 0x068, 16 bytes, UUID public readonly Guid uuid; /// 0x078, 16 bytes, volume name [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public readonly byte[] volume_name; /// 0x088, 64 bytes, where last mounted [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public readonly byte[] last_mount_dir; /// 0x0C8, Usage bitmap algorithm, for compression public readonly uint algo_usage_bmp; /// 0x0CC, Block to try to preallocate public readonly byte prealloc_blks; /// 0x0CD, Blocks to try to preallocate for directories public readonly byte prealloc_dir_blks; /// 0x0CE, Per-group desc for online growth public readonly ushort rsrvd_gdt_blocks; // Found on Linux 2.4 // ext3 /// 0x0D0, 16 bytes, UUID of journal superblock public readonly Guid journal_uuid; /// 0x0E0, inode no. of journal file public readonly uint journal_inode; /// 0x0E4, device no. of journal file public readonly uint journal_dev; /// 0x0E8, Start of list of inodes to delete public readonly uint last_orphan; /// 0x0EC, First byte of 128bit HTREE hash seed public readonly uint hash_seed_1; /// 0x0F0, Second byte of 128bit HTREE hash seed public readonly uint hash_seed_2; /// 0x0F4, Third byte of 128bit HTREE hash seed public readonly uint hash_seed_3; /// 0x0F8, Fourth byte of 128bit HTREE hash seed public readonly uint hash_seed_4; /// 0x0FC, Hash version public readonly byte hash_version; /// 0x0FD, Journal backup type public readonly byte jnl_backup_type; /// 0x0FE, Size of group descriptor public readonly ushort desc_grp_size; /// 0x100, Default mount options public readonly uint default_mnt_opts; /// 0x104, First metablock block group public readonly uint first_meta_bg; // Introduced with ext4, some can be ext3 /// 0x108, Filesystem creation time public readonly uint mkfs_t; /// Backup of the journal inode [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)] public readonly uint[] jnl_blocks; // Following 3 fields are valid if EXT4_FEATURE_COMPAT_64BIT is set /// 0x14C, High 32bits of blocks no. public readonly uint blocks_hi; /// 0x150, High 32bits of reserved blocks no. public readonly uint reserved_blocks_hi; /// 0x154, High 32bits of free blocks no. public readonly uint free_blocks_hi; /// 0x158, inodes minimal size in bytes public readonly ushort min_inode_size; /// 0x15A, Bytes reserved by new inodes public readonly ushort rsv_inode_size; /// 0x15C, Flags public readonly uint flags; /// 0x160, RAID stride public readonly ushort raid_stride; /// 0x162, Waiting seconds in MMP check public readonly ushort mmp_interval; /// 0x164, Block for multi-mount protection public readonly ulong mmp_block; /// 0x16C, Blocks on all data disks (N*stride) public readonly uint raid_stripe_width; /// 0x170, FLEX_BG group size public readonly byte flex_bg_grp_size; /// 0x171 Metadata checksum algorithm public readonly byte checksum_type; /// 0x172 Versioning level for encryption public readonly byte encryption_level; /// 0x173 Padding public readonly ushort padding; // Following are introduced with ext4 /// 0x174, Kibibytes written in volume lifetime public readonly ulong kbytes_written; /// 0x17C, Active snapshot inode number public readonly uint snapshot_inum; /// 0x180, Active snapshot sequential ID public readonly uint snapshot_id; /// 0x184, Reserved blocks for active snapshot's future use public readonly ulong snapshot_blocks; /// 0x18C, inode number of the on-disk start of the snapshot list public readonly uint snapshot_list; // Optional ext4 error-handling features /// 0x190, total registered filesystem errors public readonly uint error_count; /// 0x194, time on first error public readonly uint first_error_t; /// 0x198, inode involved in first error public readonly uint first_error_inode; /// 0x19C, block involved of first error public readonly ulong first_error_block; /// 0x1A0, 32 bytes, function where the error happened [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public readonly byte[] first_error_func; /// 0x1B0, line number where error happened public readonly uint first_error_line; /// 0x1B4, time of most recent error public readonly uint last_error_t; /// 0x1B8, inode involved in last error public readonly uint last_error_inode; /// 0x1BC, line number where error happened public readonly uint last_error_line; /// 0x1C0, block involved of last error public readonly ulong last_error_block; /// 0x1C8, 32 bytes, function where the error happened [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public readonly byte[] last_error_func; // End of optional error-handling features // 0x1D8, 64 bytes, last used mount options [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public readonly byte[] mount_options; /// Inode for user quota public readonly uint usr_quota_inum; /// Inode for group quota public readonly uint grp_quota_inum; /// Overhead clusters in volume public readonly uint overhead_clusters; /// Groups with sparse_super2 SBs [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public readonly uint[] backup_bgs; /// Encryption algorithms in use [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public readonly byte[] encrypt_algos; /// Salt used for string2key algorithm [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public readonly byte[] encrypt_pw_salt; /// Inode number of lost+found public readonly uint lpf_inum; /// Inode number for tracking project quota public readonly uint prj_quota_inum; /// crc32c(uuid) if csum_seed is set public readonly uint checksum_seed; /// Reserved [MarshalAs(UnmanagedType.ByValArray, SizeConst = 98)] public readonly byte[] reserved; /// crc32c(superblock) public readonly uint checksum; } #endregion }