mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-11-29 12:35:53 +01:00
502 lines
18 KiB
C
502 lines
18 KiB
C
/** @file
|
|
Raw filesystem data structures
|
|
|
|
Copyright (c) 2021 - 2023 Pedro Falcato All rights reserved.
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
Layout of an EXT2/3/4 filesystem:
|
|
(note: this driver has been developed using
|
|
https://www.kernel.org/doc/html/latest/filesystems/ext4/index.html as
|
|
documentation).
|
|
|
|
An ext2/3/4 filesystem (here on out referred to as simply an ext4 filesystem,
|
|
due to the similarities) is composed of various concepts:
|
|
|
|
1) Superblock
|
|
The superblock is the structure near (1024 bytes offset from the start)
|
|
the start of the partition, and describes the filesystem in general.
|
|
Here, we get to know the size of the filesystem's blocks, which features
|
|
it supports or not, whether it's been cleanly unmounted, how many blocks
|
|
we have, etc.
|
|
|
|
2) Block groups
|
|
EXT4 filesystems are divided into block groups, and each block group covers
|
|
s_blocks_per_group(8 * Block Size) blocks. Each block group has an
|
|
associated block group descriptor; these are present directly after the
|
|
superblock. Each block group descriptor contains the location of the
|
|
inode table, and the inode and block bitmaps (note these bitmaps are only
|
|
a block long, which gets us the 8 * Block Size formula covered previously).
|
|
|
|
3) Blocks
|
|
The ext4 filesystem is divided in blocks, of size s_log_block_size ^ 1024.
|
|
Blocks can be allocated using individual block groups's bitmaps. Note
|
|
that block 0 is invalid and its presence on extents/block tables means
|
|
it's part of a file hole, and that particular location must be read as
|
|
a block full of zeros.
|
|
|
|
4) Inodes
|
|
The ext4 filesystem divides files/directories into inodes (originally
|
|
index nodes). Each file/socket/symlink/directory/etc (here on out referred
|
|
to as a file, since there is no distinction under the ext4 filesystem) is
|
|
stored as a /nameless/ inode, that is stored in some block group's inode
|
|
table. Each inode has s_inode_size size (or GOOD_OLD_INODE_SIZE if it's
|
|
an old filesystem), and holds various metadata about the file. Since the
|
|
largest inode structure right now is ~160 bytes, the rest of the inode
|
|
contains inline extended attributes. Inodes' data is stored using either
|
|
data blocks (under ext2/3) or extents (under ext4).
|
|
|
|
5) Extents
|
|
Ext4 inodes store data in extents. These let N contiguous logical blocks
|
|
that are represented by N contiguous physical blocks be represented by a
|
|
single extent structure, which minimizes filesystem metadata bloat and
|
|
speeds up block mapping (particularly due to the fact that high-quality
|
|
ext4 implementations like linux's try /really/ hard to make the file
|
|
contiguous, so it's common to have files with almost 0 fragmentation).
|
|
Inodes that use extents store them in a tree, and the top of the tree
|
|
is stored on i_data. The tree's leaves always start with an
|
|
EXT4_EXTENT_HEADER and contain EXT4_EXTENT_INDEX on eh_depth != 0 and
|
|
EXT4_EXTENT on eh_depth = 0; these entries are always sorted by logical
|
|
block.
|
|
|
|
6) Directories
|
|
Ext4 directories are files that store name -> inode mappings for the
|
|
logical directory; this is where files get their names, which means ext4
|
|
inodes do not themselves have names, since they can be linked (present)
|
|
multiple times with different names. Directories can store entries in two
|
|
different ways:
|
|
1) Classical linear directories: They store entries as a mostly-linked
|
|
mostly-list of EXT4_DIR_ENTRY.
|
|
2) Hash tree directories: These are used for larger directories, with
|
|
hundreds of entries, and are designed in a backwards compatible way.
|
|
These are not yet implemented in the Ext4Dxe driver.
|
|
|
|
7) Journal
|
|
Ext3/4 filesystems have a journal to help protect the filesystem against
|
|
system crashes. This is not yet implemented in Ext4Dxe but is described
|
|
in detail in the Linux kernel's documentation.
|
|
**/
|
|
|
|
#ifndef EXT4_DISK_H_
|
|
#define EXT4_DISK_H_
|
|
|
|
#include <Uefi.h>
|
|
|
|
#define EXT4_SUPERBLOCK_OFFSET 1024U
|
|
|
|
#define EXT4_SIGNATURE 0xEF53U
|
|
|
|
#define EXT4_FS_STATE_UNMOUNTED 0x1
|
|
#define EXT4_FS_STATE_ERRORS_DETECTED 0x2
|
|
#define EXT4_FS_STATE_RECOVERING_ORPHANS 0x4
|
|
|
|
#define EXT4_ERRORS_CONTINUE 1
|
|
#define EXT4_ERRORS_RO 2
|
|
#define EXT4_ERRORS_PANIC 3
|
|
|
|
#define EXT4_LINUX_ID 0
|
|
#define EXT4_GNU_HURD_ID 1
|
|
#define EXT4_MASIX_ID 2
|
|
#define EXT4_FREEBSD_ID 3
|
|
#define EXT4_LITES_ID 4
|
|
|
|
#define EXT4_GOOD_OLD_REV 0
|
|
#define EXT4_DYNAMIC_REV 1
|
|
|
|
#define EXT4_CHECKSUM_CRC32C 0x1
|
|
|
|
#define EXT4_FEATURE_COMPAT_DIR_PREALLOC 0x01
|
|
#define EXT4_FEATURE_COMPAT_IMAGIC_INODES 0x02
|
|
#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x04
|
|
#define EXT4_FEATURE_COMPAT_EXT_ATTR 0x08
|
|
#define EXT4_FEATURE_COMPAT_RESIZE_INO 0x10
|
|
#define EXT4_FEATURE_COMPAT_DIR_INDEX 0x20
|
|
|
|
#define EXT4_FEATURE_INCOMPAT_COMPRESSION 0x00001
|
|
#define EXT4_FEATURE_INCOMPAT_FILETYPE 0x00002
|
|
#define EXT4_FEATURE_INCOMPAT_RECOVER 0x00004
|
|
#define EXT4_FEATURE_INCOMPAT_JOURNAL_DEV 0x00008
|
|
#define EXT4_FEATURE_INCOMPAT_META_BG 0x00010
|
|
#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x00040
|
|
#define EXT4_FEATURE_INCOMPAT_64BIT 0x00080
|
|
#define EXT4_FEATURE_INCOMPAT_MMP 0x00100
|
|
#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x00200
|
|
#define EXT4_FEATURE_INCOMPAT_EA_INODE 0x00400
|
|
// It's not clear whether or not this feature (below) is used right now
|
|
#define EXT4_FEATURE_INCOMPAT_DIRDATA 0x01000
|
|
#define EXT4_FEATURE_INCOMPAT_CSUM_SEED 0x02000
|
|
#define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x04000
|
|
#define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x08000
|
|
#define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000
|
|
|
|
#define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
|
|
#define EXT4_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
|
|
#define EXT4_FEATURE_RO_COMPAT_BTREE_DIR 0x0004// Unused
|
|
#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008
|
|
#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010
|
|
#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020
|
|
#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040
|
|
#define EXT4_FEATURE_RO_COMPAT_HAS_SNAPSHOT 0x0080// Not implemented in ext4
|
|
#define EXT4_FEATURE_RO_COMPAT_QUOTA 0x0100
|
|
#define EXT4_FEATURE_RO_COMPAT_BIGALLOC 0x0200
|
|
#define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM 0x0400
|
|
#define EXT4_FEATURE_RO_COMPAT_REPLICA 0x0800// Not used
|
|
|
|
// We explicitly don't recognise this, so we get read only.
|
|
#define EXT4_FEATURE_RO_COMPAT_READONLY 0x1000
|
|
#define EXT4_FEATURE_RO_COMPAT_PROJECT 0x2000
|
|
|
|
/* Important notes about the features
|
|
* Absolutely needed features:
|
|
* 1) Every incompat, because we might want to mount root filesystems
|
|
* 2) Relevant RO_COMPATs(I'm not sure of what to do wrt quota, project)
|
|
**/
|
|
|
|
#define EXT4_INO_TYPE_FIFO 0x1000
|
|
#define EXT4_INO_TYPE_CHARDEV 0x2000
|
|
#define EXT4_INO_TYPE_DIR 0x4000
|
|
#define EXT4_INO_TYPE_BLOCKDEV 0x6000
|
|
#define EXT4_INO_TYPE_REGFILE 0x8000
|
|
#define EXT4_INO_TYPE_SYMLINK 0xA000
|
|
#define EXT4_INO_TYPE_UNIX_SOCK 0xC000
|
|
|
|
/* Inode flags */
|
|
#define EXT4_SECRM_FL 0x00000001
|
|
#define EXT4_UNRM_FL 0x00000002
|
|
#define EXT4_COMPR_FL 0x00000004
|
|
#define EXT4_SYNC_FL 0x00000008
|
|
#define EXT4_IMMUTABLE_FL 0x00000010
|
|
#define EXT4_APPEND_FL 0x00000020
|
|
#define EXT4_NODUMP_FL 0x00000040
|
|
#define EXT4_NOATIME_FL 0x00000080
|
|
#define EXT4_DIRTY_FL 0x00000100
|
|
#define EXT4_COMPRBLK_FL 0x00000200
|
|
#define EXT4_NOCOMPR_FL 0x00000400
|
|
#define EXT4_ENCRYPT_FL 0x00000800
|
|
#define EXT4_BTREE_FL 0x00001000
|
|
#define EXT4_INDEX_FL 0x00002000
|
|
#define EXT4_JOURNAL_DATA_FL 0x00004000
|
|
#define EXT4_NOTAIL_FL 0x00008000
|
|
#define EXT4_DIRSYNC_FL 0x00010000
|
|
#define EXT4_TOPDIR_FL 0x00020000
|
|
#define EXT4_HUGE_FILE_FL 0x00040000
|
|
#define EXT4_EXTENTS_FL 0x00080000
|
|
#define EXT4_VERITY_FL 0x00100000
|
|
#define EXT4_EA_INODE_FL 0x00200000
|
|
#define EXT4_RESERVED_FL 0x80000000
|
|
|
|
/* File type flags that are stored in the directory entries */
|
|
#define EXT4_FT_UNKNOWN 0
|
|
#define EXT4_FT_REG_FILE 1
|
|
#define EXT4_FT_DIR 2
|
|
#define EXT4_FT_CHRDEV 3
|
|
#define EXT4_FT_BLKDEV 4
|
|
#define EXT4_FT_FIFO 5
|
|
#define EXT4_FT_SOCK 6
|
|
#define EXT4_FT_SYMLINK 7
|
|
|
|
typedef struct {
|
|
UINT32 s_inodes_count;
|
|
UINT32 s_blocks_count;
|
|
UINT32 s_r_blocks_count;
|
|
UINT32 s_free_blocks_count;
|
|
UINT32 s_free_inodes_count;
|
|
UINT32 s_first_data_block;
|
|
UINT32 s_log_block_size;
|
|
UINT32 s_log_frag_size;
|
|
UINT32 s_blocks_per_group;
|
|
UINT32 s_frags_per_group;
|
|
UINT32 s_inodes_per_group;
|
|
UINT32 s_mtime;
|
|
UINT32 s_wtime;
|
|
UINT16 s_mnt_count;
|
|
UINT16 s_max_mnt_count;
|
|
UINT16 s_magic;
|
|
UINT16 s_state;
|
|
UINT16 s_errors;
|
|
UINT16 s_minor_rev_level;
|
|
UINT32 s_lastcheck;
|
|
UINT32 s_check_interval;
|
|
UINT32 s_creator_os;
|
|
UINT32 s_rev_level;
|
|
UINT16 s_def_resuid;
|
|
UINT16 s_def_resgid;
|
|
|
|
/* Every field after this comment is revision >= 1 */
|
|
|
|
UINT32 s_first_ino;
|
|
UINT16 s_inode_size;
|
|
UINT16 s_block_group_nr;
|
|
UINT32 s_feature_compat;
|
|
UINT32 s_feature_incompat;
|
|
UINT32 s_feature_ro_compat;
|
|
UINT8 s_uuid[16];
|
|
UINT8 s_volume_name[16];
|
|
UINT8 s_last_mounted[64];
|
|
UINT32 s_algo_bitmap;
|
|
UINT8 s_prealloc_blocks;
|
|
UINT8 s_prealloc_dir_blocks;
|
|
UINT16 unused;
|
|
UINT8 s_journal_uuid[16];
|
|
UINT32 s_journal_inum;
|
|
UINT32 s_journal_dev;
|
|
UINT32 s_last_orphan;
|
|
UINT32 s_hash_seed[4];
|
|
UINT8 s_def_hash_version;
|
|
UINT8 s_jnl_backup_type;
|
|
UINT16 s_desc_size;
|
|
UINT32 s_default_mount_options;
|
|
UINT32 s_first_meta_bg;
|
|
UINT32 s_mkfs_time;
|
|
UINT32 s_jnl_blocks[17];
|
|
UINT32 s_blocks_count_hi;
|
|
UINT32 s_r_blocks_count_hi;
|
|
UINT32 s_free_blocks_count_hi;
|
|
UINT16 s_min_extra_isize;
|
|
UINT16 s_want_extra_isize;
|
|
UINT32 s_flags;
|
|
UINT16 s_raid_stride;
|
|
UINT16 s_mmp_interval;
|
|
UINT64 s_mmp_block;
|
|
UINT32 s_raid_stride_width;
|
|
UINT8 s_log_groups_per_flex;
|
|
UINT8 s_checksum_type; // Only valid value is 1 - CRC32C
|
|
UINT16 s_reserved_pad;
|
|
UINT64 s_kbytes_written;
|
|
|
|
// Snapshot stuff isn't used in Linux and isn't implemented here
|
|
UINT32 s_snapshot_inum;
|
|
UINT32 s_snapshot_id;
|
|
UINT64 s_snapshot_r_blocks_count;
|
|
UINT32 s_snapshot_list;
|
|
UINT32 s_error_count;
|
|
UINT32 s_first_error_time;
|
|
UINT32 s_first_error_ino;
|
|
UINT64 s_first_error_block;
|
|
UINT8 s_first_error_func[32];
|
|
UINT32 s_first_error_line;
|
|
UINT32 s_last_error_time;
|
|
UINT32 s_last_error_ino;
|
|
UINT32 s_last_error_line;
|
|
UINT64 s_last_error_block;
|
|
UINT8 s_last_error_func[32];
|
|
UINT8 s_mount_opts[64];
|
|
UINT32 s_usr_quota_inum;
|
|
UINT32 s_grp_quota_inum;
|
|
UINT32 s_overhead_blocks;
|
|
UINT32 s_backup_bgs[2]; // sparse_super2
|
|
UINT8 s_encrypt_algos[4];
|
|
UINT8 s_encrypt_pw_salt[16];
|
|
UINT32 s_lpf_ino;
|
|
UINT32 s_prj_quota_inum;
|
|
UINT32 s_checksum_seed;
|
|
UINT32 s_reserved[98];
|
|
UINT32 s_checksum;
|
|
} EXT4_SUPERBLOCK;
|
|
|
|
STATIC_ASSERT (
|
|
sizeof (EXT4_SUPERBLOCK) == 1024,
|
|
"ext4 superblock struct has incorrect size"
|
|
);
|
|
|
|
typedef struct {
|
|
UINT32 bg_block_bitmap_lo;
|
|
UINT32 bg_inode_bitmap_lo;
|
|
UINT32 bg_inode_table_lo;
|
|
UINT16 bg_free_blocks_count_lo;
|
|
UINT16 bg_free_inodes_count_lo;
|
|
UINT16 bg_used_dirs_count_lo;
|
|
UINT16 bg_flags;
|
|
UINT32 bg_exclude_bitmap_lo;
|
|
UINT16 bg_block_bitmap_csum_lo;
|
|
UINT16 bg_inode_bitmap_csum_lo;
|
|
UINT16 bg_itable_unused_lo;
|
|
UINT16 bg_checksum;
|
|
UINT32 bg_block_bitmap_hi;
|
|
UINT32 bg_inode_bitmap_hi;
|
|
UINT32 bg_inode_table_hi;
|
|
UINT16 bg_free_blocks_count_hi;
|
|
UINT16 bg_free_inodes_count_hi;
|
|
UINT16 bg_used_dirs_count_hi;
|
|
UINT16 bg_itable_unused_hi;
|
|
UINT32 bg_exclude_bitmap_hi;
|
|
UINT16 bg_block_bitmap_csum_hi;
|
|
UINT16 bg_inode_bitmap_csum_hi;
|
|
UINT32 bg_reserved;
|
|
} EXT4_BLOCK_GROUP_DESC;
|
|
|
|
#define EXT4_OLD_BLOCK_DESC_SIZE 32
|
|
#define EXT4_64BIT_BLOCK_DESC_SIZE 64
|
|
|
|
STATIC_ASSERT (
|
|
sizeof (EXT4_BLOCK_GROUP_DESC) == EXT4_64BIT_BLOCK_DESC_SIZE,
|
|
"ext4 block group descriptor struct has incorrect size"
|
|
);
|
|
|
|
#define EXT4_DBLOCKS 12
|
|
#define EXT4_IND_BLOCK 12
|
|
#define EXT4_DIND_BLOCK 13
|
|
#define EXT4_TIND_BLOCK 14
|
|
#define EXT4_NR_BLOCKS 15
|
|
#define EXT4_FAST_SYMLINK_MAX_SIZE EXT4_NR_BLOCKS * sizeof(UINT32)
|
|
|
|
#define EXT4_GOOD_OLD_INODE_SIZE 128U
|
|
|
|
typedef struct _Ext4_I_OSD2_Linux {
|
|
UINT16 l_i_blocks_high;
|
|
UINT16 l_i_file_acl_high;
|
|
UINT16 l_i_uid_high;
|
|
UINT16 l_i_gid_high;
|
|
UINT16 l_i_checksum_lo;
|
|
UINT16 l_i_reserved;
|
|
} EXT4_OSD2_LINUX;
|
|
|
|
typedef struct _Ext4_I_OSD2_Hurd {
|
|
UINT16 h_i_reserved1;
|
|
UINT16 h_i_mode_high;
|
|
UINT16 h_i_uid_high;
|
|
UINT16 h_i_gid_high;
|
|
UINT32 h_i_author;
|
|
} EXT4_OSD2_HURD;
|
|
|
|
typedef union {
|
|
// Note: Toolchain-specific defines (such as "linux") stops us from using
|
|
// simpler names down here.
|
|
EXT4_OSD2_LINUX data_linux;
|
|
EXT4_OSD2_HURD data_hurd;
|
|
} EXT4_OSD2;
|
|
|
|
typedef struct _Ext4Inode {
|
|
UINT16 i_mode;
|
|
UINT16 i_uid;
|
|
UINT32 i_size_lo;
|
|
UINT32 i_atime;
|
|
UINT32 i_ctime;
|
|
UINT32 i_mtime;
|
|
UINT32 i_dtime;
|
|
UINT16 i_gid;
|
|
UINT16 i_links;
|
|
UINT32 i_blocks;
|
|
UINT32 i_flags;
|
|
UINT32 i_os_spec;
|
|
UINT32 i_data[EXT4_NR_BLOCKS];
|
|
UINT32 i_generation;
|
|
UINT32 i_file_acl;
|
|
UINT32 i_size_hi;
|
|
UINT32 i_faddr;
|
|
|
|
EXT4_OSD2 i_osd2;
|
|
|
|
UINT16 i_extra_isize;
|
|
UINT16 i_checksum_hi;
|
|
UINT32 i_ctime_extra;
|
|
UINT32 i_mtime_extra;
|
|
UINT32 i_atime_extra;
|
|
UINT32 i_crtime;
|
|
UINT32 i_crtime_extra;
|
|
UINT32 i_version_hi;
|
|
UINT32 i_projid;
|
|
} EXT4_INODE;
|
|
|
|
#define EXT4_NAME_MAX 255
|
|
|
|
typedef struct {
|
|
// offset 0x0: inode number (if 0, unused entry, should skip.)
|
|
UINT32 inode;
|
|
// offset 0x4: Directory entry's length.
|
|
// Note: rec_len >= name_len + EXT4_MIN_DIR_ENTRY_LEN and rec_len % 4 == 0.
|
|
UINT16 rec_len;
|
|
// offset 0x6: Directory entry's name's length
|
|
UINT8 name_len;
|
|
// offset 0x7: Directory entry's file type indicator
|
|
UINT8 file_type;
|
|
// offset 0x8: name[name_len]: Variable length character array; not null-terminated.
|
|
CHAR8 name[EXT4_NAME_MAX];
|
|
// Further notes on names:
|
|
// 1) We use EXT4_NAME_MAX here instead of flexible arrays for ease of use around the driver.
|
|
//
|
|
// 2) ext4 directories are defined, as the documentation puts it, as:
|
|
// "a directory is more or less a flat file that maps an arbitrary byte string
|
|
// (usually ASCII) to an inode number on the filesystem". So, they are not
|
|
// necessarily encoded with ASCII, UTF-8, or any of the sort. We must treat it
|
|
// as a bag of bytes. When interacting with EFI interfaces themselves (which expect UCS-2)
|
|
// we skip any directory entry that is not valid UTF-8.
|
|
} EXT4_DIR_ENTRY;
|
|
|
|
#define EXT4_MIN_DIR_ENTRY_LEN 8
|
|
|
|
// This on-disk structure is present at the bottom of the extent tree
|
|
typedef struct {
|
|
// First logical block
|
|
UINT32 ee_block;
|
|
// Length of the extent, in blocks
|
|
UINT16 ee_len;
|
|
// The physical (filesystem-relative) block is split between the high 16 bits
|
|
// and the low 32 bits - this forms a 48-bit block number
|
|
UINT16 ee_start_hi;
|
|
UINT32 ee_start_lo;
|
|
} EXT4_EXTENT;
|
|
|
|
// This on-disk structure is present at all levels except the bottom
|
|
typedef struct {
|
|
// This index covers logical blocks from 'ei_block'
|
|
UINT32 ei_block;
|
|
// Block of the next level of the extent tree, similarly split in a high and
|
|
// low portion.
|
|
UINT32 ei_leaf_lo;
|
|
UINT16 ei_leaf_hi;
|
|
|
|
UINT16 ei_unused;
|
|
} EXT4_EXTENT_INDEX;
|
|
|
|
typedef struct {
|
|
// Needs to be EXT4_EXTENT_HEADER_MAGIC
|
|
UINT16 eh_magic;
|
|
// Number of entries
|
|
UINT16 eh_entries;
|
|
// Maximum number of entries that could follow this header
|
|
UINT16 eh_max;
|
|
// Depth of this node in the tree - the tree can be at most 5 levels deep
|
|
UINT16 eh_depth;
|
|
// Unused by standard ext4
|
|
UINT32 eh_generation;
|
|
} EXT4_EXTENT_HEADER;
|
|
|
|
#define EXT4_EXTENT_HEADER_MAGIC 0xF30A
|
|
|
|
// Specified by ext4 docs and backed by a bunch of math
|
|
#define EXT4_EXTENT_TREE_MAX_DEPTH 5
|
|
|
|
typedef struct {
|
|
// CRC32C of UUID + inode number + igeneration + extent block
|
|
UINT32 eb_checksum;
|
|
} EXT4_EXTENT_TAIL;
|
|
|
|
/**
|
|
* EXT4 has this feature called uninitialized extents:
|
|
* An extent has a maximum of 32768 blocks (2^15 or 1 << 15).
|
|
* When we find an extent with > 32768 blocks, this extent is called
|
|
* uninitialized. Long story short, it's an extent that behaves as a file hole
|
|
* but has blocks already allocated.
|
|
*/
|
|
#define EXT4_EXTENT_MAX_INITIALIZED (1 << 15)
|
|
|
|
typedef UINT64 EXT4_BLOCK_NR;
|
|
typedef UINT32 EXT2_BLOCK_NR;
|
|
typedef UINT32 EXT4_INO_NR;
|
|
|
|
/* Special inode numbers */
|
|
#define EXT4_ROOT_INODE_NR 2
|
|
#define EXT4_USR_QUOTA_INODE_NR 3
|
|
#define EXT4_GRP_QUOTA_INODE_NR 4
|
|
#define EXT4_BOOT_LOADER_INODE_NR 5
|
|
#define EXT4_UNDEL_DIR_INODE_NR 6
|
|
#define EXT4_RESIZE_INODE_NR 7
|
|
#define EXT4_JOURNAL_INODE_NR 8
|
|
|
|
/* First non-reserved inode for old ext4 filesystems */
|
|
#define EXT4_GOOD_OLD_FIRST_INODE_NR 11
|
|
|
|
#define EXT4_BLOCK_FILE_HOLE 0
|
|
|
|
#endif
|