2020-01-05 09:00:43 +01:00
|
|
|
#include <kernel/fs/vfs.h>
|
|
|
|
#include <kernel/memory.h>
|
|
|
|
#include <kernel/fs/stat.h>
|
2020-03-15 00:56:31 +01:00
|
|
|
#include <kernel/devices/earlyterm.h>
|
2020-03-28 19:52:59 +01:00
|
|
|
#include <kernel/util/atomic.h>
|
2020-03-15 00:56:31 +01:00
|
|
|
#include <lib/string.h>
|
2020-01-05 09:00:43 +01:00
|
|
|
|
|
|
|
// Internal informations
|
|
|
|
struct dentry *vfs_root_node = NULL;
|
|
|
|
|
|
|
|
// filesystem_get() - Get FS registered by the VFS
|
|
|
|
static struct file_system_type *filesystem_get(const char *name)
|
|
|
|
{
|
|
|
|
extern struct file_system_type *fs_list;
|
|
|
|
struct file_system_type *filesystem;
|
|
|
|
|
|
|
|
filesystem = fs_list;
|
|
|
|
while (filesystem != NULL)
|
|
|
|
{
|
|
|
|
// Check file system
|
|
|
|
if (strcmp(filesystem->fs_name, name) == 0)
|
|
|
|
return (filesystem);
|
|
|
|
|
|
|
|
// Get next file system
|
|
|
|
filesystem = filesystem->next;
|
|
|
|
}
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* vfs_mount() - mount filesystem */
|
|
|
|
int vfs_mount(const char *source, const char *target,
|
|
|
|
const char *filesystemtype, unsigned long mountflags,
|
|
|
|
const void *data)
|
|
|
|
{
|
2020-03-15 00:56:31 +01:00
|
|
|
// TODO: handle source and data !!
|
|
|
|
(void)source;
|
|
|
|
(void)data;
|
|
|
|
|
2020-01-05 09:00:43 +01:00
|
|
|
// Check error.
|
|
|
|
if (filesystemtype == NULL)
|
|
|
|
return (-1);
|
|
|
|
|
2020-03-28 19:52:59 +01:00
|
|
|
// Start operations
|
|
|
|
atomic_start();
|
|
|
|
|
2020-01-05 09:00:43 +01:00
|
|
|
// Get file system informations
|
|
|
|
struct file_system_type *filesystem = filesystem_get(filesystemtype);
|
2020-03-28 19:52:59 +01:00
|
|
|
if (filesystem == NULL) {
|
|
|
|
atomic_stop();
|
2020-01-05 09:00:43 +01:00
|
|
|
return (-1);
|
2020-03-28 19:52:59 +01:00
|
|
|
}
|
2020-01-05 09:00:43 +01:00
|
|
|
|
|
|
|
// Check ROOT mount.
|
|
|
|
if (target == NULL && mountflags == (unsigned long)VFS_MOUNT_ROOT)
|
|
|
|
{
|
2020-01-10 17:21:44 +01:00
|
|
|
// Check VFS root
|
2020-03-28 19:52:59 +01:00
|
|
|
if (vfs_root_node != NULL) {
|
|
|
|
atomic_stop();
|
2020-01-10 17:21:44 +01:00
|
|
|
return (-4);
|
2020-03-28 19:52:59 +01:00
|
|
|
}
|
2020-01-10 17:21:44 +01:00
|
|
|
|
2020-01-05 09:00:43 +01:00
|
|
|
// Alloc root mnt
|
2020-01-10 17:21:44 +01:00
|
|
|
vfs_root_node = vfs_dentry_alloc("/", __S_IFDIR);
|
2020-03-28 19:52:59 +01:00
|
|
|
if (vfs_root_node == NULL) {
|
|
|
|
atomic_stop();
|
2020-01-05 09:00:43 +01:00
|
|
|
return (-1);
|
2020-03-28 19:52:59 +01:00
|
|
|
}
|
2020-01-05 09:00:43 +01:00
|
|
|
|
|
|
|
// Try to mount the FS.
|
2020-03-15 00:56:31 +01:00
|
|
|
// TODO: add possibility to return to main menu
|
2020-01-05 09:00:43 +01:00
|
|
|
vfs_root_node->inode = filesystem->filesystem_operations.mount();
|
|
|
|
if (vfs_root_node->inode == NULL)
|
|
|
|
{
|
2020-03-15 00:56:31 +01:00
|
|
|
earlyterm_clear();
|
|
|
|
earlyterm_write("VFS: Unable to mount ROOT inode !");
|
|
|
|
earlyterm_write("Wait manual reset...");
|
2020-03-28 19:52:59 +01:00
|
|
|
atomic_stop();
|
2020-01-05 09:00:43 +01:00
|
|
|
while (1) { __asm__ volatile ("sleep"); }
|
|
|
|
}
|
|
|
|
|
2020-01-10 17:21:44 +01:00
|
|
|
// Get File System primitives
|
2020-01-05 09:00:43 +01:00
|
|
|
vfs_root_node->dentry_op.file_op = &filesystem->file_operations;
|
|
|
|
vfs_root_node->dentry_op.inode_op = &filesystem->inode_operations;
|
2020-03-28 19:52:59 +01:00
|
|
|
atomic_stop();
|
2020-01-05 09:00:43 +01:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get target inode informations
|
2020-01-10 17:21:44 +01:00
|
|
|
struct dentry *mnt = vfs_dentry_resolve(target, VFS_DENTRY_RESOLVE_FLAG_FULL_PATH);
|
2020-03-28 19:52:59 +01:00
|
|
|
if (mnt == NULL) {
|
|
|
|
atomic_stop();
|
2020-01-05 09:00:43 +01:00
|
|
|
return (-1);
|
2020-03-28 19:52:59 +01:00
|
|
|
}
|
2020-01-05 09:00:43 +01:00
|
|
|
|
|
|
|
// Check directory validity
|
2020-03-28 19:52:59 +01:00
|
|
|
if ((mnt->mode & __S_IFDIR) == 0) {
|
|
|
|
atomic_stop();
|
2020-01-05 09:00:43 +01:00
|
|
|
return (-2);
|
2020-03-28 19:52:59 +01:00
|
|
|
}
|
2020-01-05 09:00:43 +01:00
|
|
|
|
|
|
|
// Try to mount the directory
|
|
|
|
void *inode = filesystem->filesystem_operations.mount();
|
2020-03-28 19:52:59 +01:00
|
|
|
if (inode == NULL) {
|
|
|
|
atomic_stop();
|
2020-01-05 09:00:43 +01:00
|
|
|
return (-3);
|
2020-03-28 19:52:59 +01:00
|
|
|
}
|
2020-01-05 09:00:43 +01:00
|
|
|
|
|
|
|
// Init mount point: set new FS specific primitives
|
|
|
|
// TODO: set new FS flags
|
|
|
|
mnt->mnt.inode = inode;
|
|
|
|
mnt->mnt.file_op = &filesystem->file_operations;
|
|
|
|
mnt->mnt.inode_op = &filesystem->inode_operations;
|
2020-03-28 19:52:59 +01:00
|
|
|
atomic_stop();
|
2020-01-05 09:00:43 +01:00
|
|
|
return (0);
|
|
|
|
}
|