Fix VFS crash
This commit is contained in:
parent
6eea55d645
commit
c941207cc6
|
@ -9,7 +9,10 @@
|
|||
#include <kernel/devices/device.h>
|
||||
|
||||
// Internal VFS macros
|
||||
#define VFS_MOUNT_ROOT (-1)
|
||||
#define VFS_MOUNT_ROOT (-1)
|
||||
#define VFS_DENTRY_RESOLVE_FLAG_FULL_PATH (0)
|
||||
#define VFS_DENTRY_RESOLVE_FLAG_PATHNAME (1)
|
||||
|
||||
|
||||
|
||||
// Constructor / destructor
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <kernel/fs/file.h>
|
||||
#include <kernel/fs/filesystem.h>
|
||||
#include <kernel/context.h>
|
||||
#include <kernel/types.h>
|
||||
|
||||
|
@ -39,6 +40,7 @@ typedef struct process_s
|
|||
} status;
|
||||
FILE file;
|
||||
} opfile[PROCESS_NB_OPEN_FILE];
|
||||
struct dentry *working_dir;
|
||||
|
||||
// Signals management.
|
||||
//sighandler_t signal[NSIG];
|
||||
|
|
|
@ -17,7 +17,7 @@ extern pid_t waitpid(pid_t pid, int *wstatus, int options);
|
|||
|
||||
// File syscall
|
||||
#define O_DIRECT 0
|
||||
extern int open(const char *pathname, int flags); // <-- TODO: va_arg
|
||||
extern int open(const char *pathname, int flags, ...);
|
||||
extern ssize_t write(int fd, const void *buf, size_t count);
|
||||
extern ssize_t read(int fd, void *buf, size_t count);
|
||||
extern int close(int fd);
|
||||
|
|
|
@ -85,22 +85,6 @@ static void section_execute(void *bsection, void *esection)
|
|||
}
|
||||
}
|
||||
|
||||
void vfs_test(struct dentry *node, int level)
|
||||
{
|
||||
if (node == NULL)
|
||||
return;
|
||||
|
||||
// space !
|
||||
for (int i = 0 ; i < level ; i++)
|
||||
tty_write(NULL, " ", 1);
|
||||
|
||||
// Name
|
||||
tty_write(NULL, node->name, strlen(node->name));
|
||||
tty_write(NULL, "\n", 1);
|
||||
|
||||
vfs_test(vfs_dentry_find_first_child(node), level + 1);
|
||||
vfs_test(vfs_dentry_find_next_sibling(node), level);
|
||||
}
|
||||
|
||||
/* start() - Kernel entry point */
|
||||
__attribute__((section(".pretext")))
|
||||
|
@ -158,6 +142,7 @@ int start(void)
|
|||
// Creat initial file tree
|
||||
vfs_mount(NULL, NULL, "gladfs", VFS_MOUNT_ROOT, NULL);
|
||||
vfs_mkdir("/dev", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
vfs_mkdir("/home", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
vfs_mkdir("/mnt", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
vfs_mkdir("/mnt/smemfs", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
vfs_mount(NULL, "/mnt/smemfs", "smemfs", /*MS_RDONLY*/0, NULL);
|
||||
|
@ -166,12 +151,8 @@ int start(void)
|
|||
vfs_mknod("/dev/tty", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH,
|
||||
dev_make_major(TTY_DEV_MAJOR));
|
||||
|
||||
// VFS test
|
||||
tty_open(0, 0);
|
||||
extern struct dentry *vfs_root_node;
|
||||
vfs_test(vfs_root_node, 0);
|
||||
tty_write(NULL, "FINIT !\n", 8);
|
||||
DBG_WAIT;
|
||||
extern void kernel_test(void);
|
||||
kernel_test();
|
||||
|
||||
// Create first process: Vhex.
|
||||
pid_t vhex_pid = process_create("Vhex");
|
||||
|
@ -181,7 +162,9 @@ int start(void)
|
|||
vhex_process->context.ssr = atomic_start();
|
||||
|
||||
// Load programe.
|
||||
vhex_process->context.spc = (uint32_t)loader("/mnt/smemfs/VHEX/shell.elf", vhex_process);
|
||||
extern void kernel_test(void);
|
||||
vhex_process->context.spc = (uint32_t)&kernel_test;
|
||||
//vhex_process->context.spc = (uint32_t)loader("/mnt/smemfs/VHEX/shell.elf", vhex_process);
|
||||
if (vhex_process->context.spc == 0x00000000)
|
||||
{
|
||||
// Display message.
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <kernel/memory.h>
|
||||
#include <kernel/util.h>
|
||||
|
||||
/* vfs_dentry_alloc() - Allocate new "empty" dentry */
|
||||
struct dentry *vfs_dentry_alloc(const char *name, mode_t mode)
|
||||
{
|
||||
struct dentry *node;
|
||||
|
@ -13,9 +14,16 @@ struct dentry *vfs_dentry_alloc(const char *name, mode_t mode)
|
|||
|
||||
// Initialize dentry
|
||||
memset(node->name, 0x00, VFS_DENTRY_NAME_LENGHT);
|
||||
strncpy(node->name, name, VFS_DENTRY_NAME_LENGHT);
|
||||
node->inode = NULL;
|
||||
|
||||
// Set the name if possible
|
||||
if (name != NULL)
|
||||
strncpy(node->name, name, VFS_DENTRY_NAME_LENGHT);
|
||||
|
||||
// Set the mode
|
||||
node->mode = mode;
|
||||
|
||||
// Set default value
|
||||
node->inode = NULL;
|
||||
node->parent = NULL;
|
||||
node->child = NULL;
|
||||
node->next = NULL;
|
||||
|
|
|
@ -3,6 +3,15 @@
|
|||
#include <kernel/util.h>
|
||||
#include <kernel/fs/stat.h>
|
||||
|
||||
//
|
||||
// vfs_dentry_find_first_child()
|
||||
// Find the fist file of a file
|
||||
// @note:
|
||||
// To avoid useless memory used, the VFS cache
|
||||
// is generated only if the user want to access to a file
|
||||
// unregister to the cahe.
|
||||
// TODO: explain correctly x)
|
||||
//
|
||||
struct dentry *vfs_dentry_find_first_child(struct dentry *dentry)
|
||||
{
|
||||
// Check file type
|
||||
|
@ -43,7 +52,7 @@ struct dentry *vfs_dentry_find_first_child(struct dentry *dentry)
|
|||
}
|
||||
|
||||
// Try to create new dentry
|
||||
struct dentry *new_dentry = pm_alloc(sizeof(struct dentry));
|
||||
struct dentry *new_dentry = vfs_dentry_alloc(NULL, 0);
|
||||
if (new_dentry == NULL)
|
||||
return (NULL);
|
||||
|
||||
|
@ -64,11 +73,7 @@ struct dentry *vfs_dentry_find_first_child(struct dentry *dentry)
|
|||
// Common init
|
||||
new_dentry->inode = inode;
|
||||
new_dentry->parent = dentry;
|
||||
new_dentry->child = NULL;
|
||||
new_dentry->next = dentry->child;
|
||||
new_dentry->mnt.inode = NULL;
|
||||
new_dentry->mnt.file_op = NULL;
|
||||
new_dentry->mnt.inode_op = NULL;
|
||||
|
||||
// Update VFS cache en return
|
||||
dentry->child = new_dentry;
|
||||
|
|
|
@ -25,7 +25,7 @@ struct dentry *vfs_dentry_find_next_sibling(struct dentry *dentry)
|
|||
return (NULL);
|
||||
|
||||
// Try to create new dentry
|
||||
struct dentry *new_dentry = pm_alloc(sizeof(struct dentry));
|
||||
struct dentry *new_dentry = vfs_dentry_alloc(NULL, 0);
|
||||
if (new_dentry == NULL)
|
||||
return (NULL);
|
||||
|
||||
|
@ -34,15 +34,11 @@ struct dentry *vfs_dentry_find_next_sibling(struct dentry *dentry)
|
|||
new_dentry->mode = dentry->dentry_op.inode_op->get_mode(inode);
|
||||
new_dentry->inode = inode;
|
||||
new_dentry->parent = dentry;
|
||||
new_dentry->child = NULL;
|
||||
new_dentry->next = dentry->next;
|
||||
new_dentry->dentry_op.file_op = dentry->dentry_op.file_op;
|
||||
new_dentry->dentry_op.inode_op = dentry->dentry_op.inode_op;
|
||||
new_dentry->mnt.inode = NULL;
|
||||
new_dentry->mnt.file_op = NULL;
|
||||
new_dentry->mnt.inode_op = NULL;
|
||||
|
||||
// Update VFS cache en return
|
||||
new_dentry->next = dentry->next;
|
||||
dentry->next = new_dentry;
|
||||
return (new_dentry);
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include <kernel/fs/vfs.h>
|
||||
#include <kernel/memory.h>
|
||||
|
||||
/* vfs_dentry_free() - Free'd allocated dentry */
|
||||
/* @note: *WARNING* no verification will be done, so do not use this primitive */
|
||||
void vfs_dentry_free(struct dentry *dentry)
|
||||
{
|
||||
// Check error
|
||||
|
|
|
@ -1,20 +1,43 @@
|
|||
#include <kernel/fs/vfs.h>
|
||||
#include <kernel/fs/stat.h>
|
||||
#include <kernel/process.h>
|
||||
#include <kernel/util.h>
|
||||
|
||||
//TODO add '.' handling.
|
||||
static int get_name(int *name_lenght, const char *path, char *name)
|
||||
{
|
||||
// Get file name
|
||||
*name_lenght = 0;
|
||||
while (*name_lenght < 24 &&
|
||||
path[*name_lenght] != '/' &&
|
||||
path[*name_lenght] != '\0')
|
||||
{
|
||||
name[*name_lenght] = path[*name_lenght];
|
||||
*name_lenght = *name_lenght + 1;
|
||||
}
|
||||
|
||||
// Check error
|
||||
if (path[*name_lenght] != '/' && path[*name_lenght] != '\0')
|
||||
return (-1);
|
||||
|
||||
// Add null char
|
||||
name[*name_lenght] = '\0';
|
||||
return (0);
|
||||
}
|
||||
|
||||
//TODO add '..' handling.
|
||||
//TODO add '//' handling
|
||||
struct dentry *vfs_dentry_resolve(const char *path, int mode)
|
||||
{
|
||||
extern struct process_s *process_current;
|
||||
extern struct dentry *vfs_root_node;
|
||||
struct dentry *curr_dentry;
|
||||
struct dentry *old_dentry;
|
||||
struct dentry *file;
|
||||
struct dentry *next;
|
||||
struct dentry *tmp;
|
||||
int name_lenght;
|
||||
char name[24];
|
||||
|
||||
// Check VFS validity
|
||||
if (vfs_root_node == NULL){
|
||||
if (vfs_root_node == NULL)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "VFS root error !");
|
||||
kvram_display();
|
||||
|
@ -23,61 +46,109 @@ struct dentry *vfs_dentry_resolve(const char *path, int mode)
|
|||
}
|
||||
|
||||
// Get start inode
|
||||
if (path[0] != '/'){
|
||||
// TODO get current process working directory
|
||||
return (NULL);
|
||||
if (path[0] != '/')
|
||||
{
|
||||
// Check if current process validity
|
||||
if (process_current == NULL)
|
||||
return (NULL);
|
||||
|
||||
// Get current working directory
|
||||
file = process_current->working_dir;
|
||||
next = process_current->working_dir->child;
|
||||
} else {
|
||||
curr_dentry = vfs_root_node->child;
|
||||
old_dentry = vfs_root_node;
|
||||
path = path + 1;
|
||||
// Get root inode
|
||||
file = vfs_root_node;
|
||||
next = vfs_root_node->child;
|
||||
|
||||
// Update path (skip '/')
|
||||
path = &path[1];
|
||||
}
|
||||
|
||||
// VFS walk entry !
|
||||
while (path[0] != '\0')
|
||||
{
|
||||
// Get file name
|
||||
name_lenght = 0;
|
||||
while (name_lenght < 24 &&
|
||||
path[name_lenght] != '/' &&
|
||||
path[name_lenght] != '\0')
|
||||
{
|
||||
name[name_lenght] = path[name_lenght];
|
||||
name_lenght = name_lenght + 1;
|
||||
}
|
||||
|
||||
// Check error
|
||||
if (path[name_lenght] != '/' && path[name_lenght] != '\0')
|
||||
// Get next file name
|
||||
if (get_name(&name_lenght, path, name) != 0)
|
||||
return (NULL);
|
||||
|
||||
// Add null char
|
||||
name[name_lenght] = '\0';
|
||||
// Check '..' file (parent directory)
|
||||
if (name[0] == '.' && name[1] == '.' && name[2] == '\0')
|
||||
{
|
||||
if (file->parent != NULL)
|
||||
{
|
||||
next = file->parent->child;
|
||||
file = file->parent->child;
|
||||
}
|
||||
path = &path[3];
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check parthname or path
|
||||
if (mode == 1 && path[name_lenght] == '\0')
|
||||
return (old_dentry);
|
||||
// Check '.' or '//' file (current directory)
|
||||
if (name[0] == '\0' || (name[0] == '.' && name[1] == '\0'))
|
||||
{
|
||||
path = (path[name_lenght] == '/') ? &path[name_lenght + 1] : &path[name_lenght];
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check potential error
|
||||
if (curr_dentry == NULL)
|
||||
// Check parthname or path mode
|
||||
if (path[name_lenght] == '\0' &&
|
||||
mode == VFS_DENTRY_RESOLVE_FLAG_PATHNAME)
|
||||
break;
|
||||
|
||||
// Check next file entry
|
||||
if (next == NULL)
|
||||
return (NULL);
|
||||
|
||||
// Try to find file in the current VFS level.
|
||||
while (strncmp(curr_dentry->name, name, name_lenght) != 0)
|
||||
while (strncmp(next->name, name, name_lenght) != 0)
|
||||
{
|
||||
curr_dentry = vfs_dentry_find_next_sibling(curr_dentry);
|
||||
if (curr_dentry == NULL)
|
||||
tmp = next;
|
||||
next = vfs_dentry_find_next_sibling(next);
|
||||
if (next == NULL)
|
||||
{
|
||||
// Debug !
|
||||
kvram_clear();
|
||||
printk(0, 0, "vfs_resolve(): sibling error !");
|
||||
printk(0, 1, "old next: %s$", tmp->name);
|
||||
printk(0, 2, "file: %s$", file->name);
|
||||
printk(0, 3, "name: %s$", name);
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
while (1);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// Update current file
|
||||
file = next;
|
||||
|
||||
// Directory check
|
||||
if (path[name_lenght] == '/')
|
||||
{
|
||||
// Check type
|
||||
if ((curr_dentry->mode & __S_IFDIR) == 0)
|
||||
if ((file->mode & __S_IFDIR) == 0)
|
||||
{
|
||||
// Debug !
|
||||
kvram_clear();
|
||||
printk(0, 0, "vfs_resolve(): dir error !");
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// Try to find first child
|
||||
old_dentry = curr_dentry;
|
||||
curr_dentry = vfs_dentry_find_first_child(curr_dentry);
|
||||
next = vfs_dentry_find_first_child(next);
|
||||
if (next != NULL)
|
||||
{
|
||||
// Debug !
|
||||
kvram_clear();
|
||||
printk(0, 0, "vfs_resolve(): child info !");
|
||||
printk(0, 1, "file name: %s$", file->name);
|
||||
printk(0, 2, "next name: %s$", next->name);
|
||||
printk(0, 3, "name: %s$", name);
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
}
|
||||
|
||||
// Update name lenght to skip '/' char
|
||||
name_lenght = name_lenght + 1;
|
||||
|
@ -86,5 +157,5 @@ struct dentry *vfs_dentry_resolve(const char *path, int mode)
|
|||
// Update path
|
||||
path = &path[name_lenght];
|
||||
}
|
||||
return (curr_dentry);
|
||||
return (file);
|
||||
}
|
||||
|
|
|
@ -21,8 +21,9 @@ off_t vfs_lseek(FILE *file, off_t offset, int whence)
|
|||
if (whence == SEEK_END)
|
||||
{
|
||||
//TODO: get file size !!
|
||||
//TODO: use copy-on-write system !!
|
||||
//file->cursor = file->size + offset - 1;
|
||||
return (file->cursor);
|
||||
return (-1);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
#include <kernel/fs/stat.h>
|
||||
#include <kernel/util.h>
|
||||
|
||||
// Intrenal functions
|
||||
extern struct dentry *vfs_dentry_resolve(const char *path, int mode);
|
||||
|
||||
/* vfs_open() - Open file named pathname */
|
||||
int vfs_open(FILE *file, char const *pathname, int flags)
|
||||
{
|
||||
struct dentry *dentry;
|
||||
|
@ -14,7 +12,8 @@ int vfs_open(FILE *file, char const *pathname, int flags)
|
|||
if (dentry == NULL)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "VFS_open(): path error '%s'", pathname);
|
||||
printk(0, 0, "VFS_open() error !");
|
||||
printk(0, 1, "path error '%s'", pathname);
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
return (-1);
|
||||
|
@ -30,6 +29,18 @@ int vfs_open(FILE *file, char const *pathname, int flags)
|
|||
return (-2);
|
||||
}
|
||||
|
||||
// debug
|
||||
kvram_clear();
|
||||
printk(0, 0, "vfs_open(): inode found !");
|
||||
printk(0, 1, "path: %s", pathname);
|
||||
printk(0, 2, "name: %s", dentry->name);
|
||||
printk(0, 3, "inode: %p", dentry->inode);
|
||||
printk(0, 4, "file_op: %p", dentry->dentry_op.file_op);
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
|
||||
//TODO: update interne dentry counter !!
|
||||
|
||||
// Initialize new file.
|
||||
file->private = dentry->inode;
|
||||
file->permission = dentry->mode & (~__S_IFMT);
|
||||
|
|
|
@ -10,7 +10,9 @@ ssize_t vfs_read(FILE *file, void *buf, size_t count)
|
|||
return (-1);
|
||||
|
||||
// Get / check file's informations
|
||||
if (file->private == NULL || file->file_op->read == NULL)
|
||||
if (file->private == NULL ||
|
||||
file->file_op == NULL ||
|
||||
file->file_op->read == NULL)
|
||||
return (-1);
|
||||
|
||||
// Read with FS specifique primitive and return the numbe of reading bytes.
|
||||
|
|
|
@ -10,7 +10,9 @@ ssize_t vfs_write(FILE *file, const void *buf, size_t count)
|
|||
return (-1);
|
||||
|
||||
// Get / check file's informations
|
||||
if (file->private == NULL || file->file_op->write == NULL)
|
||||
if (file->private == NULL ||
|
||||
file->file_op == NULL ||
|
||||
file->file_op->write == NULL)
|
||||
return (-1);
|
||||
|
||||
// Writa with FS specifique primitive and return the numbe of reading bytes.
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
#include <kernel/fs/stat.h>
|
||||
#include <kernel/util.h>
|
||||
|
||||
// Internal functions
|
||||
struct dentry *vfs_dentry_resolve(const char *path, int mode);
|
||||
|
||||
/* vfs_mkdir() - Attempts to create a directory named pathname */
|
||||
int vfs_mkdir(const char *pathname, mode_t mode)
|
||||
{
|
||||
extern struct dentry *vfs_root_node;
|
||||
|
@ -18,14 +16,14 @@ int vfs_mkdir(const char *pathname, mode_t mode)
|
|||
name = (name == NULL) ? (void *)pathname : &name[1];
|
||||
|
||||
// Get parent dentry
|
||||
parent_dentry = vfs_dentry_resolve(pathname, 1);
|
||||
parent_dentry = vfs_dentry_resolve(pathname, VFS_DENTRY_RESOLVE_FLAG_PATHNAME);
|
||||
|
||||
// Check parent dentry and FS primitives
|
||||
if (parent_dentry == NULL || parent_dentry->dentry_op.inode_op->mkdir == NULL)
|
||||
return (-1);
|
||||
|
||||
// Try to create new dentry
|
||||
folder = pm_alloc(sizeof(struct dentry));
|
||||
folder = vfs_dentry_alloc(name, mode | __S_IFDIR);
|
||||
if (folder == NULL)
|
||||
return (-2);
|
||||
|
||||
|
@ -33,24 +31,17 @@ int vfs_mkdir(const char *pathname, mode_t mode)
|
|||
folder->inode = parent_dentry->dentry_op.inode_op->mkdir(parent_dentry->inode, name, mode);
|
||||
if (folder->inode == NULL)
|
||||
{
|
||||
pm_free(folder);
|
||||
vfs_dentry_free(folder);
|
||||
return (-3);
|
||||
}
|
||||
|
||||
// Initialize new dentry
|
||||
memset(folder->name, 0x00, VFS_DENTRY_NAME_LENGHT);
|
||||
strncpy(folder->name, name, VFS_DENTRY_NAME_LENGHT);
|
||||
folder->mode = mode | __S_IFDIR;
|
||||
folder->parent = parent_dentry;
|
||||
folder->next = parent_dentry->child;
|
||||
folder->child = NULL;
|
||||
// Set FS primitives operations
|
||||
folder->dentry_op.file_op = parent_dentry->dentry_op.file_op;
|
||||
folder->dentry_op.inode_op = parent_dentry->dentry_op.inode_op;
|
||||
folder->mnt.inode = NULL;
|
||||
folder->mnt.inode_op = NULL;
|
||||
folder->mnt.file_op = NULL;
|
||||
|
||||
// Release dentry
|
||||
folder->parent = parent_dentry;
|
||||
folder->next = parent_dentry->child;
|
||||
parent_dentry->child = folder;
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <kernel/fs/stat.h>
|
||||
#include <kernel/util.h>
|
||||
|
||||
/* gevice_get() - Find internal device */
|
||||
struct device *device_get(dev_t major)
|
||||
{
|
||||
extern uint32_t bdevice_section;
|
||||
|
@ -19,6 +20,7 @@ struct device *device_get(dev_t major)
|
|||
return (NULL);
|
||||
}
|
||||
|
||||
/* vfs_mknod - Create VFS inode (file, device special file, or pipe) named pathname */
|
||||
int vfs_mknod(const char *pathname, mode_t mode, dev_t dev)
|
||||
{
|
||||
extern struct dentry *vfs_root_node;
|
||||
|
@ -27,60 +29,54 @@ int vfs_mknod(const char *pathname, mode_t mode, dev_t dev)
|
|||
struct dentry *file;
|
||||
char *name;
|
||||
|
||||
// Check device
|
||||
// TODO: remove me !
|
||||
if (dev == 0)
|
||||
return (-2);
|
||||
|
||||
// Get parent dentry
|
||||
parent_dentry = vfs_dentry_resolve(pathname, 1);
|
||||
parent_dentry = vfs_dentry_resolve(pathname, VFS_DENTRY_RESOLVE_FLAG_PATHNAME);
|
||||
if (parent_dentry == NULL)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "mknod: parent dentry error !");
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
// Get folder name
|
||||
name = strrchr(pathname, '/');
|
||||
name = (name == NULL) ? (void *)pathname : &name[1];
|
||||
|
||||
// Try to find open device
|
||||
// Try to find the device
|
||||
// TODO: handle othe file (mode) !!!
|
||||
device = device_get(dev_get_major(dev));
|
||||
if (device == NULL)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "mknod: device error !");
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
return (-2);
|
||||
}
|
||||
|
||||
// Tru to create empty node
|
||||
file = vfs_dentry_alloc(name, mode | __S_IFCHR);
|
||||
if (file == NULL)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "mknod: dentry alloc error !");
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
return (-3);
|
||||
}
|
||||
|
||||
|
||||
// Try to open device
|
||||
file->inode = device->open(dev_get_major(dev), dev_get_minor(dev));
|
||||
if (file->inode == NULL)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "mknod: device inode error !");
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
vfs_dentry_free(file);
|
||||
return (-4);
|
||||
}
|
||||
|
||||
|
||||
// Debug !
|
||||
kvram_clear();
|
||||
printk(0, 0, "New mknod device !");
|
||||
printk(0, 1, "dentry: %p$", file);
|
||||
printk(0, 2, "inode: %p$", file->inode);
|
||||
printk(0, 3, "name: %s$", file->name);
|
||||
printk(0, 4, "dev->file_op: %p$", &device->file_op);
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
DBG_WAIT;
|
||||
|
||||
// Set file operations
|
||||
file->dentry_op.file_op = &device->file_op;
|
||||
|
||||
// Add file into VFS
|
||||
file->parent = parent_dentry;
|
||||
file->next = parent_dentry->child;
|
||||
parent_dentry->child = file;
|
||||
return (0);
|
||||
|
|
|
@ -42,8 +42,12 @@ int vfs_mount(const char *source, const char *target,
|
|||
// Check ROOT mount.
|
||||
if (target == NULL && mountflags == (unsigned long)VFS_MOUNT_ROOT)
|
||||
{
|
||||
// Check VFS root
|
||||
if (vfs_root_node != NULL)
|
||||
return (-4);
|
||||
|
||||
// Alloc root mnt
|
||||
vfs_root_node = pm_alloc(sizeof(struct dentry));
|
||||
vfs_root_node = vfs_dentry_alloc("/", __S_IFDIR);
|
||||
if (vfs_root_node == NULL)
|
||||
return (-1);
|
||||
|
||||
|
@ -58,22 +62,23 @@ int vfs_mount(const char *source, const char *target,
|
|||
while (1) { __asm__ volatile ("sleep"); }
|
||||
}
|
||||
|
||||
// Initialize entry
|
||||
vfs_root_node->name[0] = '/';
|
||||
vfs_root_node->name[1] = '\0';
|
||||
vfs_root_node->parent = NULL;
|
||||
vfs_root_node->child = NULL;
|
||||
vfs_root_node->next = NULL;
|
||||
// Get File System primitives
|
||||
vfs_root_node->dentry_op.file_op = &filesystem->file_operations;
|
||||
vfs_root_node->dentry_op.inode_op = &filesystem->inode_operations;
|
||||
vfs_root_node->mnt.inode = NULL;
|
||||
vfs_root_node->mnt.file_op = NULL;
|
||||
vfs_root_node->mnt.inode_op = NULL;
|
||||
|
||||
// Debug !
|
||||
kvram_clear();
|
||||
printk(0, 0, "vfs_root_node = %p", vfs_root_node);
|
||||
printk(0, 1, "vfs_root_node = %s$", vfs_root_node->name);
|
||||
printk(0, 2, "vfs_root_node = %p", vfs_root_node->child);
|
||||
printk(0, 3, "vfs_root_node = %p", vfs_root_node->next);
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
return (0);
|
||||
}
|
||||
|
||||
// Get target inode informations
|
||||
struct dentry *mnt = vfs_dentry_resolve(target, 0);
|
||||
struct dentry *mnt = vfs_dentry_resolve(target, VFS_DENTRY_RESOLVE_FLAG_FULL_PATH);
|
||||
if (mnt == NULL)
|
||||
return (-1);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
.align 2
|
||||
_exception_handler_pre:
|
||||
! Due to TRAPA syscall API we should
|
||||
! Due to TRAPA syscall ABI we should
|
||||
! switch stack to avoid variodic argument
|
||||
! corruption.
|
||||
mov.l .process_current, r2 ! get current_process address
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
pid_t process_create(const char *name)
|
||||
{
|
||||
extern struct dentry *vfs_root_node;
|
||||
extern process_t *process_current;
|
||||
process_t *process;
|
||||
pid_t process_pid;
|
||||
|
@ -69,6 +70,17 @@ pid_t process_create(const char *name)
|
|||
process->context.ssr = 0x00000000;
|
||||
process->context.spc = 0x00000000;
|
||||
|
||||
// Initialise file cache
|
||||
for (int i = 0 ; i < PROCESS_NB_OPEN_FILE ; i = i + 1)
|
||||
{
|
||||
process->opfile[i].status = PROCESS_FILE_SLOT_UNUSED;
|
||||
process->opfile[i].file.private = NULL;
|
||||
process->opfile[i].file.file_op = NULL;
|
||||
process->opfile[i].file.cursor = 0;
|
||||
process->opfile[i].file.permission = 0;
|
||||
}
|
||||
process->working_dir = vfs_root_node;
|
||||
|
||||
// Initialize processes.
|
||||
process->parent = process_current;
|
||||
process->child = NULL;
|
||||
|
|
|
@ -44,12 +44,15 @@ void *sys_get_handler(int sysno)
|
|||
return (0);
|
||||
|
||||
// DEBUG
|
||||
/* kvram_clear();
|
||||
printk(0, 0, "sysno = %d", sysno);
|
||||
printk(0, 0, "handler = %p", sys_handler[sysno]);
|
||||
kvram_clear();
|
||||
printk(0, 0, "TRAPA ABI pre_handler !");
|
||||
printk(0, 1, "sysno = %d", sysno);
|
||||
printk(0, 2, "handler = %p", sys_handler[sysno]);
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
*/
|
||||
DBG_WAIT;
|
||||
DBG_WAIT;
|
||||
|
||||
// Return syscall
|
||||
return ((void *)sys_handler[sysno]);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
#include <kernel/fs/vfs.h>
|
||||
#include <kernel/devices/tty.h>
|
||||
#include <kernel/memory.h>
|
||||
#include <kernel/util.h>
|
||||
|
||||
// Tree-wrapper
|
||||
static void vfs_test(struct dentry *node, int level)
|
||||
{
|
||||
int curr_line;
|
||||
|
||||
// Check error.
|
||||
if (node == NULL)
|
||||
return;
|
||||
|
||||
// Space management.
|
||||
for (int i = 0 ; i < level ; i++)
|
||||
tty_write(NULL, " ", 1);
|
||||
|
||||
// Display name
|
||||
tty_write(NULL, node->name, strlen(node->name));
|
||||
tty_write(NULL, "\n", 1);
|
||||
|
||||
// Walk into child and sibling
|
||||
vfs_test(vfs_dentry_find_first_child(node), level + 1);
|
||||
vfs_test(vfs_dentry_find_next_sibling(node), level);
|
||||
}
|
||||
|
||||
void kernel_test(void)
|
||||
{
|
||||
extern struct dentry *vfs_root_node;
|
||||
char path[] = "/../dev/./../dev/////tty";
|
||||
void *test;
|
||||
FILE file;
|
||||
|
||||
// Debug !
|
||||
kvram_clear();
|
||||
printk(0, 0, "Kernel test mode entry !");
|
||||
printk(0, 1, "Check VFS...");
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
|
||||
// Check root node
|
||||
printk(0, 2, "vfs_root_node = %p", vfs_root_node);
|
||||
printk(0, 3, "vfs_root_node = %s$", vfs_root_node->name);
|
||||
printk(0, 4, "vfs_root_node = %p", vfs_root_node->child);
|
||||
printk(0, 5, "vfs_root_node = %p", vfs_root_node->next);
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
|
||||
// VFS test
|
||||
tty_open(0, 0);
|
||||
vfs_test(vfs_root_node, 0);
|
||||
tty_write(NULL, "FINI !\n", 7);
|
||||
DBG_WAIT;
|
||||
DBG_WAIT;
|
||||
|
||||
// Try to open file using VFS
|
||||
if (vfs_open(&file, path, 0))
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "vfs_open(): error !");
|
||||
printk(0, 1, "path %s$", path);
|
||||
kvram_display();
|
||||
while (1) { __asm__ volatile ("sleep"); }
|
||||
}
|
||||
|
||||
// Display file informations
|
||||
kvram_clear();
|
||||
printk(0, 0, "vfs_open: success !");
|
||||
printk(0, 1, "path: %s$", path);
|
||||
printk(0, 2, "file->private: %p", file.private);
|
||||
printk(0, 3, "file->file_op: %p", file.file_op);
|
||||
kvram_display();
|
||||
while (1);
|
||||
}
|
|
@ -30,13 +30,14 @@ SECTIONS
|
|||
/*
|
||||
** ROM sections
|
||||
*/
|
||||
_brom = 0x00300000;
|
||||
_srom = 0x200 + SIZEOF(.text) +
|
||||
SIZEOF(.data) +
|
||||
SIZEOF(.vhex) +
|
||||
SIZEOF(.ubc);
|
||||
|
||||
. = ORIGIN(rom);
|
||||
_brom = ABSOLUTE (0x00300000) ;
|
||||
_srom = ABSOLUTE (0x200 +
|
||||
SIZEOF(.text) +
|
||||
SIZEOF(.data) +
|
||||
SIZEOF(.vhex) +
|
||||
SIZEOF(.ubc)) ;
|
||||
|
||||
.text : {
|
||||
/* Source Code */
|
||||
*(.pretext)
|
||||
|
|
Loading…
Reference in New Issue