1 /* 2 * Copyright (c) 2023 Antmicro <www.antmicro.com> 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef __EXT2_STRUCT_H__ 8 #define __EXT2_STRUCT_H__ 9 10 #include <zephyr/kernel.h> 11 #include "ext2.h" 12 13 /* Disk structures ---------------------------------------------------------- */ 14 15 struct ext2_disk_superblock { 16 uint32_t s_inodes_count; 17 uint32_t s_blocks_count; 18 uint32_t s_r_blocks_count; 19 uint32_t s_free_blocks_count; 20 uint32_t s_free_inodes_count; 21 uint32_t s_first_data_block; 22 uint32_t s_log_block_size; 23 uint32_t s_log_frag_size; 24 uint32_t s_blocks_per_group; 25 uint32_t s_frags_per_group; 26 uint32_t s_inodes_per_group; 27 uint32_t s_mtime; 28 uint32_t s_wtime; 29 uint16_t s_mnt_count; 30 uint16_t s_max_mnt_count; 31 uint16_t s_magic; 32 uint16_t s_state; 33 uint16_t s_errors; 34 uint16_t s_minor_rev_level; 35 uint32_t s_lastcheck; 36 uint32_t s_checkinterval; 37 uint32_t s_creator_os; 38 uint32_t s_rev_level; 39 uint16_t s_def_resuid; 40 uint16_t s_def_resgid; 41 uint32_t s_first_ino; 42 uint16_t s_inode_size; 43 uint16_t s_block_group_nr; 44 uint32_t s_feature_compat; 45 uint32_t s_feature_incompat; 46 uint32_t s_feature_ro_compat; 47 uint8_t s_uuid[16]; 48 uint8_t s_volume_name[16]; 49 uint8_t s_last_mounted[64]; 50 uint32_t s_algo_bitmap; 51 uint8_t s_prealloc_blocks; 52 uint8_t s_prealloc_dir_blocks; 53 uint8_t s_align[2]; 54 uint8_t s_journal_uuid[16]; 55 uint32_t s_journal_inum; 56 uint32_t s_journal_dev; 57 uint32_t s_last_orphan; 58 uint8_t s_padding[788]; 59 } __packed; 60 61 struct ext2_disk_bgroup { 62 uint32_t bg_block_bitmap; 63 uint32_t bg_inode_bitmap; 64 uint32_t bg_inode_table; 65 uint16_t bg_free_blocks_count; 66 uint16_t bg_free_inodes_count; 67 uint16_t bg_used_dirs_count; 68 uint16_t bg_pad; 69 uint8_t bg_reserved[12]; 70 } __packed; 71 72 struct ext2_disk_inode { 73 uint16_t i_mode; 74 uint16_t i_uid; 75 uint32_t i_size; 76 uint32_t i_atime; 77 uint32_t i_ctime; 78 uint32_t i_mtime; 79 uint32_t i_dtime; 80 uint16_t i_gid; 81 uint16_t i_links_count; 82 uint32_t i_blocks; 83 uint32_t i_flags; 84 uint32_t i_osd1; 85 uint32_t i_block[15]; 86 uint32_t i_generation; 87 uint32_t i_file_acl; 88 uint32_t i_dir_acl; 89 uint32_t i_faddr; 90 uint8_t i_osd2[12]; 91 } __packed; 92 93 struct ext2_disk_direntry { 94 uint32_t de_inode; 95 uint16_t de_rec_len; 96 uint8_t de_name_len; 97 uint8_t de_file_type; 98 char de_name[]; 99 } __packed; 100 101 /* Program structures ------------------------------------------------------- */ 102 103 struct ext2_superblock { 104 uint32_t s_inodes_count; 105 uint32_t s_blocks_count; 106 uint32_t s_free_blocks_count; 107 uint32_t s_free_inodes_count; 108 uint32_t s_first_data_block; 109 uint32_t s_log_block_size; 110 uint32_t s_log_frag_size; 111 uint32_t s_blocks_per_group; 112 uint32_t s_frags_per_group; 113 uint32_t s_inodes_per_group; 114 uint16_t s_mnt_count; 115 uint16_t s_max_mnt_count; 116 uint16_t s_magic; 117 uint16_t s_state; 118 uint16_t s_errors; 119 uint32_t s_creator_os; 120 uint32_t s_rev_level; 121 uint32_t s_first_ino; 122 uint16_t s_inode_size; 123 uint16_t s_block_group_nr; 124 uint32_t s_feature_compat; 125 uint32_t s_feature_incompat; 126 uint32_t s_feature_ro_compat; 127 }; 128 129 #define EXT2_BLOCK_NUM_SIZE (sizeof(uint32_t)) 130 #define EXT2_DISK_DIRENTRY_BY_OFFSET(addr, offset) \ 131 ((struct ext2_disk_direntry *)(((uint8_t *)(addr)) + (offset))) 132 133 #define EXT2_BLOCK_ASSIGNED BIT(0) 134 135 struct ext2_block { 136 uint32_t num; 137 uint8_t flags; 138 uint8_t *data; 139 } __aligned(sizeof(void *)); 140 141 #define BGROUP_INODE_TABLE(bg) ((struct ext2_disk_inode *)(bg)->inode_table->data) 142 #define BGROUP_INODE_BITMAP(bg) ((uint8_t *)(bg)->inode_bitmap->data) 143 #define BGROUP_BLOCK_BITMAP(bg) ((uint8_t *)(bg)->block_bitmap->data) 144 145 struct ext2_bgroup { 146 struct ext2_data *fs; /* pointer to file system data */ 147 148 struct ext2_block *inode_table; /* fetched block of inode table */ 149 struct ext2_block *inode_bitmap; /* inode bitmap */ 150 struct ext2_block *block_bitmap; /* block bitmap */ 151 152 int32_t num; /* number of described block group */ 153 uint32_t inode_table_block; /* number of fetched block (relative) */ 154 155 uint32_t bg_block_bitmap; 156 uint32_t bg_inode_bitmap; 157 uint32_t bg_inode_table; 158 uint16_t bg_free_blocks_count; 159 uint16_t bg_free_inodes_count; 160 uint16_t bg_used_dirs_count; 161 }; 162 163 /* Flags for inode */ 164 #define INODE_FETCHED_BLOCK BIT(0) 165 #define INODE_REMOVE BIT(1) 166 167 struct ext2_inode { 168 struct ext2_data *i_fs; /* pointer to file system data */ 169 uint8_t i_ref; /* reference count */ 170 171 uint8_t flags; 172 uint32_t i_id; /* inode number */ 173 uint16_t i_mode; /* mode */ 174 uint16_t i_links_count; /* link count */ 175 uint32_t i_size; /* size */ 176 uint32_t i_blocks; /* number of reserved blocks (of size 512B) */ 177 uint32_t i_block[15]; /* numbers of blocks */ 178 179 int block_lvl; /* level of current block */ 180 uint32_t block_num; /* relative number of fetched block */ 181 uint32_t offsets[4]; /* offsets describing path to fetched block */ 182 struct ext2_block *blocks[4]; /* fetched blocks for each level */ 183 }; 184 inode_current_block(struct ext2_inode * inode)185static inline struct ext2_block *inode_current_block(struct ext2_inode *inode) 186 { 187 return inode->blocks[inode->block_lvl]; 188 } 189 inode_current_block_mem(struct ext2_inode * inode)190static inline uint8_t *inode_current_block_mem(struct ext2_inode *inode) 191 { 192 return (uint8_t *)inode_current_block(inode)->data; 193 } 194 195 struct ext2_direntry { 196 uint32_t de_inode; 197 uint16_t de_rec_len; 198 uint8_t de_name_len; 199 uint8_t de_file_type; 200 char de_name[]; 201 }; 202 203 /* Max size of directory entry that could be allocated from heap. */ 204 #define MAX_DIRENTRY_SIZE (sizeof(struct ext2_direntry) + UINT8_MAX) 205 206 /* Structure common for files and directories representation */ 207 struct ext2_file { 208 struct ext2_inode *f_inode; 209 uint32_t f_off; 210 uint8_t f_flags; 211 }; 212 213 #define EXT2_DATA_FLAGS_RO BIT(0) 214 #define EXT2_DATA_FLAGS_ERR BIT(1) 215 216 struct ext2_data; 217 218 struct ext2_backend_ops { 219 int64_t (*get_device_size)(struct ext2_data *fs); 220 int64_t (*get_write_size)(struct ext2_data *fs); 221 int (*read_block)(struct ext2_data *fs, void *buf, uint32_t num); 222 int (*write_block)(struct ext2_data *fs, const void *buf, uint32_t num); 223 int (*read_superblock)(struct ext2_data *fs, struct ext2_disk_superblock *sb); 224 int (*sync)(struct ext2_data *fs); 225 }; 226 227 #define MAX_INODES (CONFIG_MAX_FILES + 2) 228 229 struct ext2_data { 230 struct ext2_superblock sblock; /* superblock */ 231 struct ext2_bgroup bgroup; /* block group */ 232 233 int32_t open_inodes; 234 int32_t open_files; 235 struct ext2_inode *inode_pool[MAX_INODES]; 236 237 uint32_t sblock_offset; 238 uint32_t block_size; /* fs block size */ 239 uint32_t write_size; /* dev minimal write size */ 240 uint64_t device_size; 241 struct k_thread sync_thr; 242 243 void *backend; /* pointer to implementation specific resource */ 244 const struct ext2_backend_ops *backend_ops; 245 uint8_t flags; 246 }; 247 248 #endif /* __EXT2_STRUCT_H__ */ 249