// // Created by rick on 18-09-21. // #ifndef NEW_KERNEL_EXT2_H #define NEW_KERNEL_EXT2_H #include #include #define EXT2_SIGNATURE 0xEF53 #define EXT2_SB_ADDR 1024 #define EXT2_SB_SIZE 1024 #define EXT2_BGD_START_ADDR (EXT2_SB_ADDR + EXT2_SB_SIZE) #define EXT2_DEFAULT_RESERVED_INODES 11 #define EXT2_DEFAULT_INODE_SIZE 128 #define EXT2_ROOT_INODE 2 typedef struct ext2_sb { uint32_t total_inodes; uint32_t total_blocks; uint32_t num_reserved_su; uint32_t unallocated_blocks; uint32_t unallocated_inodes; uint32_t no_blocks_with_sb; uint32_t block_size; uint32_t fragment_size; uint32_t no_blocks_per_group; uint32_t no_fragments_per_group; uint32_t no_inodes_per_group; uint32_t last_mounted; uint32_t last_written; uint16_t no_mounted_since_fschk; uint16_t max_no_mounted_since_fschk; uint16_t ext2_signature; uint16_t fs_state; uint16_t error_action; uint16_t minor_version; uint32_t last_fschk; uint32_t interval_fschk; uint32_t os_id; uint32_t major_version; uint16_t uid_reserved; uint16_t gid_reserved; // below extended fields uint32_t first_nor_reserved_inode; uint16_t size_inode; uint16_t owner_bg; uint32_t features_optional; uint32_t features_required; uint32_t features_ro; uint8_t fs_id[16]; char fs_name[16]; char last_mounted_path[64]; uint32_t compression_alg; uint8_t preallocate_files; uint8_t preallocate_dirs; uint16_t: 16; // unused uint8_t journal_id[16]; uint32_t journal_inode; uint32_t journal_device; uint32_t head_of_orphan_inode_list; } att_packed ext2_sb_t; enum { EXT2_FS_STATE_CLEAN = 1, EXT2_FS_STATE_ERROR = 2, }; enum { EXT2_ERROR_ACTION_IGNORE = 1, EXT2_ERROR_ACTION_REMOUNT_RO = 2, EXT2_ERROR_ACTION_PANIC = 3, }; enum { EXT2_OS_ID_LINUX = 0, EXT2_OS_ID_GNU_HURD = 1, EXT2_OS_ID_MASIX = 2, EXT2_OS_ID_FREE_BSD = 3, EXT2_OS_ID_LITES = 4, }; enum { EXT2_FEATURE_OPTIONAL_PREALLOCATE = 0x01, EXT2_FEATURE_OPTIONAL_AFS_SERVER_INODE = 0x02, EXT2_FEATURE_OPTIONAL_HAS_JOURNAL = 0x04, EXT2_FEATURE_OPTIONAL_EXTENDED_ATTRIBUTES = 0x08, EXT2_FEATURE_OPTIONAL_CAN_RESIZE = 0x10, EXT2_FEATURE_OPTIONAL_DIR_HASH_INDEX = 0x20, }; #define EXT2_FEAT_OPT_SUPPORTED ( \ 0 \ ) enum { EXT2_FEATURE_REQUIRED_COMPRESSION = 0x01, EXT2_FEATURE_REQUIRED_DIR_HAS_TYPE = 0x02, EXT2_FEATURE_REQUIRED_JOURNAL_REPLAY_REQUIRED = 0x04, EXT2_FEATURE_REQUIRED_HAS_JOURNAL_DEVICE = 0x08, }; #define EXT2_FEAT_REQ_SUPPORTED ( \ EXT2_FEATURE_REQUIRED_DIR_HAS_TYPE | \ 0 \ ) enum { EXT2_FEATURE_RO_SPARSE_SUPERBLOCKS_AND_GROUPS_DESCRIPTOR = 0x01, EXT2_FEATURE_RO_64BIT_SIZE = 0x02, EXT2_FEATURE_RO_DIR_BTREE = 0X04 }; #define EXT2_FEAT_RO_64BIT_SIZE (SIZE_MAX > UINT32_MAX) #define EXT2_FEAT_RO_SUPPORTED ( \ (EXT2_FEAT_RO_64BIT_SIZE ? EXT2_FEATURE_RO_64BIT_SIZE : 0) | \ 0 \ ) typedef struct ext2_bg_descriptor { uint32_t block_usage_bm; uint32_t inode_usage_bm; uint32_t start_block_inode; uint16_t no_unallocated_blocks; uint16_t no_unallocated_inodes; uint16_t no_dirs; uint8_t unused[14]; } ext2_bg_descriptor_t; typedef struct ext2_inode { union { uint16_t type_permission; struct { uint8_t permission_o: 3; uint8_t permission_g: 3; uint8_t permission_u: 3; bool permission_sticky: 1; bool permission_setgid: 1; bool permission_setuid: 1; uint8_t type: 4; } att_packed; }; uint16_t uid; uint32_t size_l; uint32_t last_access; uint32_t created; uint32_t last_mod; uint32_t deleted; uint16_t gid; uint16_t no_hard_links; uint32_t no_sectors; uint32_t flags; uint32_t os_val1; uint32_t dbp[12]; // fist 12 direct block pointers uint32_t sibp; uint32_t dibp; uint32_t tibp; uint32_t generation; uint32_t extended_attr; union { uint32_t size_h; uint32_t dir_acl; }; uint32_t fragment_addr; uint8_t os_val2[12]; } att_packed ext2_inode_t; enum { EXT2_INODE_FLAG_SECURE_DELETE = 0x00000001, EXT2_INODE_FLAG_KEEP_COPY_ON_DELETE = 0x00000002, EXT2_INODE_FLAG_FILE_COMPRESSION = 0x00000004, EXT2_INODE_FLAG_SYNC_UPDATE = 0x00000008, EXT2_INODE_FLAG_IMMUTABLE = 0x00000010, EXT2_INODE_FLAG_APPEND_ONLY = 0x00000020, EXT2_INODE_FLAG_NO_DUMP = 0x00000040, EXT2_INODE_FLAG_LAST_ACCESS_IGNORE = 0x00000080, EXT2_INODE_FLAG_HASH_INDEXED_DIR = 0x00010000, EXT2_INODE_FLAG_AFS_DIRECTORY = 0x00020000, EXT2_INODE_FLAG_JOURNAL_FILE_DATA = 0x00040000, }; typedef struct ext2_dir_entry { uint32_t inode; uint16_t ent_size; uint8_t name_size; uint8_t type_or_name_size_h; char name; } ext2_dir_entry_t; enum { EXT2_INODE_TYPE_FIFO = 0x1, EXT2_INODE_TYPE_CHAR_DEV = 0x2, EXT2_INODE_TYPE_DIR = 0x4, EXT2_INODE_TYPE_BLOCK_DEV = 0x6, EXT2_INODE_TYPE_FILE = 0x8, EXT2_INODE_TYPE_SYM_LINK = 0xA, EXT2_INODE_TYPE_UNIX_SOCK = 0xC, }; enum { EXT2_DIR_TYPE_UNKNOWN = 0, EXT2_DIR_TYPE_FILE = 1, EXT2_DIR_TYPE_DIR = 2, EXT2_DIR_TYPE_CHAR_DEV = 3, EXT2_DIR_TYPE_BLOCK_DEV = 4, EXT2_DIR_TYPE_FIFO = 5, EXT2_DIR_TYPE_SOCKET = 6, EXT2_DIR_TYPE_SOFT_LINK = 7, }; typedef struct ext2_mount_info { ext2_sb_t sb; uint32_t no_block_groups; uint64_t block_size; uint64_t fragment_size; void *block_dev; } ext2_mount_info_t; #endif //NEW_KERNEL_EXT2_H