From 6bad3f2b96cce2490c955d7b1fcc6a7da016e4ef Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 29 Dec 2004 22:00:00 -0500 Subject: [PATCH] Import backup from 2004-12-29 --- Makefile | 2 +- kernel/fs/ext2.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++- kernel/fs/ext2.h | 18 +++++++- kernel/fs/vfs.c | 3 ++ 4 files changed, 127 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index d4679f0..91b1486 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,7 @@ install_img: initrd: dd if=/dev/zero of=$(INITRD) bs=1024 count=$(INITRD_SIZE) - mke2fs -Fv -m0 -r0 $(INITRD) + mke2fs -Fv -m0 -r0 -i1024 $(INITRD) -mkdir $(INITRD_MOUNT) mount -t ext2 -o loop $(INITRD) $(INITRD_MOUNT) mkdir $(INITRD_MOUNT)/txt diff --git a/kernel/fs/ext2.c b/kernel/fs/ext2.c index 3dbf358..a48ae55 100644 --- a/kernel/fs/ext2.c +++ b/kernel/fs/ext2.c @@ -109,9 +109,69 @@ u32_t ext2_get_inode_number(vfs_mount_t *mount, char *file) return inode_number; } +// DEBUG +void ext2_dump_root(vfs_mount_t *mount) +{ + ext2_open_dir_t *root_dir = ext2_open_dir(mount, 2); + ext2_dir_entry_t dentry; + while (!ext2_dir_read_entry(mount, root_dir, &dentry)) + { + kprintf("Directory Entry: inode %d, length %d, name_length %d, file_type 0x%x, name '%s'\n", + dentry.inode, dentry.length, dentry.name_length, dentry.file_type, dentry.name); + } + ext2_close_dir(mount, root_dir); +} + +// open a directory by inode number for reading +ext2_open_dir_t *ext2_open_dir(vfs_mount_t *mount, u32_t inode_number) +{ + ext2_open_dir_t *open_dir = New(ext2_open_dir_t); + ext2_open_inode_t *open_inode = ext2_open_inode(mount, inode_number); + if (!open_inode) + { + kfree(open_dir); + return NULL; + } + open_dir->open_inode = open_inode; + open_dir->position = 0; + return open_dir; +} + +int ext2_dir_read_entry(vfs_mount_t *mount, ext2_open_dir_t *open_dir, ext2_dir_entry_t *dentry) +{ + ext2_super_block_t *super = mount->super; + if (open_dir->position >= open_dir->open_inode->inode.i_size) + return -1; // EOF + u32_t dir_block = open_dir->position >> (10 + super->s_log_block_size); + char *block = kmalloc(2048 << super->s_log_block_size); + ext2_inode_seek(mount, open_dir->open_inode, dir_block); + if (ext2_read_inode_block(mount, open_dir->open_inode, block)) + ext2_read_inode_block(mount, open_dir->open_inode, block + (1024 << super->s_log_block_size)); + ext2_dir_entry_t *dir_entry = (ext2_dir_entry_t *)(block + open_dir->position % (1024 << super->s_log_block_size)); + if (!dir_entry->inode) + { + kfree(block); + return -2; // EOF + } + + memcpy(dentry, dir_entry, min(dir_entry->length, sizeof(ext2_dir_entry_t))); + open_dir->position += dir_entry->length; + kfree(block); + return 0; +} + +int ext2_close_dir(vfs_mount_t *mount, ext2_open_dir_t *open_dir) +{ + ext2_close_inode(mount, open_dir->open_inode); + kfree(open_dir); + return 0; +} + // open an inode for reading ext2_open_inode_t *ext2_open_inode(vfs_mount_t *mount, u32_t inode_number) { + if (ext2_inode_status(mount, inode_number) != 1) + return NULL; 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; @@ -122,9 +182,54 @@ ext2_open_inode_t *ext2_open_inode(vfs_mount_t *mount, u32_t inode_number) return open_inode; } -// seek to a certain block of an open inode -int ext2_inode_seek(ext2_open_inode_t *open_inode, u32_t block_number) +// check the status of an inode +// -1: invalid inode number +// 0: free inode +// 1: allocated inode +int ext2_inode_status(vfs_mount_t *mount, u32_t inode_number) { + ext2_super_block_t *super = mount->super; + if (inode_number < 1 || inode_number > super->s_inodes_count) // inode number invalid + return -1; + inode_number--; // turn inode_number into a 0-based index + u32_t group = inode_number / super->s_inodes_per_group; + u32_t index = inode_number % super->s_inodes_per_group; + u32_t inode_bitmap_block = ext2_get_group_desc(mount, group).bg_inode_bitmap + (index >> (13 + super->s_log_block_size)); + u32_t bitmap_index = index % (8192 << super->s_log_block_size); + u8_t *inode_bitmap = kmalloc(1024 << super->s_log_block_size); + block_read(mount->major, mount->minor, + ext2_FSToDiskBlock(inode_bitmap_block, super), 2 << super->s_log_block_size, inode_bitmap); + int inode_status = (inode_bitmap[bitmap_index >> 3] >> (bitmap_index & 0x7)) & 1; + kfree(inode_bitmap); + return inode_status; +} + +// check the status of a block +// -1: invalid block number +// 0: free block +// 1: allocated block +int ext2_block_status(vfs_mount_t *mount, u32_t block_number) +{ + ext2_super_block_t *super = mount->super; + if (block_number < super->s_first_data_block || block_number > super->s_blocks_count) // block number invalid + return -1; + block_number -= super->s_first_data_block; + u32_t group = block_number / super->s_blocks_per_group; + u32_t index = block_number % super->s_blocks_per_group; + u32_t block_bitmap_block = ext2_get_group_desc(mount, group).bg_block_bitmap + (index >> (13 + super->s_log_block_size)); + u32_t bitmap_index = index % (8192 << super->s_log_block_size); + u8_t *block_bitmap = kmalloc(1024 << super->s_log_block_size); + block_read(mount->major, mount->minor, + ext2_FSToDiskBlock(block_bitmap_block, super), 2 << super->s_log_block_size, block_bitmap); + int block_status = (block_bitmap[bitmap_index >> 3] >> (bitmap_index & 0x7)) & 1; + kfree(block_bitmap); + return block_status; +} + +// seek to a certain block of an open inode +int ext2_inode_seek(vfs_mount_t *mount, ext2_open_inode_t *open_inode, u32_t block_number) +{ + ext2_super_block_t *super = mount->super; if (open_inode->inode.i_size <= (block_number << (10 + super->s_log_block_size))) return -1; // at or past EOF open_inode->block = block_number; diff --git a/kernel/fs/ext2.h b/kernel/fs/ext2.h index ccbcf64..009248a 100644 --- a/kernel/fs/ext2.h +++ b/kernel/fs/ext2.h @@ -136,7 +136,7 @@ typedef struct u8_t name_length; // name length u8_t file_type; // File type char name[EXT2_NAME_LEN]; -} ext2_dir_entry_t; +} ext2_dir_entry_t; typedef struct { @@ -146,6 +146,12 @@ typedef struct u32_t block_pointers_start; } ext2_open_inode_t; +typedef struct +{ + ext2_open_inode_t *open_inode; + u32_t position; +} ext2_open_dir_t; + static inline u32_t ext2_diskToFSBlock(u32_t block, ext2_super_block_t *super) { @@ -172,7 +178,15 @@ 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); u32_t ext2_get_inode_number(vfs_mount_t *mount, char *file); -int ext2_inode_seek(ext2_open_inode_t *open_inode, u32_t block_number); +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); + +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); + +void ext2_dump_root(vfs_mount_t *mount); #endif diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c index e552781..629aeca 100644 --- a/kernel/fs/vfs.c +++ b/kernel/fs/vfs.c @@ -63,6 +63,9 @@ int vfs_mount(major_t maj, minor_t min, int fsType, char *mountPoint) kfree(mnt); return -4; // could not add mount } + // DEBUG + ext2_dump_root(mnt); + return 0; }