wolfBoot/include/ext4.h

153 lines
5.3 KiB
C

/* ext4.h
*
* Copyright (C) 2026 wolfSSL Inc.
*
* This file is part of wolfBoot.
*
* wolfBoot is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfBoot 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* On-disk ext4 layout constants and the ext4 backend interface.
*/
#ifndef WOLFBOOT_EXT4_H
#define WOLFBOOT_EXT4_H
#include <stdint.h>
/* The superblock always starts 1024 bytes into the volume. */
#define EXT4_SB_OFF 1024U
/* Superblock fields are read in two contiguous groups so that no single
* stack buffer gets large; both land in the same metadata cache window. */
#define EXT4_SB_A_OFF 0x00U
#define EXT4_SB_A_LEN 0x2CU
#define EXT4_SB_B_OFF 0x38U
#define EXT4_SB_B_LEN 0x30U
/* Offsets within group A */
#define EXT4_A_INODES_COUNT 0x00U
#define EXT4_A_BLOCKS_COUNT_LO 0x04U
#define EXT4_A_FIRST_DATA_BLOCK 0x14U
#define EXT4_A_LOG_BLOCK_SIZE 0x18U
#define EXT4_A_LOG_CLUSTER_SIZE 0x1CU
#define EXT4_A_BLOCKS_PER_GROUP 0x20U
#define EXT4_A_INODES_PER_GROUP 0x28U
/* Offsets within group B (relative to EXT4_SB_B_OFF) */
#define EXT4_B_MAGIC 0x00U
#define EXT4_B_STATE 0x02U
#define EXT4_B_REV_LEVEL 0x14U
#define EXT4_B_FIRST_INO 0x1CU
#define EXT4_B_INODE_SIZE 0x20U
#define EXT4_B_FEATURE_INCOMPAT 0x28U
/* Standalone superblock fields */
#define EXT4_SB_VOLUME_NAME 0x78U
#define EXT4_SB_VOLUME_NAME_LEN 16U
#define EXT4_SB_DESC_SIZE 0xFEU
#define EXT4_SB_BLOCKS_COUNT_HI 0x150U
#define EXT4_SUPER_MAGIC 0xEF53U
#define EXT4_ROOT_INO 2U
#define EXT4_GOOD_OLD_INO_SZ 128U
#define EXT4_STATE_VALID_FS 0x0001U
/* INCOMPAT feature bits. A whitelist, tested as "any bit not in it", so
* every unlisted bit - including ones defined after this was written - is
* refused. That is what makes the parser fail closed: COMPRESSION, RECOVER
* (dirty journal), JOURNAL_DEV, META_BG, MMP, DIRDATA, LARGEDIR,
* INLINE_DATA, ENCRYPT and CASEFOLD all land outside it. */
#define EXT4_INCOMPAT_FILETYPE 0x0002U
#define EXT4_INCOMPAT_EXTENTS 0x0040U
#define EXT4_INCOMPAT_64BIT 0x0080U
#define EXT4_INCOMPAT_FLEX_BG 0x0200U
#define EXT4_INCOMPAT_EA_INODE 0x0400U
#define EXT4_INCOMPAT_CSUM_SEED 0x2000U
#define EXT4_INCOMPAT_SUPPORTED ( \
EXT4_INCOMPAT_FILETYPE /* dirent type byte; optional, handled */ \
| EXT4_INCOMPAT_EXTENTS /* required outright, see ext4_mount */ \
| EXT4_INCOMPAT_64BIT /* descriptor geometry only; hi refused */ \
| EXT4_INCOMPAT_FLEX_BG /* allocation policy, layout-neutral */ \
| EXT4_INCOMPAT_EA_INODE /* extended attributes, never read */ \
| EXT4_INCOMPAT_CSUM_SEED /* checksum seed, layout-neutral */ )
/* Inode flags */
#define EXT4_FL_COMPR 0x00000004U
#define EXT4_FL_ENCRYPT 0x00000800U
#define EXT4_FL_EXTENTS 0x00080000U
#define EXT4_FL_INLINE_DATA 0x10000000U
/* Inode layout */
#define EXT4_INODE_MODE 0x00U
#define EXT4_INODE_SIZE_LO 0x04U
#define EXT4_INODE_FLAGS 0x20U
#define EXT4_INODE_BLOCK 0x28U
#define EXT4_INODE_BLOCK_LEN 60U
#define EXT4_INODE_SIZE_HIGH 0x6CU
#define EXT4_INODE_HDR_LEN 0x24U
#define EXT4_S_IFMT 0xF000U
#define EXT4_S_IFREG 0x8000U
#define EXT4_S_IFDIR 0x4000U
#define EXT4_S_IFLNK 0xA000U
/* Group descriptor */
#define EXT4_GD_INODE_TABLE_LO 0x08U
#define EXT4_GD_INODE_TABLE_HI 0x28U
#define EXT4_GD_MIN_SIZE 32U
#define EXT4_GD_64BIT_SIZE 64U
/* Extent tree */
#define EXT4_EXT_MAGIC 0xF30AU
#define EXT4_EXT_HDR_LEN 12U
#define EXT4_EXT_ENT_LEN 12U
#define EXT4_EXT_ROOT_CAP 60U
#define EXT4_EXT_INIT_MAX_LEN 32768U
/* Directory entry */
#define EXT4_DIRENT_HDR_LEN 8U
#define EXT4_FT_SYMLINK 7U
#define EXT4_NAME_MAX 255U
/* ext4 geometry, validated at mount. */
struct ext4_volume {
uint64_t gdt_off; /* byte offset of the group descriptor table */
uint64_t vol_sz; /* blocks_count * block_sz, <= partition size */
uint32_t block_sz;
uint32_t blocks_count;
uint32_t inodes_count;
uint32_t inodes_per_group;
uint32_t blocks_per_group;
uint32_t first_data_block;
uint32_t groups;
uint32_t incompat; /* validated feature word (FILETYPE is read) */
uint16_t inode_sz;
uint16_t desc_sz; /* 32, or s_desc_size when INCOMPAT_64BIT */
};
struct fs_volume;
struct fs_file;
/* Backend entry points; same NOFS / UNSUPPORTED split as fat32_mount(). */
int ext4_mount(struct fs_volume *vol);
int ext4_open(struct fs_volume *vol, struct fs_file *f, const char *path,
uint64_t max_size);
int ext4_read(struct fs_file *f, uint64_t off, uint64_t len, uint8_t *buf);
int ext4_label_eq(struct fs_volume *vol, const char *label);
#endif /* WOLFBOOT_EXT4_H */