| /* |
| * Copyright (c) 2023 Antmicro <www.antmicro.com> |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #ifndef __EXT2_STRUCT_H__ |
| #define __EXT2_STRUCT_H__ |
| |
| #include <zephyr/kernel.h> |
| #include "ext2.h" |
| |
| /* Disk structures ---------------------------------------------------------- */ |
| |
| struct ext2_disk_superblock { |
| uint32_t s_inodes_count; |
| uint32_t s_blocks_count; |
| uint32_t s_r_blocks_count; |
| uint32_t s_free_blocks_count; |
| uint32_t s_free_inodes_count; |
| uint32_t s_first_data_block; |
| uint32_t s_log_block_size; |
| uint32_t s_log_frag_size; |
| uint32_t s_blocks_per_group; |
| uint32_t s_frags_per_group; |
| uint32_t s_inodes_per_group; |
| uint32_t s_mtime; |
| uint32_t s_wtime; |
| uint16_t s_mnt_count; |
| uint16_t s_max_mnt_count; |
| uint16_t s_magic; |
| uint16_t s_state; |
| uint16_t s_errors; |
| uint16_t s_minor_rev_level; |
| uint32_t s_lastcheck; |
| uint32_t s_checkinterval; |
| uint32_t s_creator_os; |
| uint32_t s_rev_level; |
| uint16_t s_def_resuid; |
| uint16_t s_def_resgid; |
| uint32_t s_first_ino; |
| uint16_t s_inode_size; |
| uint16_t s_block_group_nr; |
| uint32_t s_feature_compat; |
| uint32_t s_feature_incompat; |
| uint32_t s_feature_ro_compat; |
| uint8_t s_uuid[16]; |
| uint8_t s_volume_name[16]; |
| uint8_t s_last_mounted[64]; |
| uint32_t s_algo_bitmap; |
| uint8_t s_prealloc_blocks; |
| uint8_t s_prealloc_dir_blocks; |
| uint8_t s_align[2]; |
| uint8_t s_journal_uuid[16]; |
| uint32_t s_journal_inum; |
| uint32_t s_journal_dev; |
| uint32_t s_last_orphan; |
| uint8_t s_padding[788]; |
| } __packed; |
| |
| struct ext2_disk_bgroup { |
| uint32_t bg_block_bitmap; |
| uint32_t bg_inode_bitmap; |
| uint32_t bg_inode_table; |
| uint16_t bg_free_blocks_count; |
| uint16_t bg_free_inodes_count; |
| uint16_t bg_used_dirs_count; |
| uint16_t bg_pad; |
| uint8_t bg_reserved[12]; |
| } __packed; |
| |
| struct ext2_disk_inode { |
| uint16_t i_mode; |
| uint16_t i_uid; |
| uint32_t i_size; |
| uint32_t i_atime; |
| uint32_t i_ctime; |
| uint32_t i_mtime; |
| uint32_t i_dtime; |
| uint16_t i_gid; |
| uint16_t i_links_count; |
| uint32_t i_blocks; |
| uint32_t i_flags; |
| uint32_t i_osd1; |
| uint32_t i_block[15]; |
| uint32_t i_generation; |
| uint32_t i_file_acl; |
| uint32_t i_dir_acl; |
| uint32_t i_faddr; |
| uint8_t i_osd2[12]; |
| } __packed; |
| |
| struct ext2_disk_direntry { |
| uint32_t de_inode; |
| uint16_t de_rec_len; |
| uint8_t de_name_len; |
| uint8_t de_file_type; |
| char de_name[]; |
| } __packed; |
| |
| /* Program structures ------------------------------------------------------- */ |
| |
| struct ext2_superblock { |
| uint32_t s_inodes_count; |
| uint32_t s_blocks_count; |
| uint32_t s_free_blocks_count; |
| uint32_t s_free_inodes_count; |
| uint32_t s_first_data_block; |
| uint32_t s_log_block_size; |
| uint32_t s_log_frag_size; |
| uint32_t s_blocks_per_group; |
| uint32_t s_frags_per_group; |
| uint32_t s_inodes_per_group; |
| uint16_t s_mnt_count; |
| uint16_t s_max_mnt_count; |
| uint16_t s_magic; |
| uint16_t s_state; |
| uint16_t s_errors; |
| uint32_t s_creator_os; |
| uint32_t s_rev_level; |
| uint32_t s_first_ino; |
| uint16_t s_inode_size; |
| uint16_t s_block_group_nr; |
| uint32_t s_feature_compat; |
| uint32_t s_feature_incompat; |
| uint32_t s_feature_ro_compat; |
| }; |
| |
| #define EXT2_BLOCK_NUM_SIZE (sizeof(uint32_t)) |
| #define EXT2_DISK_DIRENTRY_BY_OFFSET(addr, offset) \ |
| ((struct ext2_disk_direntry *)(((uint8_t *)(addr)) + (offset))) |
| |
| #define EXT2_BLOCK_ASSIGNED BIT(0) |
| |
| struct ext2_block { |
| uint32_t num; |
| uint8_t flags; |
| uint8_t *data; |
| } __aligned(sizeof(void *)); |
| |
| #define BGROUP_INODE_TABLE(bg) ((struct ext2_disk_inode *)(bg)->inode_table->data) |
| #define BGROUP_INODE_BITMAP(bg) ((uint8_t *)(bg)->inode_bitmap->data) |
| #define BGROUP_BLOCK_BITMAP(bg) ((uint8_t *)(bg)->block_bitmap->data) |
| |
| struct ext2_bgroup { |
| struct ext2_data *fs; /* pointer to file system data */ |
| |
| struct ext2_block *inode_table; /* fetched block of inode table */ |
| struct ext2_block *inode_bitmap; /* inode bitmap */ |
| struct ext2_block *block_bitmap; /* block bitmap */ |
| |
| int32_t num; /* number of described block group */ |
| uint32_t inode_table_block; /* number of fetched block (relative) */ |
| |
| uint32_t bg_block_bitmap; |
| uint32_t bg_inode_bitmap; |
| uint32_t bg_inode_table; |
| uint16_t bg_free_blocks_count; |
| uint16_t bg_free_inodes_count; |
| uint16_t bg_used_dirs_count; |
| }; |
| |
| /* Flags for inode */ |
| #define INODE_FETCHED_BLOCK BIT(0) |
| #define INODE_REMOVE BIT(1) |
| |
| struct ext2_inode { |
| struct ext2_data *i_fs; /* pointer to file system data */ |
| uint8_t i_ref; /* reference count */ |
| |
| uint8_t flags; |
| uint32_t i_id; /* inode number */ |
| uint16_t i_mode; /* mode */ |
| uint16_t i_links_count; /* link count */ |
| uint32_t i_size; /* size */ |
| uint32_t i_blocks; /* number of reserved blocks (of size 512B) */ |
| uint32_t i_block[15]; /* numbers of blocks */ |
| |
| int block_lvl; /* level of current block */ |
| uint32_t block_num; /* relative number of fetched block */ |
| uint32_t offsets[4]; /* offsets describing path to fetched block */ |
| struct ext2_block *blocks[4]; /* fetched blocks for each level */ |
| }; |
| |
| static inline struct ext2_block *inode_current_block(struct ext2_inode *inode) |
| { |
| return inode->blocks[inode->block_lvl]; |
| } |
| |
| static inline uint8_t *inode_current_block_mem(struct ext2_inode *inode) |
| { |
| return (uint8_t *)inode_current_block(inode)->data; |
| } |
| |
| struct ext2_direntry { |
| uint32_t de_inode; |
| uint16_t de_rec_len; |
| uint8_t de_name_len; |
| uint8_t de_file_type; |
| char de_name[]; |
| }; |
| |
| /* Max size of directory entry that could be allocated from heap. */ |
| #define MAX_DIRENTRY_SIZE (sizeof(struct ext2_direntry) + UINT8_MAX) |
| |
| /* Structure common for files and directories representation */ |
| struct ext2_file { |
| struct ext2_inode *f_inode; |
| uint32_t f_off; |
| uint8_t f_flags; |
| }; |
| |
| #define EXT2_DATA_FLAGS_RO BIT(0) |
| #define EXT2_DATA_FLAGS_ERR BIT(1) |
| |
| struct ext2_data; |
| |
| struct ext2_backend_ops { |
| int64_t (*get_device_size)(struct ext2_data *fs); |
| int64_t (*get_write_size)(struct ext2_data *fs); |
| int (*read_block)(struct ext2_data *fs, void *buf, uint32_t num); |
| int (*write_block)(struct ext2_data *fs, const void *buf, uint32_t num); |
| int (*read_superblock)(struct ext2_data *fs, struct ext2_disk_superblock *sb); |
| int (*sync)(struct ext2_data *fs); |
| }; |
| |
| #define MAX_INODES (CONFIG_MAX_FILES + 2) |
| |
| struct ext2_data { |
| struct ext2_superblock sblock; /* superblock */ |
| struct ext2_bgroup bgroup; /* block group */ |
| |
| int32_t open_inodes; |
| int32_t open_files; |
| struct ext2_inode *inode_pool[MAX_INODES]; |
| |
| uint32_t sblock_offset; |
| uint32_t block_size; /* fs block size */ |
| uint32_t write_size; /* dev minimal write size */ |
| uint64_t device_size; |
| struct k_thread sync_thr; |
| |
| void *backend; /* pointer to implementation specific resource */ |
| const struct ext2_backend_ops *backend_ops; |
| uint8_t flags; |
| }; |
| |
| #endif /* __EXT2_STRUCT_H__ */ |