aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/fs/ext2.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/fs/ext2.h')
-rw-r--r--src/kernel/fs/ext2.h211
1 files changed, 211 insertions, 0 deletions
diff --git a/src/kernel/fs/ext2.h b/src/kernel/fs/ext2.h
new file mode 100644
index 0000000..62105c7
--- /dev/null
+++ b/src/kernel/fs/ext2.h
@@ -0,0 +1,211 @@
+#ifndef MELVIX_EXT2_H
+#define MELVIX_EXT2_H
+
+#include <stdint.h>
+#include <kernel/fs/vfs.h>
+
+#define EXT2_DIRECT_BLOCKS 12
+
+#define SUPERBLOCK_SIZE 1024
+#define ROOT_INODE_NUMBER 2
+
+#define EXT2_S_IFSOCK 0xC000
+#define EXT2_S_IFLNK 0xA000
+#define EXT2_S_IFREG 0x8000
+#define EXT2_S_IFBLK 0x6000
+#define EXT2_S_IFDIR 0x4000
+#define EXT2_S_IFCHR 0x2000
+#define EXT2_S_IFIFO 0x1000
+
+// http://wiki.osdev.org/Ext2#Locating_the_Superblock
+typedef struct superblock {
+ uint32_t total_inodes;
+ uint32_t total_blocks;
+ uint32_t su_blocks;
+ uint32_t free_blocks;
+ uint32_t free_inodes;
+ uint32_t superblock_idx;
+ uint32_t log2block_size;
+ uint32_t log2frag_size;
+ uint32_t blocks_per_group;
+ uint32_t frags_per_group;
+ uint32_t inodes_per_group;
+
+ uint32_t mtime;
+ uint32_t wtime;
+
+ uint16_t mount_count;
+ uint16_t mount_allowed_count;
+ uint16_t ext2_magic;
+ uint16_t fs_state;
+ uint16_t err;
+ uint16_t minor;
+
+ uint32_t last_check;
+ uint32_t interval;
+ uint32_t os_id;
+ uint32_t major;
+
+ uint16_t r_userid;
+ uint16_t r_groupid;
+
+ // Extensions
+ uint32_t first_inode;
+ uint16_t inode_size;
+ uint16_t superblock_group;
+ uint32_t optional_feature;
+ uint32_t required_feature;
+ uint32_t readonly_feature;
+ char fs_id[16];
+ char vol_name[16];
+ char last_mount_path[64];
+ uint32_t compression_method;
+ uint8_t file_pre_alloc_blocks;
+ uint8_t dir_pre_alloc_blocks;
+ uint16_t unused1;
+ char journal_id[16];
+ uint32_t journal_inode;
+ uint32_t journal_device;
+ uint32_t orphan_head;
+
+ char unused2[1024 - 236];
+} __attribute__((packed)) superblock_t;
+
+typedef struct bgd {
+ uint32_t block_bitmap;
+ uint32_t inode_bitmap;
+ uint32_t inode_table;
+ uint32_t free_blocks;
+ uint32_t free_inodes;
+ uint32_t num_dirs;
+ uint32_t unused1;
+ uint32_t unused2;
+} __attribute__((packed)) bgd_t;
+
+typedef struct direntry {
+ uint32_t inode;
+ uint16_t size;
+ uint8_t name_len;
+ uint8_t type;
+ char name[];
+} __attribute__((packed)) direntry_t;
+
+typedef struct inode {
+ uint16_t permission;
+ uint16_t userid;
+ uint32_t size;
+ uint32_t atime;
+ uint32_t ctime;
+ uint32_t mtime;
+ uint32_t dtime;
+ uint16_t gid;
+ uint16_t hard_links;
+ uint32_t num_sectors;
+ uint32_t flags;
+ uint32_t os_specific1;
+ uint32_t blocks[EXT2_DIRECT_BLOCKS + 3];
+ uint32_t generation;
+ uint32_t file_acl;
+ union {
+ uint32_t dir_acl;
+ uint32_t size_high;
+ };
+ uint32_t f_block_addr;
+ char os_specific2[12];
+} __attribute__((packed)) inode_t;
+
+typedef struct ext2_cache {
+ uint32_t block;
+ uint32_t times;
+ uint8_t dirty;
+ char *block_data;
+} ext2_cache_t;
+
+typedef struct ext2_fs {
+ vfs_node_t *disk_device;
+
+ superblock_t *sb;
+ bgd_t *bgds;
+ uint32_t block_size;
+ uint32_t blocks_per_group;
+ uint32_t inodes_per_group;
+ uint32_t total_groups;
+
+ uint32_t bgd_blocks;
+} ext2_fs_t;
+
+uint32_t ext2_file_size(vfs_node_t *node);
+
+void ext2_mkdir(vfs_node_t *parent, char *name, uint16_t permission);
+
+void ext2_mkfile(vfs_node_t *parent, char *name, uint16_t permission);
+
+void ext2_create_entry(vfs_node_t *parent, char *entry_name, uint32_t entry_inode);
+
+void ext2_unlink(vfs_node_t *parent, char *name);
+
+char **ext2_listdir(vfs_node_t *parent);
+
+vfs_node_t *ext2_finddir(vfs_node_t *parent, char *name);
+
+void ext2_create_entry(vfs_node_t *parent, char *entry_name, uint32_t entry_inode);
+
+void ext2_remove_entry(vfs_node_t *parent, char *entry_name);
+
+void ext2_chmod(vfs_node_t *file, uint32_t mode);
+
+uint32_t ext2_read(vfs_node_t *file, uint32_t offset, uint32_t size, char *buf);
+
+uint32_t ext2_write(vfs_node_t *file, uint32_t offset, uint32_t size, char *buf);
+
+void ext2_open(vfs_node_t *file, uint32_t flags);
+
+void ext2_close();
+
+void read_inode_metadata(ext2_fs_t *ext2fs, inode_t *inode, uint32_t inode_idx);
+
+void write_inode_metadata(ext2_fs_t *ext2fs, inode_t *inode, uint32_t inode_idx);
+
+uint32_t read_inode_filedata(ext2_fs_t *ext2fs, inode_t *inode, uint32_t offset, uint32_t size,
+ char *buf);
+
+void write_inode_filedata(ext2_fs_t *ext2fs, inode_t *inode, uint32_t inode_idx, uint32_t offset,
+ uint32_t size, char *buf);
+
+char *read_inode_block(ext2_fs_t *ext2fs, inode_t *inode, uint32_t iblock);
+
+void write_inode_block(ext2_fs_t *ext2fs, inode_t *inode, uint32_t iblock, char *buf);
+
+void read_disk_block(ext2_fs_t *ext2fs, uint32_t block, char *buf);
+
+void write_disk_block(ext2_fs_t *ext2fs, uint32_t block, char *buf);
+
+void rewrite_bgds(ext2_fs_t *ext2fs);
+
+void rewrite_superblock(ext2_fs_t *ext2fs);
+
+int alloc_inode_metadata_block(uint32_t *block_ptr, ext2_fs_t *ext2fs, inode_t *inode,
+ uint32_t inode_idx, char *buffer, unsigned int block_overwrite);
+
+uint32_t get_disk_block_number(ext2_fs_t *ext2fs, inode_t *inode, uint32_t inode_block);
+
+void set_disk_block_number(ext2_fs_t *ext2fs, inode_t *inode, uint32_t inode_idx,
+ uint32_t inode_block, uint32_t disk_block);
+
+uint32_t ext2_alloc_block(ext2_fs_t *ext2fs);
+
+void ext2_free_block(ext2_fs_t *ext2fs, uint32_t block);
+
+void alloc_inode_block(ext2_fs_t *ext2fs, inode_t *inode, uint32_t inode_idx, uint32_t block);
+
+void free_inode_block(ext2_fs_t *ext2fs, inode_t *inode, uint32_t inode_idx, uint32_t block);
+
+uint32_t alloc_inode(ext2_fs_t *ext2fs);
+
+void free_inode(ext2_fs_t *ext2fs, uint32_t inode);
+
+vfs_node_t *get_ext2_root(ext2_fs_t *ext2fs, inode_t *inode);
+
+void ext2_init(char *device_path, char *mountpoint);
+
+#endif