// ext2.h // Author: Josh Holtrop // Date: 08/22/04 // Modified: 12/24/04 #ifndef __HOS_EXT2_H__ #define __HOS_EXT2_H__ __HOS_EXT2_H__ #include "hos_defines.h" #include "fs/devices.h" #include "fs/vfs.h" #define EXT2_MAGIC 0xEF53 #define EXT2_NAME_LEN 255 #define EXT2_I_MODE_ATTR_MASK 0x0FFF #define EXT2_I_MODE_OX 0x0001 #define EXT2_I_MODE_OW 0x0002 #define EXT2_I_MODE_OR 0x0004 #define EXT2_I_MODE_GX 0x0008 #define EXT2_I_MODE_GW 0x0010 #define EXT2_I_MODE_GR 0x0020 #define EXT2_I_MODE_UX 0x0040 #define EXT2_I_MODE_UW 0x0080 #define EXT2_I_MODE_UR 0x0100 #define EXT2_I_MODE_STICKY 0x0200 #define EXT2_I_MODE_SGID 0x0400 #define EXT2_I_MODE_SUID 0x0800 #define EXT2_I_MODE_TYPE_MASK 0xF000 #define EXT2_I_MODE_FIFO 0x1000 #define EXT2_I_MODE_CHAR 0x2000 #define EXT2_I_MODE_DIR 0x4000 #define EXT2_I_MODE_BLOCK 0x6000 #define EXT2_I_MODE_FILE 0x8000 #define EXT2_I_MODE_SYM 0xA000 #define EXT2_I_MODE_SOCK 0xC000 #define EXT2_I_FLAGS_SEC_DEL 0x01 #define EXT2_I_FLAGS_UNDELETE 0x02 #define EXT2_I_FLAGS_COMPRESS 0x04 #define EXT2_I_FLAGS_SYNC 0x08 #define EXT2_I_FLAGS_IMMUTABLE 0x10 #define EXT2_I_FLAGS_APPEND 0x20 #define EXT2_I_FLAGS_NODUMP 0x40 #define EXT2_INODE_BAD_BLOCKS 1 #define EXT2_INODE_ROOT 2 #define EXT2_INODE_ACL_INDEX 3 #define EXT2_INODE_ACL_DATA 4 #define EXT2_INODE_BOOT_LOADER 5 #define EXT2_INODE_UNDELETE_DIR 6 #define EXT2_INODE_AVAIL 11 #define EXT2_FT_UNKNOWN 0 #define EXT2_FT_FILE 1 #define EXT2_FT_DIR 2 #define EXT2_FT_CHAR 3 #define EXT2_FT_BLOCK 4 #define EXT2_FT_FIFO 5 #define EXT2_FT_SOCK 6 #define EXT2_FT_SYMLINK 7 #define EXT2_FT_MAX 8 typedef struct { u32_t s_inodes_count; /* Inodes count */ u32_t s_blocks_count; /* Blocks count */ u32_t s_r_blocks_count; /* Reserved blocks count */ u32_t s_free_blocks_count; /* Free blocks count */ u32_t s_free_inodes_count; /* Free inodes count */ u32_t s_first_data_block; /* First Data Block */ u32_t s_log_block_size; /* Block size: 0->1024, 1->2048, 2->4096 */ int s_log_frag_size; /* Fragment size */ u32_t s_blocks_per_group; /* # Blocks per group */ u32_t s_frags_per_group; /* # Fragments per group */ u32_t s_inodes_per_group; /* # Inodes per group */ u32_t s_mtime; /* Mount time */ u32_t s_wtime; /* Write time */ u16_t s_mnt_count; /* Mount count */ short s_max_mnt_count; /* Maximal mount count */ u16_t s_magic; /* Magic signature */ u16_t s_state; /* File system state */ u16_t s_errors; /* Behaviour when detecting errors */ u16_t s_minor_rev_level; /* minor revision level */ u32_t s_lastcheck; /* time of last check */ u32_t s_checkinterval; /* max. time between checks */ u32_t s_creator_os; /* OS */ u32_t s_rev_level; /* Revision level */ u16_t s_def_resuid; /* Default uid for reserved blocks */ u16_t s_def_resgid; /* Default gid for reserved blocks */ u32_t s_reserved[235]; } ext2_super_block_t; typedef struct { u32_t bg_block_bitmap; // Blocks bitmap block u32_t bg_inode_bitmap; // Inode bitmap block u32_t bg_inode_table; // Inode table block u16_t bg_free_blocks_count; // Free blocks count u16_t bg_free_inodes_count; // Free Inodes count u16_t bg_used_dirs_count; // Directories count u16_t bg_pad1; u32_t bg_reserved[3]; } ext2_group_desc_t; typedef struct { u16_t i_mode; // File mode u16_t i_uid; // Owner UID u32_t i_size; // Size in bytes u32_t i_atime; // Access time u32_t i_ctime; // Creation time u32_t i_mtime; // Modification time u32_t i_dtime; // Deletion time u16_t i_gid; // Group ID u16_t i_links_count; // Links count u32_t i_blocks; // Blocks count u32_t i_flags; // File flags u32_t i_reserved1; u32_t i_block[15]; // Pointers to blocks (12 direct, single, double, triple indirect) u32_t i_version; // File version (for NFS) u32_t i_file_acl; // File ACL u32_t i_dir_acl; // Directory ACL u32_t i_faddr; // Fragment address u8_t i_frag; // Fragment number u8_t i_fsize; // Fragment size u16_t i_pad1; u32_t i_reserved2[2]; } ext2_inode_t; typedef struct { u32_t inode; // inode number u16_t length; // directory entry length u8_t name_length; // name length u8_t file_type; // File type char name[EXT2_NAME_LEN]; } ext2_dir_entry_t; typedef struct { ext2_inode_t inode; u32_t block; u32_t *block_pointers; u32_t block_pointers_start; } ext2_open_inode_t; typedef struct { ext2_open_inode_t *open_inode; u32_t position; } ext2_open_dir_t; typedef struct { ext2_open_inode_t *open_inode; u32_t position; u32_t buffer_start; u32_t buffer_bytes; u8_t *buffer; } ext2__open_file_t; typedef struct { ext2_open_inode_t *open_inode; u32_t block; } ext2__open_block_file_t; static inline u32_t ext2_diskToFSBlock(u32_t block, ext2_super_block_t *super) { // convert # of disk blocks to # of filesystem blocks return block >> (super->s_log_block_size + 1); } static inline u32_t ext2_FSToDiskBlock(u32_t block, ext2_super_block_t *super) { // convert # of filesystem blocks to # of disk blocks return block << (super->s_log_block_size + 1); } int ext2_init(int fsID); int ext2_read_inode(vfs_mount_t *mount, u32_t inode, ext2_inode_t *dat); int ext2_write_inode(vfs_mount_t *mount, u32_t inode, ext2_inode_t *dat); ext2_group_desc_t ext2_get_group_desc(vfs_mount_t *mount, u32_t group); void ext2_write_group_desc(vfs_mount_t *mount, u32_t group_num, ext2_group_desc_t *gd); ext2_open_inode_t *ext2_open_inode(vfs_mount_t *mount, u32_t inode_number); int ext2_close_inode(vfs_mount_t *mount, ext2_open_inode_t *open_inode); int ext2_read_inode_block(vfs_mount_t *mount, ext2_open_inode_t *open_inode, void *block); u32_t ext2_block_number(vfs_mount_t *mount, ext2_open_inode_t *open_inode); int ext2_inode_seek(vfs_mount_t *mount, ext2_open_inode_t *open_inode, u32_t block_number); int ext2_inode_status(vfs_mount_t *mount, u32_t inode_number); int ext2_block_status(vfs_mount_t *mount, u32_t block_number); u32_t ext2_alloc_inode(vfs_mount_t *mount); int ext2_free_inode(vfs_mount_t *mount, u32_t inode_number); u32_t ext2_alloc_block(vfs_mount_t *mount); int ext2_free_block(vfs_mount_t *mount, u32_t block_number); u32_t ext2_reserve_node(vfs_mount_t *mount, u32_t bitmap_block_num, u32_t bitmap_size); int ext2_free_node(vfs_mount_t *mount, u32_t bitmap_block_num, u32_t node_number); int ext2_num_block_groups(ext2_super_block_t *super); void ext2_write_super(vfs_mount_t *mount); int ext2_resize_inode(vfs_mount_t *mount, u32_t inode_number, u32_t new_size); ext2_open_dir_t *ext2_open_dir(vfs_mount_t *mount, u32_t inode_number); int ext2_dir_read_entry(vfs_mount_t *mount, ext2_open_dir_t *open_dir, ext2_dir_entry_t *dentry); int ext2_close_dir(vfs_mount_t *mount, ext2_open_dir_t *open_dir); int ext2_dir_lookup(vfs_mount_t *mount, u32_t dir_inode, char *fileName, ext2_dir_entry_t *direntry); void *ext2_mount_super(major_t major, minor_t minor); int ext2_umount_super(vfs_mount_t *mount); int ext2_stat(vfs_mount_t *mount, u32_t inode_number, vfs_stat_t *stat); u32_t ext2__get_root_dir_inode(vfs_mount_t *mount); int ext2__link_deref(vfs_mount_t *mount, u32_t link_inode, char *link); int ext2__free_inodes(vfs_mount_t *mount); int ext2__total_inodes(vfs_mount_t *mount); int ext2__free_blocks(vfs_mount_t *mount); int ext2__total_blocks(vfs_mount_t *mount); int ext2__open_dir(vfs_mount_t *mount, u32_t inode_number, vfs_open_file_t *dir); int ext2__read_dir(vfs_mount_t *mount, vfs_open_file_t *dir, vfs_dir_entry_t *dentry); int ext2__close_dir(vfs_mount_t *mount, vfs_open_file_t *dir); int ext2__open_file(vfs_mount_t *mount, u32_t inode_number, vfs_open_file_t *open_file); int ext2__read_file(vfs_mount_t *mount, vfs_open_file_t *open_file); int ext2__close_file(vfs_mount_t *mount, vfs_open_file_t *open_file); int ext2__open_block_file(vfs_mount_t *mount, u32_t inode_number, vfs_open_file_t *open_file); int ext2__read_block_file(vfs_mount_t *mount, vfs_open_file_t *open_file, void *buffer); int ext2__block_file_seek(vfs_mount_t *mount, vfs_open_file_t *open_file, u32_t block_number); int ext2__close_block_file(vfs_mount_t *mount, vfs_open_file_t *open_file); #endif