249 lines
6.4 KiB
C
249 lines
6.4 KiB
C
/*
|
|
* 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__ */
|