Import backup from 2004-12-30

This commit is contained in:
josh committed 2017-07-25 22:23:49 -04:00
1 parent 6bad3f2b96
commit 76a243d894
18 files changed
+408 -158

No files matched your search

+145 -94
View File
@@ -9,7 +9,7 @@
#include "ext2.h"
#include "mm/vmm.h"
#include "fs/vfs.h"
#include "lang/asmfuncs.h"
#include "lang/lang.h"
#include "functions.h"
/* Turning an inode number into a (group, inode_index) pair:
@@ -26,8 +26,10 @@ int ext2_init(int fsID)
{
fs->mount_super = ext2_mount_super;
fs->umount_super = ext2_umount_super;
fs->mkfs = ext2_mkfs;
fs->stat = ext2_stat;
fs->open_dir = ext2__open_dir;
fs->read_dir = ext2__read_dir;
fs->close_dir = ext2__close_dir;
vfs_register_fs(fsID, fs);
return 0;
}
@@ -35,13 +37,6 @@ int ext2_init(int fsID)
}
// create an ext2 filesystem on the given device
int ext2_mkfs(major_t major, minor_t minor)
{
return 0;
}
// mount the superblock of the filesystem and return a pointer to it, if valid
void *ext2_mount_super(major_t major, minor_t minor)
{
@@ -55,6 +50,14 @@ void *ext2_mount_super(major_t major, minor_t minor)
return super;
}
// called when we are unmounting this filesystem mount
int ext2_umount_super(vfs_mount_t *mount)
{
return kfree(mount->super); // free memory that the superblock was taking
}
// stat a file, return a structure of info about it
int ext2_stat(vfs_mount_t *mount, char *file, vfs_stat_t *stat)
{
@@ -65,14 +68,14 @@ int ext2_stat(vfs_mount_t *mount, char *file, vfs_stat_t *stat)
switch(inode.i_mode & EXT2_I_MODE_TYPE_MASK)
{
case EXT2_I_MODE_FIFO: stat->type = VFS_FT_FIFO;
case EXT2_I_MODE_CHAR: stat->type = VFS_FT_CHAR;
case EXT2_I_MODE_DIR: stat->type = VFS_FT_DIR;
case EXT2_I_MODE_BLOCK: stat->type = VFS_FT_BLOCK;
case EXT2_I_MODE_FILE: stat->type = VFS_FT_FILE;
case EXT2_I_MODE_SYM: stat->type = VFS_FT_SYMLINK;
case EXT2_I_MODE_SOCK: stat->type = VFS_FT_SOCK;
default: stat->type = VFS_FT_UNKNOWN;
case EXT2_I_MODE_FIFO: stat->type = VFS_FT_FIFO; break;
case EXT2_I_MODE_CHAR: stat->type = VFS_FT_CHAR; break;
case EXT2_I_MODE_DIR: stat->type = VFS_FT_DIR; break;
case EXT2_I_MODE_BLOCK: stat->type = VFS_FT_BLOCK; break;
case EXT2_I_MODE_FILE: stat->type = VFS_FT_FILE; break;
case EXT2_I_MODE_SYM: stat->type = VFS_FT_SYMLINK; break;
case EXT2_I_MODE_SOCK: stat->type = VFS_FT_SOCK; break;
default: stat->type = VFS_FT_UNKNOWN; break;
}
stat->size = inode.i_size;
stat->inode = inode_number;
@@ -92,34 +95,51 @@ u32_t ext2_get_inode_number(vfs_mount_t *mount, char *file)
{
if (file[0] != '/')
return 0;
int length = strlen(file);
if (length == 1)
return 2;
char *fil = kmalloc(length + 1);
strcpy(fil, file);
if (fil[length-1] == '/')
if (strlen(file) == 1)
return 2; // root inode number
char *fil = kmalloc(strlen(file));
strcpy(fil, file + 1);
int subs = str_split(fil, '/'); // how many levels are there to do lookups on?
u32_t on_dir = 2; // start on the root directory
char *lookupName = fil;
ext2_dir_entry_t dentry;
while (subs--)
{
length--;
fil[length] = 0;
}
u32_t inode_number = 0;
// TODO: get inode number
if (ext2_dir_lookup(mount, on_dir, lookupName, &dentry))
{
kfree(fil);
return 0; // entry not found
}
on_dir = dentry.inode;
lookupName = str_advance(lookupName);
}
kfree(fil);
return inode_number;
return on_dir;
}
// DEBUG
void ext2_dump_root(vfs_mount_t *mount)
// lookup a file name in a directory and store the directory entry for it
int ext2_dir_lookup(vfs_mount_t *mount, u32_t dir_inode, char *fileName, ext2_dir_entry_t *direntry)
{
ext2_open_dir_t *root_dir = ext2_open_dir(mount, 2);
ext2_open_dir_t *dir = ext2_open_dir(mount, dir_inode);
if (!dir)
return -1; // bad directory inode number
ext2_dir_entry_t dentry;
while (!ext2_dir_read_entry(mount, root_dir, &dentry))
while (!ext2_dir_read_entry(mount, 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);
char *dentryName = kcalloc(1, dentry.name_length + 1);
memcpy(dentryName, dentry.name, dentry.name_length);
int res = strcmp(fileName, dentryName);
kfree(dentryName);
if (!res)
{
*direntry = dentry;
ext2_close_dir(mount, dir);
return 0;
}
}
ext2_close_dir(mount, root_dir);
ext2_close_dir(mount, dir);
return -2;
}
// open a directory by inode number for reading
@@ -127,7 +147,7 @@ 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)
if (!open_inode || ((open_inode->inode.i_mode & EXT2_I_MODE_TYPE_MASK) != EXT2_I_MODE_DIR))
{
kfree(open_dir);
return NULL;
@@ -153,7 +173,6 @@ int ext2_dir_read_entry(vfs_mount_t *mount, ext2_open_dir_t *open_dir, ext2_dir_
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);
@@ -167,6 +186,7 @@ int ext2_close_dir(vfs_mount_t *mount, ext2_open_dir_t *open_dir)
return 0;
}
// open an inode for reading
ext2_open_inode_t *ext2_open_inode(vfs_mount_t *mount, u32_t inode_number)
{
@@ -182,49 +202,6 @@ ext2_open_inode_t *ext2_open_inode(vfs_mount_t *mount, u32_t inode_number)
return open_inode;
}
// 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)
@@ -250,6 +227,64 @@ int ext2_read_inode_block(vfs_mount_t *mount, ext2_open_inode_t *open_inode, voi
return min(leftover_bytes, 1024 << super->s_log_block_size);
}
// close an open inode
int ext2_close_inode(vfs_mount_t *mount, ext2_open_inode_t *open_inode)
{
mount->refs--;
if (open_inode->block_pointers)
kfree(open_inode->block_pointers); // free the block pointers cache
kfree(open_inode);
return 0;
}
// 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;
}
// transform open_inode->block (a relative block number) to an absolute block number for the filesystem
u32_t ext2_block_number(vfs_mount_t *mount, ext2_open_inode_t *open_inode)
{
@@ -300,15 +335,6 @@ u32_t ext2_block_number(vfs_mount_t *mount, ext2_open_inode_t *open_inode)
return open_inode->block_pointers[leftover_2];
}
// close an open inode
int ext2_close_inode(vfs_mount_t *mount, ext2_open_inode_t *open_inode)
{
mount->refs--;
if (open_inode->block_pointers)
kfree(open_inode->block_pointers); // free the block pointers cache
kfree(open_inode);
return 0;
}
// read the inode structure from the device and return it
ext2_inode_t ext2_get_inode(vfs_mount_t *mount, u32_t inode)
@@ -338,9 +364,34 @@ ext2_group_desc_t ext2_get_group_desc(vfs_mount_t *mount, u32_t group)
return gd;
}
// called when we are unmounting this filesystem mount
int ext2_umount_super(vfs_mount_t *mount)
int ext2__open_dir(vfs_mount_t *mount, char *file, vfs_open_dir_t *dir)
{
return kfree(mount->super); // free memory that the superblock was taking
u32_t dir_inode = ext2_get_inode_number(mount, file);
if (!dir_inode)
return -1;
ext2_open_dir_t *open_dir = ext2_open_dir(mount, dir_inode);
if (!open_dir)
return -2;
dir->fs_data = open_dir;
return 0;
}
int ext2__read_dir(vfs_mount_t *mount, vfs_open_dir_t *dir, vfs_dir_entry_t *dentry)
{
ext2_dir_entry_t t_dentry;
int status = ext2_dir_read_entry(mount, dir->fs_data, &t_dentry);
if (status)
return status;
memcpy(dentry->name, t_dentry.name, t_dentry.name_length);
dentry->name[t_dentry.name_length] = 0;
return 0;
}
int ext2__close_dir(vfs_mount_t *mount, vfs_open_dir_t *dir)
{
return ext2_close_dir(mount, dir->fs_data);
}
+15 -13
View File
@@ -13,19 +13,20 @@
#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_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
@@ -152,7 +153,6 @@ typedef struct
u32_t position;
} ext2_open_dir_t;
static inline u32_t ext2_diskToFSBlock(u32_t block, ext2_super_block_t *super)
{
// convert # of disk blocks to # of filesystem blocks
@@ -169,7 +169,6 @@ static inline u32_t ext2_FSToDiskBlock(u32_t block, ext2_super_block_t *super)
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);
int ext2_stat(vfs_mount_t *mount, char *file, vfs_stat_t *stat);
@@ -185,8 +184,11 @@ 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);
int ext2_dir_lookup(vfs_mount_t *mount, u32_t dir_inode, char *fileName, ext2_dir_entry_t *direntry);
void ext2_dump_root(vfs_mount_t *mount);
int ext2__open_dir(vfs_mount_t *mount, char *file, vfs_open_dir_t *dir);
int ext2__read_dir(vfs_mount_t *mount, vfs_open_dir_t *dir, vfs_dir_entry_t *dentry);
int ext2__close_dir(vfs_mount_t *mount, vfs_open_dir_t *dir);
#endif
+48 -4
View File
@@ -9,7 +9,7 @@
#include "fs/ext2.h"
#include "kernel.h"
#include "mm/vmm.h"
#include "lang/asmfuncs.h"
#include "lang/lang.h"
vfs_fs_t *fses[VFS_MAX_FS]; // a vfs_fs structure for every filesystem we support
vfs_node_t *vfsMountTree; // points to the root node ('/') of the VFS Mount Tree
@@ -63,8 +63,6 @@ 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;
}
@@ -243,7 +241,52 @@ int vfs_retire_node(vfs_node_t *node)
}
// debug routine to draw the VFS Mount Tree
// stat a file, fills a vfs_stat_t structure with stat information and returns standard status
int vfs_stat(char *file, vfs_stat_t *stat)
{
vfs_mount_match_t match = vfs_get_rel_path(file);
if (match.mount == NULL)
return -256;
if (fses[match.mount->fs]->stat)
return fses[match.mount->fs]->stat(match.mount, file + match.length - 1, stat);
return -257;
}
vfs_open_dir_t *vfs_open_dir(char *file)
{
vfs_mount_match_t match = vfs_get_rel_path(file);
if (match.mount == NULL)
return NULL;
vfs_open_dir_t *open_dir = New(vfs_open_dir_t);
if (fses[match.mount->fs]->open_dir && !(fses[match.mount->fs]->open_dir(match.mount, file + match.length - 1, open_dir)))
{
open_dir->mount = match.mount;
return open_dir;
}
kfree(open_dir);
return NULL;
}
int vfs_read_dir(vfs_open_dir_t *open_dir, vfs_dir_entry_t *dentry)
{
return !(fses[open_dir->mount->fs]->read_dir &&
!(fses[open_dir->mount->fs]->read_dir(open_dir->mount, open_dir, dentry)));
}
int vfs_close_dir(vfs_open_dir_t *open_dir)
{
int status = 0;
if (fses[open_dir->mount->fs]->close_dir)
status = fses[open_dir->mount->fs]->close_dir(open_dir->mount, open_dir);
kfree(open_dir);
return status;
}
// DEBUG routines to draw the VFS Mount Tree
/******************************************/
void vfs_dump_tree()
{
if (!vfsMountTree)
@@ -269,4 +312,5 @@ void vfs_dump_node(vfs_node_t *node, int level)
node = node->next;
}
}
/******************************************/
+32 -1
View File
@@ -21,6 +21,7 @@
#define VFS_FT_SOCK 6
#define VFS_FT_SYMLINK 7
#define EOF 1000000
/* Structure to hold information about a mount point */
typedef struct
@@ -68,13 +69,34 @@ typedef struct
u16_t links;
} vfs_stat_t;
typedef struct
{
vfs_mount_t *mount;
void *fs_data;
} vfs_open_dir_t;
typedef struct
{
vfs_mount_t *mount;
void *fs_data;
} vfs_open_file_t;
typedef struct
{
char name[257];
} vfs_dir_entry_t;
/* Every filesystem must provide pointers to its respective functions in a structure like this */
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);
int (*stat)(vfs_mount_t *mount, char *file, vfs_stat_t *stat);
int (*open_dir)(vfs_mount_t *mount, char *file, vfs_open_dir_t *dir);
int (*read_dir)(vfs_mount_t *mount, vfs_open_dir_t *dir, vfs_dir_entry_t *dentry);
int (*close_dir)(vfs_mount_t *mount, vfs_open_dir_t *dir);
} vfs_fs_t;
@@ -86,6 +108,15 @@ vfs_mount_t *vfs_find_mount(char *mountPoint);
vfs_mount_match_t vfs_get_rel_path(char *path);
int vfs_umount(char *mountPoint);
int vfs_retire_node(vfs_node_t *node);
int vfs_stat(char *file, vfs_stat_t *stat);
vfs_open_dir_t *vfs_open_dir(char *file);
int vfs_read_dir(vfs_open_dir_t *open_dir, vfs_dir_entry_t *dentry);
int vfs_close_dir(vfs_open_dir_t *open_dir);
// DEBUG routines
void vfs_dump_tree();
void vfs_dump_node(vfs_node_t *node, int level);