From 55b7429d4ede4026b2813cc2cf1de50878f54b0d Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 22 Dec 2004 22:00:00 -0500 Subject: [PATCH] Import backup from 2004-12-22 --- Makefile | 7 ++-- kernel/fs/ext2.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++- kernel/fs/ext2.h | 21 ++++++++++- kernel/fs/vfs.c | 6 +++ kernel/fs/vfs.h | 25 ++++++++++++ 5 files changed, 152 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 585cfac..d4679f0 100644 --- a/Makefile +++ b/Makefile @@ -61,8 +61,9 @@ initrd: dd if=/dev/zero of=$(INITRD) bs=1024 count=$(INITRD_SIZE) mke2fs -Fv -m0 -r0 $(INITRD) -mkdir $(INITRD_MOUNT) -# mount -t ext2 -o loop $(INITRD) $(INITRD_MOUNT) -# mkdir $(INITRD_MOUNT)/bin -# umount $(INITRD_MOUNT) + mount -t ext2 -o loop $(INITRD) $(INITRD_MOUNT) + mkdir $(INITRD_MOUNT)/txt + cp Makefile $(INITRD_MOUNT)/txt + umount $(INITRD_MOUNT) rm -rf $(INITRD_MOUNT) diff --git a/kernel/fs/ext2.c b/kernel/fs/ext2.c index 6a99d20..66af65e 100644 --- a/kernel/fs/ext2.c +++ b/kernel/fs/ext2.c @@ -9,6 +9,7 @@ #include "ext2.h" #include "mm/vmm.h" #include "fs/vfs.h" +#include "lang/asmfuncs.h" /* Turning an inode number into a (group, inode_index) pair: * group = (inode - 1) / s_inodes_per_group @@ -22,6 +23,7 @@ int ext2_init(int fsID) if (( fs = New(vfs_fs_t) )) { fs->mount_super = ext2_mount_super; + fs->umount_super = ext2_umount_super; fs->mkfs = ext2_mkfs; vfs_register_fs(fsID, fs); return 0; @@ -46,7 +48,101 @@ void *ext2_mount_super(major_t major, minor_t minor) kfree(super); return NULL; } - return super; } +void ext2_dump_root(vfs_mount_t *mount) +{ + ext2_inode_t inode_root = ext2_get_inode(mount, 2); + kprintf("root dir i_mode: 0x%x, i_size: %d, i_links_count: %d, i_blocks: %d, i_uid: %d, i_gid: %d, i_flags: 0x%x\n", inode_root.i_mode, inode_root.i_size, inode_root.i_links_count, inode_root.i_blocks, inode_root.i_uid, inode_root.i_gid, inode_root.i_flags); + ext2_super_block_t *super = mount->super; + kprintf("s_def_resuid: %d, s_def_resgid: %d\n", super->s_def_resuid, super->s_def_resgid); +} + +int ext2_stat(vfs_mount_t *mount, char *file, vfs_stat_t *stat) +{ + if (file[0] != '/') + return -1; + char *fil = kmalloc(strlen(file) + 1); + strcpy(fil, file); + // TODO: stat the file :) + kfree(fil); + return 0; +} + +ext2_open_inode_t *ext2_open_inode(vfs_mount_t *mount, u32_t inode_number) +{ + ext2_inode_t inode = ext2_get_inode(mount, inode_number); + ext2_open_inode_t *open_inode = New(ext2_open_inode_t); + open_inode->inode = inode; + open_inode->block = 0; + open_inode->block_pointers = NULL; + open_inode->block_pointers_start = 0; + return open_inode; +} + +int ext2_read_inode_block(vfs_mount_t *mount, ext2_open_inode_t *open_inode, void *block) +{ + ext2_super_block_t *super = mount->super; + // TODO: get the block number, read it to block +} + +// block_index is a relative block number - the block number of the file +// this needs to be transformed into an absolute block number for the entire disk +u32_t ext2_block_number(vfs_mount_t *mount, ext2_open_inode_t *open_inode, u32_t block_index) +{ + // TODO: convert block_index to block number using open_inode fields + return 0; +} + +int ext2_close_inode(vfs_mount_t *mount, ext2_open_inode_t *open_inode) +{ + if (open_inode->block_pointers) + kfree(open_inode->block_pointers); + kfree(open_inode); + return 0; +} + +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); +} + +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); +} + +ext2_inode_t ext2_get_inode(vfs_mount_t *mount, u32_t inode) +{ + ext2_super_block_t *super = mount->super; + inode--; // turn inode into a 0-based index + u32_t group = inode / super->s_inodes_per_group; + u32_t index = inode % super->s_inodes_per_group; + u32_t inodeAddr = (ext2_get_group_desc(mount, group).bg_inode_table << + (10 + super->s_log_block_size)) + (index << 7); + void *block = kmalloc(512); + block_read(mount->major, mount->minor, inodeAddr >> 9, 1, block); + ext2_inode_t in = *(ext2_inode_t *)(block + (inodeAddr & 0x1FF)); + kfree(block); + return in; +} + +ext2_group_desc_t ext2_get_group_desc(vfs_mount_t *mount, u32_t group) +{ + ext2_super_block_t *super = mount->super; + u32_t groupDescAddr = ((1 + super->s_first_data_block) << (10 + super->s_log_block_size)) + (group << 5); + void *block = kmalloc(512); + block_read(mount->major, mount->minor, groupDescAddr >> 9, 1, block); + ext2_group_desc_t gd = *(ext2_group_desc_t *)(block + (groupDescAddr & 0x1FF)); + kfree(block); + return gd; +} + +int ext2_umount_super(vfs_mount_t *mount) +{ + return kfree(mount->super); +} + diff --git a/kernel/fs/ext2.h b/kernel/fs/ext2.h index b71eedd..50a11e7 100644 --- a/kernel/fs/ext2.h +++ b/kernel/fs/ext2.h @@ -8,6 +8,7 @@ #include "hos_defines.h" #include "fs/devices.h" +#include "fs/vfs.h" #define EXT2_MAGIC 0xEF53 #define EXT2_NAME_LEN 255 @@ -67,7 +68,7 @@ typedef struct 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, 4->4096 */ + 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 */ @@ -136,10 +137,28 @@ typedef struct 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; + int ext2_init(int fsID); void *ext2_mount_super(major_t major, minor_t minor); +int ext2_umount_super(vfs_mount_t *mount); int ext2_mkfs(major_t major, minor_t minor); +ext2_inode_t ext2_get_inode(vfs_mount_t *mount, u32_t inode); +ext2_group_desc_t ext2_get_group_desc(vfs_mount_t *mount, u32_t group); +inline u32_t ext2_diskToFSBlock(u32_t block, ext2_super_block_t *super); +inline u32_t ext2_FSToDiskBlock(u32_t block, ext2_super_block_t *super); +int ext2_stat(vfs_mount_t *mount, char *file, vfs_stat_t *stat); +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_index); +void ext2_dump_root(vfs_mount_t *mount); #endif diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c index ca52d0b..e552781 100644 --- a/kernel/fs/vfs.c +++ b/kernel/fs/vfs.c @@ -54,6 +54,7 @@ int vfs_mount(major_t maj, minor_t min, int fsType, char *mountPoint) if (!mnt) return -3; // could not allocate memory mnt->refs = 0; + mnt->fs = fsType; mnt->major = maj; mnt->minor = min; mnt->super = super; @@ -186,6 +187,11 @@ int vfs_umount(char *mountPoint) // is there something mounted underneath this directory? if (node->down) return -3; // yes, don't umount + if (!node->mount) + return -4; // no mount here + if (node->mount->refs) + return -5; // still refs open to mount + fses[node->mount->fs]->umount_super(node->mount); kfree(node->mount); node->mount = NULL; return vfs_retire_node(node); diff --git a/kernel/fs/vfs.h b/kernel/fs/vfs.h index 327bce3..620efa4 100644 --- a/kernel/fs/vfs.h +++ b/kernel/fs/vfs.h @@ -12,12 +12,22 @@ #define FS_EXT2 1 #define VFS_MAX_FS 10 +#define VFS_FT_UNKNOWN 0 +#define VFS_FT_FILE 1 +#define VFS_FT_DIR 2 +#define VFS_FT_CHAR 3 +#define VFS_FT_BLOCK 4 +#define VFS_FT_FIFO 5 +#define VFS_FT_SOCK 6 +#define VFS_FT_SYMLINK 7 + /* Structure to hold information about a mount point */ typedef struct { int refs; void *super; + int fs; major_t major; minor_t minor; } vfs_mount_t; @@ -26,6 +36,7 @@ typedef struct typedef struct { void *(*mount_super)(major_t major, minor_t minor); + int (*umount_super)(vfs_mount_t *mount); int (*mkfs)(major_t major, minor_t minor); } vfs_fs_t; @@ -51,6 +62,20 @@ typedef struct int length; } vfs_mount_match_t; +typedef struct +{ + u16_t type; // file type, of VFS_FILE_TYPE_* + u32_t size; + u32_t inode; + u16_t permissions; + u16_t uid; + u16_t gid; + u32_t atime; + u32_t mtime; + u32_t ctime; + u16_t links; +} vfs_stat_t; + int vfs_init(); int vfs_mount(major_t maj, minor_t min, int fsType, char *mountPoint);