Import backup from 2004-12-21
This commit is contained in:
parent
2445034e43
commit
7b805f2495
2
Makefile
2
Makefile
@ -59,7 +59,7 @@ install_img:
|
||||
|
||||
initrd:
|
||||
dd if=/dev/zero of=$(INITRD) bs=1024 count=$(INITRD_SIZE)
|
||||
mke2fs -Fv -m0 $(INITRD)
|
||||
mke2fs -Fv -m0 -r0 $(INITRD)
|
||||
-mkdir $(INITRD_MOUNT)
|
||||
# mount -t ext2 -o loop $(INITRD) $(INITRD_MOUNT)
|
||||
# mkdir $(INITRD_MOUNT)/bin
|
||||
|
@ -10,6 +10,11 @@
|
||||
#include "mm/vmm.h"
|
||||
#include "fs/vfs.h"
|
||||
|
||||
/* Turning an inode number into a (group, inode_index) pair:
|
||||
* group = (inode - 1) / s_inodes_per_group
|
||||
* index = (inode - 1) % s_inodes_per_group
|
||||
*/
|
||||
|
||||
|
||||
int ext2_init(int fsID)
|
||||
{
|
||||
@ -36,11 +41,12 @@ void *ext2_mount_super(major_t major, minor_t minor)
|
||||
{
|
||||
ext2_super_block_t *super = kmalloc(1024);
|
||||
block_read(major, minor, 2, 2, super);
|
||||
if (super->s_magic != EXT2_MAGIC)
|
||||
if (super->s_magic != EXT2_MAGIC) // not an ext2 filesystem
|
||||
{
|
||||
kfree(super);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return super;
|
||||
}
|
||||
|
||||
|
177
kernel/fs/ext2.h
177
kernel/fs/ext2.h
@ -10,72 +10,131 @@
|
||||
#include "fs/devices.h"
|
||||
|
||||
#define EXT2_MAGIC 0xEF53
|
||||
#define EXT2_NAME_LEN 255
|
||||
|
||||
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 */
|
||||
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 */
|
||||
#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
|
||||
|
||||
/*
|
||||
* EXT2_DYNAMIC_REV fields...
|
||||
*/
|
||||
u32_t s_first_ino; /* First non-reserved inode */
|
||||
u16_t s_inode_size; /* size of inode structure */
|
||||
u16_t s_block_group_nr; /* block group # of this superblock */
|
||||
u32_t s_feature_compat; /* compatible feature set */
|
||||
u32_t s_feature_incompat; /* incompatible feature set */
|
||||
u32_t s_feature_ro_compat; /* readonly-compatible feature set */
|
||||
u8_t s_uuid[16]; /* 128-bit uuid for volume */
|
||||
char s_volume_name[16]; /* volume name */
|
||||
char s_last_mounted[64]; /* directory where last mounted */
|
||||
u32_t s_algorithm_usage_bitmap; /* For compression */
|
||||
#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
|
||||
|
||||
/*
|
||||
* Performance hints...
|
||||
*/
|
||||
u8_t s_prealloc_blocks; /* Nr of blocks to try to preallocate */
|
||||
u8_t s_prealloc_dir_blocks; /* Nr to preallocate for dirs */
|
||||
u16_t s_padding1;
|
||||
#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
|
||||
|
||||
/*
|
||||
* Journaling information...
|
||||
*/
|
||||
u8_t s_journal_uuid[16]; /* uuid of journal superblock */
|
||||
u32_t s_journal_inum; /* inode number of journal file */
|
||||
u32_t s_journal_dev; /* device number of journal file */
|
||||
u32_t s_last_orphan; /* start of list of inodes to delete */
|
||||
u32_t s_hash_seed[4]; /* HTREE hash seed */
|
||||
u8_t s_def_hash_version; /* Default hash version to use */
|
||||
u8_t s_reserved_char_pad;
|
||||
u16_t s_reserved_word_pad;
|
||||
u32_t s_default_mount_opts;
|
||||
u32_t s_first_meta_bg; /* First metablock block group */
|
||||
u32_t s_reserved[190]; /* Padding to the end of the block */
|
||||
#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, 4->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 file blocks
|
||||
u32_t i_version; // File version (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;
|
||||
|
||||
int ext2_init(int fsID);
|
||||
void *ext2_mount_super(major_t major, minor_t minor);
|
||||
|
101
kernel/fs/vfs.c
101
kernel/fs/vfs.c
@ -1,7 +1,7 @@
|
||||
// vfs.c
|
||||
// Author: Josh Holtrop
|
||||
// Date: 08/22/04
|
||||
// Modified: 12/20/04
|
||||
// Modified: 12/21/04
|
||||
|
||||
#include "hos_defines.h"
|
||||
#include "kout.h"
|
||||
@ -9,16 +9,19 @@
|
||||
#include "fs/ext2.h"
|
||||
#include "kernel.h"
|
||||
#include "mm/vmm.h"
|
||||
#include "lang/asmfuncs.h"
|
||||
|
||||
vfs_fs_t *fses[VFS_MAX_FS];
|
||||
vfs_node_t *vfsMountTree;
|
||||
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
|
||||
|
||||
// basic initialization routine, init all filesystem drivers
|
||||
int vfs_init()
|
||||
{
|
||||
k_check(ext2_init(FS_EXT2), "ext2_init() failed!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// called by a filesystem driver to let us know that it is ready to handle fs requests
|
||||
int vfs_register_fs(int fsn, vfs_fs_t *fs)
|
||||
{
|
||||
if (fsn < 0 || fsn >= VFS_MAX_FS || fses[fsn])
|
||||
@ -30,16 +33,20 @@ int vfs_register_fs(int fsn, vfs_fs_t *fs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// called to mount a block device with a certain filesystem to a part of our VFS Mount Tree
|
||||
int vfs_mount(major_t maj, minor_t min, int fsType, char *mountPoint)
|
||||
{
|
||||
if (mountPoint[0] != '/')
|
||||
return -1; // mount point must be absolute
|
||||
int l = strlen(mountPoint);
|
||||
if (l < 1)
|
||||
return -7; // mount point must be non-null string
|
||||
if (mountPoint[l-1] != '/')
|
||||
return -8; // mount point must end with a '/' character
|
||||
if (fsType < 0 || fsType >= VFS_MAX_FS || !fses[fsType])
|
||||
return -2; // invalid filesystem type
|
||||
if (vfs_find_mount(mountPoint))
|
||||
{
|
||||
return -5; // mount point already mounted
|
||||
}
|
||||
void *super = fses[fsType]->mount_super(maj, min);
|
||||
if (!super)
|
||||
return -6; // filesystem superblock not correctly identified
|
||||
@ -58,6 +65,7 @@ int vfs_mount(major_t maj, minor_t min, int fsType, char *mountPoint)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// invoked by vfs_mount to do the "dirty work" of adding the nodes to the tree
|
||||
int vfs_add_mount(vfs_mount_t *mnt, char *mountPoint)
|
||||
{
|
||||
vfs_node_t *node = vfsMountTree;
|
||||
@ -114,9 +122,10 @@ int vfs_add_mount(vfs_mount_t *mnt, char *mountPoint)
|
||||
}
|
||||
}
|
||||
|
||||
// lookup a path and return the match structure for the deepest path matched
|
||||
vfs_mount_match_t vfs_get_rel_path(char *path)
|
||||
{
|
||||
vfs_mount_match_t matched;
|
||||
vfs_mount_match_t matched = {NULL, 0};
|
||||
char *pp = path;
|
||||
int length = 0;
|
||||
vfs_node_t *node = vfsMountTree;
|
||||
@ -126,14 +135,13 @@ vfs_mount_match_t vfs_get_rel_path(char *path)
|
||||
break;
|
||||
if (node->chr == *pp) // got a character match
|
||||
{
|
||||
length++;
|
||||
if (node->mount) // and there is something mounted here
|
||||
{
|
||||
matched.major = node->mount->major;
|
||||
matched.minor = node->mount->minor;
|
||||
matched.mount = node->mount;
|
||||
matched.length = length;
|
||||
}
|
||||
pp++;
|
||||
length++;
|
||||
node = node->down;
|
||||
}
|
||||
else
|
||||
@ -142,6 +150,8 @@ vfs_mount_match_t vfs_get_rel_path(char *path)
|
||||
return matched;
|
||||
}
|
||||
|
||||
// is mountPoint a valid mount point?
|
||||
// returns a pointer to the mount structure if so
|
||||
vfs_mount_t *vfs_find_mount(char *mountPoint)
|
||||
{
|
||||
char *mp = mountPoint;
|
||||
@ -161,9 +171,76 @@ vfs_mount_t *vfs_find_mount(char *mountPoint)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*void vfs_dump_tree()
|
||||
// unmount the mountPoint, remove nodes from tree that aren't used anymore
|
||||
int vfs_umount(char *mountPoint)
|
||||
{
|
||||
vfs_dump_node(vfsMountTree, 0);
|
||||
char *mp = mountPoint;
|
||||
vfs_node_t *node = vfsMountTree;
|
||||
while (node)
|
||||
{
|
||||
if (node->chr == *mp)
|
||||
{
|
||||
mp++;
|
||||
if (*mp == 0) // we matched the whole mount point string
|
||||
{
|
||||
// is there something mounted underneath this directory?
|
||||
if (node->down)
|
||||
return -3; // yes, don't umount
|
||||
kfree(node->mount);
|
||||
node->mount = NULL;
|
||||
return vfs_retire_node(node);
|
||||
}
|
||||
node = node->down;
|
||||
}
|
||||
else
|
||||
node = node->next;
|
||||
}
|
||||
return -2; // mount point does not exist
|
||||
}
|
||||
|
||||
// remove this node from the tree if it is not needed anymore
|
||||
int vfs_retire_node(vfs_node_t *node)
|
||||
{
|
||||
if (node->down)
|
||||
return 0; // node is part of another mount point, don't remove
|
||||
if (node->mount)
|
||||
return 0; // something is still mounted here
|
||||
if (!node->up)
|
||||
{
|
||||
kfree(node);
|
||||
vfsMountTree = NULL;
|
||||
return 0; // we unmounted the root directory
|
||||
}
|
||||
// 3 cases left: node is first child (or only child), middle child, or last child
|
||||
if (node->up->down == node) // first child
|
||||
{
|
||||
node->up->down = node->next; // re-point parent to next child
|
||||
int r = vfs_retire_node(node->up); // retire parent if we were an only-child
|
||||
kfree(node);
|
||||
return r;
|
||||
}
|
||||
vfs_node_t *onode = node->up->down; // onode points to first child
|
||||
while (onode)
|
||||
{
|
||||
if (onode->next == node) // onode is child before node
|
||||
{
|
||||
onode->next = node->next;
|
||||
kfree(node);
|
||||
return 0;
|
||||
}
|
||||
onode = onode->next;
|
||||
}
|
||||
return -1; // node wasn't found following onode
|
||||
}
|
||||
|
||||
|
||||
// debug routine to draw the VFS Mount Tree
|
||||
void vfs_dump_tree()
|
||||
{
|
||||
if (!vfsMountTree)
|
||||
kprintf("vfsMountTree == NULL!\n");
|
||||
else
|
||||
vfs_dump_node(vfsMountTree, 0);
|
||||
}
|
||||
|
||||
void vfs_dump_node(vfs_node_t *node, int level)
|
||||
@ -182,5 +259,5 @@ void vfs_dump_node(vfs_node_t *node, int level)
|
||||
vfs_dump_node(node, level + 1);
|
||||
node = node->next;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// vfs.h
|
||||
// Author: Josh Holtrop
|
||||
// Date: 08/22/04
|
||||
// Modified: 12/20/04
|
||||
// Modified: 12/21/04
|
||||
|
||||
#ifndef __HOS_VFS_H__
|
||||
#define __HOS_VFS_H__ __HOS_VFS_H__
|
||||
@ -13,6 +13,7 @@
|
||||
#define VFS_MAX_FS 10
|
||||
|
||||
|
||||
/* Structure to hold information about a mount point */
|
||||
typedef struct
|
||||
{
|
||||
int refs;
|
||||
@ -21,27 +22,32 @@ typedef struct
|
||||
minor_t minor;
|
||||
} vfs_mount_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 (*mkfs)(major_t major, minor_t minor);
|
||||
} vfs_fs_t;
|
||||
|
||||
/* This structure represents a node of the "VFS Mount Tree" */
|
||||
struct vfs_node_s
|
||||
{
|
||||
char chr;
|
||||
vfs_mount_t *mount;
|
||||
struct vfs_node_s *up;
|
||||
struct vfs_node_s *next;
|
||||
struct vfs_node_s *down;
|
||||
char chr; // the character we are at
|
||||
vfs_mount_t *mount; // is there a mount at this character?
|
||||
struct vfs_node_s *up; // the parent
|
||||
struct vfs_node_s *next; // the next sibling
|
||||
struct vfs_node_s *down; // subtree for submounts
|
||||
};
|
||||
|
||||
typedef struct vfs_node_s vfs_node_t;
|
||||
|
||||
/* This structure is generated when a path is matched. For example, if /dev is mounted on
|
||||
device (4,2) and '/dev/yoda' is looked up, the structure returned would be
|
||||
{4, 2, 4} and then the lookup could continue on device (4,2) with 4 characters stripped
|
||||
off the front of the initial path (ex '/yoda') */
|
||||
typedef struct
|
||||
{
|
||||
major_t major;
|
||||
minor_t minor;
|
||||
vfs_mount_t *mount;
|
||||
int length;
|
||||
} vfs_mount_match_t;
|
||||
|
||||
@ -52,8 +58,10 @@ int vfs_register_fs(int fsn, vfs_fs_t *fs);
|
||||
int vfs_add_mount(vfs_mount_t *mnt, char *mountPoint);
|
||||
vfs_mount_t *vfs_find_mount(char *mountPoint);
|
||||
vfs_mount_match_t vfs_get_rel_path(char *path);
|
||||
/*void vfs_dump_tree();
|
||||
void vfs_dump_node(vfs_node_t *node, int level);*/
|
||||
int vfs_umount(char *mountPoint);
|
||||
int vfs_retire_node(vfs_node_t *node);
|
||||
void vfs_dump_tree();
|
||||
void vfs_dump_node(vfs_node_t *node, int level);
|
||||
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user