Import backup from 2005-01-31

This commit is contained in:
Josh Holtrop 2005-01-31 22:00:00 -05:00
parent 3381041a8f
commit 4638656aaf
9 changed files with 226 additions and 74 deletions

View File

@ -68,6 +68,8 @@ initrd:
mknod $(INITRD_MOUNT)/rd0 b 5 2
mkdir $(INITRD_MOUNT)/txt
cp Makefile $(INITRD_MOUNT)/txt
ln -s txt/../txt/../txt/../txt/../txt/../txt/../txt/../txt/../txt/.. $(INITRD_MOUNT)/link
ln -s /txt/. $(INITRD_MOUNT)/yoda
umount $(INITRD_MOUNT)
rm -rf $(INITRD_MOUNT)

View File

@ -18,7 +18,7 @@
*/
vfs_fs_t ext2_driver = {ext2_mount_super, ext2_umount_super, ext2_stat,
ext2__get_root_dir_inode,
ext2__get_root_dir_inode, ext2__link_deref,
ext2__open_dir, ext2__read_dir, ext2__close_dir,
ext2__open_file, ext2__read_file, ext2__close_file,
ext2__open_block_file, ext2__read_block_file, ext2__block_file_seek, ext2__close_block_file};
@ -370,6 +370,47 @@ u32_t ext2__get_root_dir_inode(vfs_mount_t *mount)
}
// VFS interface function to dereference a symbolic link
int ext2__link_deref(vfs_mount_t *mount, u32_t link_inode, char *link)
{
ext2_inode_t inode;
if (ext2_read_inode(mount, link_inode, &inode))
return -1;
if ( (inode.i_mode & EXT2_I_MODE_TYPE_MASK) != EXT2_I_MODE_SYM )
return -2;
if (!inode.i_size)
return -4;
if (inode.i_size < 61)
{
memcpy(link, inode.i_block, inode.i_size);
link[inode.i_size] = 0;
return 0;
}
else
{
ext2_open_inode_t *open_inode;
if (!(open_inode = ext2_open_inode(mount, link_inode)))
return -3;
ext2_super_block_t *super = mount->super;
void *buffer = kmalloc(1024 << super->s_log_block_size);
memset(link, 0, 4096);
int copied = 0;
while (copied < 4096)
{
int bytes_read = ext2_read_inode_block(mount, open_inode, buffer);
if (bytes_read == 0)
break;
memcpy(link + copied, buffer, bytes_read);
copied += bytes_read;
}
ext2_close_inode(mount, open_inode);
kfree(buffer);
return 0;
}
}
// VFS interface function to open a directory
int ext2__open_dir(vfs_mount_t *mount, u32_t inode_number, vfs_open_file_t *dir)
{
@ -485,4 +526,3 @@ int ext2__close_block_file(vfs_mount_t *mount, vfs_open_file_t *open_file)

View File

@ -204,6 +204,7 @@ void *ext2_mount_super(major_t major, minor_t minor);
int ext2_umount_super(vfs_mount_t *mount);
int ext2_stat(vfs_mount_t *mount, u32_t inode_number, vfs_stat_t *stat);
u32_t ext2__get_root_dir_inode(vfs_mount_t *mount);
int ext2__link_deref(vfs_mount_t *mount, u32_t link_inode, char *link);
int ext2__open_dir(vfs_mount_t *mount, u32_t inode_number, vfs_open_file_t *dir);
int ext2__read_dir(vfs_mount_t *mount, vfs_open_file_t *dir, vfs_dir_entry_t *dentry);

View File

@ -53,26 +53,66 @@ int vfs_mount(major_t maj, minor_t min, int fsType, char *mountPoint)
mnt->super = super;
mnt->next = NULL;
mnt->prev = NULL;
node->vfs_mount_inode = 0; // root not mounted on another fs
node->vfs_up_inode = 0;
mnt->mountPoint = kmalloc(2);
strcpy(mnt->mountPoint, mountPoint);
mnt->vfs_mount_inode = 0; // root not mounted on another fs
mnt->vfs_root_inode = ((vfs_inode_t)maj << 40) | ((vfs_inode_t)min << 32) | fses[fsType]->get_root_inode(mnt);
mnt->vfs_up_inode = mnt->vfs_root_inode;
mounts = mnt;
return 0; // successfully mounted root
}
if (mountPoint[0] != '/')
return -3; // mount point must be absolute
if (!mounts)
return -4;
int l = strlen(mountPoint);
if (l < 2)
return -4; // mount point is too short
return -5;
return -5; // mount point is too short
return -6;
}
vfs_inode_t vfs_get_inode_number(char *path)
{
if (path[0] != '/')
return 0;
vfs_inode_t vfs_inode = 0;
if (!mounts)
return 0;
return vfs_get_inode_number_rel(mounts->vfs_root_inode, path + 1);
}
vfs_inode_t vfs_get_inode_number_rel(vfs_inode_t dir_inode, char *path)
{
char *path_copy = kmalloc(strlen(path) + 1);
strcpy(path_copy, path);
int stanzas = str_split(path_copy, '/');
char *lookup = path_copy;
vfs_inode_t vfs_inode = dir_inode;
for (; stanzas > 0; stanzas--)
{
vfs_inode_t vfs_inode_this_dir = vfs_inode;
vfs_inode = vfs_entry_lookup(vfs_inode, lookup);
vfs_stat_t stat;
if (vfs_stat_inode(vfs_inode, &stat))
return 0x8000000000000002ULL;
if (stat.type == VFS_FT_SYMLINK)
{
char *link = kmalloc(4096);
vfs_link_deref(vfs_inode, link);
if (link[0] == '/')
vfs_inode = vfs_get_inode_number(link);
else
vfs_inode = vfs_get_inode_number_rel(vfs_inode_this_dir, link);
kfree(link);
}
if (!vfs_inode || (vfs_inode & 0x8000000000000000ULL))
{
kfree(path_copy);
return 0;
}
lookup = str_advance(lookup);
}
kfree(path_copy);
return vfs_inode;
}
// look for entry in dir_inode, return the vfs_inode for the entry
@ -82,38 +122,97 @@ vfs_inode_t vfs_entry_lookup(vfs_inode_t dir_inode, char *entry)
if (!open_dir)
return 0x8000000000000001ULL;
vfs_dir_entry_t dentry;
vfs_inode_t vfs_inode = 0;
while (!vfs_read_dir(open_dir, &dentry))
{
if (!strcmp(dentry.name, entry))
{
vfs_inode = (dir_inode & 0xFFFFFFFF00000000ULL) | dentry.inode_number;
break;
vfs_close_dir(open_dir);
return vfs_real_inode((dir_inode & 0xFFFFFFFF00000000ULL) | dentry.inode_number);
}
}
vfs_close_dir(open_dir);
return 0x8000000000000002ULL;
}
// return the "real" vfs inode number (inode of the root of
// a mounted filesystem instead of the inode of the folder
// that the filesystem is mounted to)
vfs_inode_t vfs_real_inode(vfs_inode_t vfs_inode)
{
vfs_mount_t *mnt = mounts;
while (mnt)
{
if (mnt->vfs_mount_inode == vfs_inode)
return mnt->vfs_root_inode;
mnt = mnt->next;
}
return vfs_inode;
}
// translage a vfs inode number into a mount pointer and relative
// inode for a mounted filesystem
vfs_file_addr_t vfs_get_file_addr(vfs_inode_t vfs_inode)
{
vfs_inode = vfs_real_inode(vfs_inode);
vfs_file_addr_t addr = {mounts, vfs_inode & 0xFFFFFFFF};
vfs_mount_t *mnt = mounts;
while (mnt)
{
if ( (mnt->vfs_root_inode & 0xFFFFFFFF00000000ULL) == (vfs_inode & 0xFFFFFFFF00000000ULL) )
{
addr.mount = mnt;
return addr;
}
mnt = mnt->next;
}
return addr;
}
int vfs_link_deref(vfs_inode_t vfs_inode, char *link)
{
vfs_stat_t stat;
if (vfs_stat_inode(vfs_inode, &stat))
return -1;
if (stat.type != VFS_FT_SYMLINK)
return -2;
vfs_file_addr_t addr = vfs_get_file_addr(vfs_inode);
if (fses[addr.mount->fs]->link_deref)
return fses[addr.mount->fs]->link_deref(addr.mount, addr.inode, link);
return -3;
}
// 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)
vfs_inode_t vfs_inode = vfs_get_inode_number(file);
if (!vfs_inode || (vfs_inode & 0x8000000000000000ULL))
return -256;
if (fses[match.mount->fs]->stat)
return fses[match.mount->fs]->stat(match.mount, file + match.length - 1, stat);
return vfs_stat_inode(vfs_inode, stat);
}
int vfs_stat_inode(vfs_inode_t vfs_inode, vfs_stat_t *stat)
{
vfs_file_addr_t addr = vfs_get_file_addr(vfs_inode);
if (fses[addr.mount->fs]->stat)
return fses[addr.mount->fs]->stat(addr.mount, addr.inode, stat);
return -257;
}
vfs_open_file_t *vfs_open_dir(vfs_inode_t inode)
vfs_open_file_t *vfs_open_dir(char *path)
{
vfs_inode_t vfs_inode = vfs_get_inode_number(path);
if (!vfs_inode || (vfs_inode & 0x8000000000000000ULL))
return NULL;
return vfs_open_dir_inode(vfs_inode);
}
vfs_open_file_t *vfs_open_dir_inode(vfs_inode_t vfs_inode)
{
vfs_file_addr_t addr = vfs_get_file_addr(vfs_inode);
vfs_open_file_t *open_dir = New(vfs_open_file_t);
if (fses[match.mount->fs]->open_dir && !(fses[match.mount->fs]->open_dir(match.mount, file + match.length - 1, open_dir)))
if (fses[addr.mount->fs]->open_dir && !(fses[addr.mount->fs]->open_dir(addr.mount, addr.inode, open_dir)))
{
open_dir->mount = match.mount;
open_dir->mount = addr.mount;
return open_dir;
}
kfree(open_dir);
@ -135,16 +234,21 @@ int vfs_close_dir(vfs_open_file_t *open_dir)
return status;
}
vfs_open_file_t *vfs_open_block_file(char *file)
vfs_open_file_t *vfs_open_block_file(char *path)
{
vfs_mount_match_t match = vfs_get_rel_path(file);
if (match.mount == NULL)
vfs_inode_t vfs_inode = vfs_get_inode_number(path);
if (!vfs_inode || (vfs_inode & 0x8000000000000000ULL))
return NULL;
return vfs_open_block_file_inode(vfs_inode);
}
vfs_open_file_t *vfs_open_block_file_inode(vfs_inode_t vfs_inode)
{
vfs_file_addr_t addr = vfs_get_file_addr(vfs_inode);
vfs_open_file_t *open_file = New(vfs_open_file_t);
if (fses[match.mount->fs]->open_block_file && !(fses[match.mount->fs]->open_block_file(match.mount, file + match.length - 1, open_file)))
if (fses[addr.mount->fs]->open_block_file && !(fses[addr.mount->fs]->open_block_file(addr.mount, addr.inode, open_file)))
{
open_file->mount = match.mount;
open_file->mount = addr.mount;
return open_file;
}
kfree(open_file);
@ -174,33 +278,3 @@ int vfs_close_block_file(vfs_open_file_t *open_file)
return status;
}
// DEBUG routines 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)
{
int i;
for (i = 0; i < level; i++)
{
putc(' ');
}
kprintf("%c (0x%x) mount: 0x%x, up: 0x%x, next:0x%x, down:0x%x\n", node->chr, node, node->mount, node->up, node->next, node->down);
node = node->down;
if (!node)
return;
while (node)
{
vfs_dump_node(node, level + 1);
node = node->next;
}
}
/******************************************/

View File

@ -49,6 +49,7 @@ struct vfs_mount_s
char *mountPoint;
vfs_inode_t vfs_mount_inode;
vfs_inode_t vfs_up_inode;
vfs_inode_t vfs_root_inode;
struct vfs_mount_s *next;
struct vfs_mount_s *prev;
};
@ -81,6 +82,12 @@ typedef struct
u32_t inode_number; // relative inode number returned from fs
} vfs_dir_entry_t;
typedef struct
{
vfs_mount_t *mount;
u32_t inode;
} vfs_file_addr_t;
/* Every filesystem must provide pointers to its respective functions in a structure like this */
typedef struct
{
@ -88,6 +95,7 @@ typedef struct
int (*umount_super)(vfs_mount_t *mount);
int (*stat)(vfs_mount_t *mount, u32_t inode_number, vfs_stat_t *stat);
u32_t (*get_root_inode)(vfs_mount_t *mount);
int (*link_deref)(vfs_mount_t *mount, u32_t inode_number, char *link);
int (*open_dir)(vfs_mount_t *mount, u32_t inode_number, vfs_open_file_t *dir);
int (*read_dir)(vfs_mount_t *mount, vfs_open_file_t *dir, vfs_dir_entry_t *dentry);
@ -108,28 +116,28 @@ typedef struct
int vfs_init();
int vfs_mount(major_t maj, minor_t min, int fsType, char *mountPoint);
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);
int vfs_umount(char *mountPoint);
int vfs_retire_node(vfs_node_t *node);
vfs_inode_t vfs_get_inode_number(char *path);
vfs_inode_t vfs_get_inode_number_rel(vfs_inode_t dir_inode, char *path);
vfs_inode_t vfs_real_inode(vfs_inode_t vfs_inode);
vfs_file_addr_t vfs_get_file_addr(vfs_inode_t vfs_inode);
vfs_inode_t vfs_entry_lookup(vfs_inode_t dir_inode, char *entry);
int vfs_link_deref(vfs_inode_t vfs_inode, char *link);
int vfs_stat(char *file, vfs_stat_t *stat);
int vfs_stat_inode(vfs_inode_t vfs_inode, vfs_stat_t *stat);
vfs_open_file_t *vfs_open_dir(char *file);
vfs_open_file_t *vfs_open_dir(char *path);
vfs_open_file_t *vfs_open_dir_inode(vfs_inode_t inode);
int vfs_read_dir(vfs_open_file_t *open_dir, vfs_dir_entry_t *dentry);
int vfs_close_dir(vfs_open_file_t *open_dir);
vfs_open_file_t *vfs_open_block_file(char *file);
vfs_open_file_t *vfs_open_block_file_inode(vfs_inode_t vfs_inode);
int vfs_read_block_file(vfs_open_file_t *open_file, void *buffer);
int vfs_block_file_seek(vfs_open_file_t *open_file, u32_t block_number);
int vfs_close_block_file(vfs_open_file_t *open_file);
// DEBUG routines
void vfs_dump_tree();
void vfs_dump_node(vfs_node_t *node, int level);
#endif

View File

@ -136,18 +136,16 @@ void k_init()
}
}
/* vfs_open_file_t *root = vfs_open_dir("/");
vfs_open_file_t *root = vfs_open_dir("/link");
if (root)
{
vfs_dir_entry_t dentry;
char *fname = kmalloc(257);
vfs_stat_t fstat;
while (!vfs_read_dir(root, &dentry))
{
strcpy(fname, "/");
strcat(fname, dentry.name);
vfs_stat(fname, &fstat);
putc(fstat.type == VFS_FT_DIR ? 'd' : fstat.type == VFS_FT_CHAR ? 'c' : fstat.type == VFS_FT_BLOCK ? 'b' : '-');
vfs_stat_inode(dentry.inode_number, &fstat);
kprintf("%d\t", fstat.inode);
putc(fstat.type == VFS_FT_DIR ? 'd' : fstat.type == VFS_FT_CHAR ? 'c' : fstat.type == VFS_FT_BLOCK ? 'b' : fstat.type == VFS_FT_SYMLINK ? 'l' : '-');
putc(fstat.permissions & VFS_PERMS_UR ? 'r' : '-');
putc(fstat.permissions & VFS_PERMS_UW ? 'w' : '-');
putc(fstat.permissions & VFS_PERMS_UX ? 'x' : '-');
@ -163,13 +161,20 @@ void k_init()
kprintf(" %d\t%d\t%d\t%d\t%s", fstat.links, fstat.uid, fstat.gid, fstat.size, dentry.name);
if (fstat.type == VFS_FT_CHAR || fstat.type == VFS_FT_BLOCK)
kprintf("\t(%d, %d)", fstat.dev >> 8, fstat.dev & 0xFF);
if (fstat.type == VFS_FT_SYMLINK)
{
char *link = kmalloc(4096);
vfs_link_deref(dentry.inode_number, link);
kprintf(" -> %s", link);
kfree(link);
}
putc('\n');
}
vfs_close_dir(root);
}
else
kprintf("Error: Could not open /txt/Makefile!\n");
*/
kprintf("Error: Could not open directory\n");
criticalCounter--;
}

View File

@ -44,6 +44,25 @@ int strncmp(char *str1, char *str2, int n)
}
/* str_change changes a certain character in a string
* to a different character
* Returns: how many characters were changed
*/
int str_change(char *str, char ch1, char ch2)
{
int count = 0;
while (*str)
{
if (*str == ch1)
{
*str = ch2;
count++;
}
str++;
}
return count;
}
// counts the occurrences of lookfor in str
int str_count(char *str, char lookfor)
{
@ -60,6 +79,8 @@ int str_count(char *str, char lookfor)
// split the string into substrings by the splitchar, return number of substrings
int str_split(char *str, char splitchar)
{
if (!(*str))
return 0;
int subs = 1;
while (*str)
{

View File

@ -29,6 +29,7 @@ void invlpg_(u32_t addr);
/* lang.c */
int strcmp(char *str1, char *str2);
int strncmp(char *str1, char *str2, int n);
int str_change(char *str, char ch1, char ch2);
int str_count(char *str, char lookfor);
int str_split(char *str, char splitchar);
char *str_advance(char *str);

View File

@ -53,7 +53,7 @@ no_vesa:
end_rmmod: ; get ready to go back to pmode and return to kernel initialization
call con_getkey
; call con_getkey
mov ebx, [dat_retn]
lgdt [gdtrlin32]
mov eax, cr0