[FS] VFS and mountpoints
This commit is contained in:
parent
e3e661e7e5
commit
2fe66e4f80
20
init/init.c
20
init/init.c
@ -7,26 +7,6 @@ int main(int argc, char **argv)
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
|
||||
if(!fork())
|
||||
{
|
||||
if(!fork())
|
||||
return 200;
|
||||
return 100;
|
||||
}
|
||||
|
||||
for(int j=0; j <= 10; j++)
|
||||
{
|
||||
if(!fork())
|
||||
return j;
|
||||
}
|
||||
while(1)
|
||||
{
|
||||
int retval;
|
||||
int pid = wait(&retval);
|
||||
printf("Pid: %d exited with %d\n", pid, retval);
|
||||
}
|
||||
|
||||
|
||||
for(;;);
|
||||
return 0;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <elf.h>
|
||||
#include <syscall.h>
|
||||
#include <cpuid.h>
|
||||
#include <vfs.h>
|
||||
|
||||
int kernel_execve(process_t *p, void *image, char *argv[], char *envp[]);
|
||||
int kmain(uint64_t multiboot_magic, void *multiboot_data)
|
||||
@ -36,6 +37,16 @@ int kmain(uint64_t multiboot_magic, void *multiboot_data)
|
||||
scheduler_insert(th);
|
||||
|
||||
procmm_print_map(p1->mmap);
|
||||
fs_mount(0, "/");
|
||||
fs_mount(0, "/dev");
|
||||
fs_mount(0, "/home/user/mnt/photos");
|
||||
|
||||
|
||||
fs_namef("/");
|
||||
fs_namef("/usr/local/bin/python");
|
||||
fs_namef("/dev/tty0");
|
||||
fs_namef("/home/thomas");
|
||||
fs_namef("/home/user/mnt/photos/2016/june");
|
||||
|
||||
asm("sti");
|
||||
debug_info("BOOT COMPLETE\n");
|
||||
|
161
kernel/fs/vfs.c
Normal file
161
kernel/fs/vfs.c
Normal file
@ -0,0 +1,161 @@
|
||||
#include <vfs.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <mem.h>
|
||||
#include <string.h>
|
||||
#include <debug.h>
|
||||
|
||||
file_t *fs_get(file_t *file)
|
||||
{
|
||||
if(!file)
|
||||
file = kcalloc(1, sizeof(file_t));
|
||||
file->refs += 1;
|
||||
return file;
|
||||
}
|
||||
file_t *fs_put(file_t *file)
|
||||
{
|
||||
if(!file)
|
||||
return file;
|
||||
file->refs -= 1;
|
||||
if(!file->refs)
|
||||
{
|
||||
kfree(file);
|
||||
file = 0;
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
int fs_open(file_t *file, uint64_t flags)
|
||||
{
|
||||
if(file && file->driver && file->driver->open)
|
||||
return file->driver->open(file, flags);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fs_close(file_t *file)
|
||||
{
|
||||
if(file && file->driver && file->driver->close)
|
||||
return file->driver->close(file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t fs_read(file_t *file, void *buffer, size_t nbyte, size_t offset)
|
||||
{
|
||||
if(file && file->driver && file->driver->read)
|
||||
return file->driver->read(file, buffer, nbyte, offset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t fs_write(file_t *file, void *buffer, size_t nbyte, size_t offset)
|
||||
{
|
||||
if(file && file->driver && file->driver->write)
|
||||
return file->driver->write(file, buffer, nbyte, offset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fs_readdir(file_t *dir, dirent_t *entry, uint64_t offset)
|
||||
{
|
||||
if(dir && dir->driver && dir->driver->readdir)
|
||||
return dir->driver->readdir(dir, entry, offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
file_t *fs_finddir(file_t *dir, char *name)
|
||||
{
|
||||
dirent_t entry;
|
||||
int offset = 0;
|
||||
while(1)
|
||||
{
|
||||
int retval = fs_readdir(dir, &entry, offset++);
|
||||
if(!retval)
|
||||
break;
|
||||
if(strcmp((&entry)->name, name))
|
||||
{
|
||||
fs_put(entry.file);
|
||||
continue;
|
||||
}
|
||||
return entry.file;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void fs_mount(file_t *root, const char *path)
|
||||
{
|
||||
struct mountpoint *mp = kcalloc(1, sizeof(struct mountpoint) + strlen(path) + 1);
|
||||
mp->root = fs_get(root);
|
||||
mp->path_len = strlen(path);
|
||||
memcpy(mp->path, path, mp->path_len);
|
||||
mp->path[mp->path_len] = '\0';
|
||||
LIST_APPEND(mountpoints, mp, mountpoints);
|
||||
}
|
||||
|
||||
void fs_umount(const char *path)
|
||||
{
|
||||
LIST_FOREACH(mountpoints, struct mountpoint, mp, mountpoints)
|
||||
{
|
||||
if(!strcmp(mp->path, path))
|
||||
{
|
||||
LIST_REMOVE(mountpoints, mp, mountpoints);
|
||||
fs_put(mp->root);
|
||||
kfree(mp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct mountpoint *fs_closest_mp(const char *path)
|
||||
{
|
||||
uint64_t best_len = 0;
|
||||
struct mountpoint *best = 0;
|
||||
LIST_FOREACH(mountpoints, struct mountpoint, mp, mountpoints)
|
||||
{
|
||||
uint64_t len = mp->path_len;
|
||||
if((!strncmp(mp->path, path, len-1)) && (len > best_len))
|
||||
{
|
||||
best = mp;
|
||||
best_len = len;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
|
||||
char *pathtok(char **p)
|
||||
{
|
||||
char sep = '/';
|
||||
|
||||
if(!**p) return 0;
|
||||
|
||||
while(**p && **p == sep) (*p)++;
|
||||
char *ret = *p;
|
||||
while(**p && **p != sep) (*p)++;
|
||||
if(**p) **p = '\0', (*p)++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
file_t *fs_namef(const char *path)
|
||||
{
|
||||
char *name;
|
||||
char *p = strdup(path);
|
||||
char *q = p;
|
||||
struct mountpoint *mp = fs_closest_mp(path);
|
||||
file_t *root = mp->root;
|
||||
p += mp->path_len;
|
||||
file_t *dir = fs_get(root);
|
||||
|
||||
while((name = pathtok(&p)))
|
||||
{
|
||||
file_t *next = fs_finddir(dir, name);
|
||||
if(!next)
|
||||
{
|
||||
dir = 0;
|
||||
goto end;
|
||||
}
|
||||
fs_put(dir);
|
||||
dir = next;
|
||||
}
|
||||
end:
|
||||
kfree(q);
|
||||
return dir;
|
||||
}
|
@ -11,3 +11,6 @@ void *memmove(void *dest, const void *src, size_t n);
|
||||
int memcmp(const void *s1, const void *s2, size_t n);
|
||||
|
||||
size_t strlen(const char *s);
|
||||
int strncmp(const char *s1, const char *s2, size_t n);
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
char *strdup(const char *s);
|
||||
|
58
kernel/include/vfs.h
Normal file
58
kernel/include/vfs.h
Normal file
@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <list.h>
|
||||
|
||||
typedef struct vfs_node_st * INODE;
|
||||
|
||||
typedef struct file_st
|
||||
{
|
||||
uint64_t refs;
|
||||
uint64_t type;
|
||||
struct fs_driver_st *driver;
|
||||
void *data;
|
||||
} file_t;
|
||||
|
||||
typedef struct dirent_st
|
||||
{
|
||||
char name[256];
|
||||
file_t *file;
|
||||
} dirent_t;
|
||||
|
||||
#define FS_FILE 0x1
|
||||
#define FS_DIR 0x2
|
||||
#define FS_PIPE 0x3
|
||||
|
||||
typedef struct fs_driver_st
|
||||
{
|
||||
int (*open)(file_t *file, uint64_t flags);
|
||||
int (*close)(file_t *file);
|
||||
size_t (*read)(file_t *file, void *buffer, size_t nbyte, size_t offset);
|
||||
size_t (*write)(file_t *file, void *buffer, size_t nbyte, size_t offset);
|
||||
int (*readdir)(file_t *dir, dirent_t *entry, uint64_t offset);
|
||||
} fs_driver_t;
|
||||
|
||||
int fs_open(file_t *file, uint64_t flags);
|
||||
int fs_close(file_t *file);
|
||||
size_t fs_read(file_t *file, void *buffer, size_t nbyte, size_t offset);
|
||||
size_t fs_write(file_t *file, void *buffer, size_t nbyte, size_t offset);
|
||||
int fs_readdir(file_t *dir, dirent_t *entry, uint64_t offset);
|
||||
|
||||
|
||||
struct mountpoint
|
||||
{
|
||||
LIST(struct mountpoint, mountpoints);
|
||||
file_t *root;
|
||||
uint64_t path_len;
|
||||
char path[];
|
||||
};
|
||||
|
||||
file_t *fs_get(file_t *file);
|
||||
file_t *fs_put(file_t *file);
|
||||
|
||||
LIST(struct mountpoint, mountpoints);
|
||||
|
||||
void fs_mount(file_t *root, const char *path);
|
||||
void fs_umount(const char *path);
|
||||
|
||||
file_t *fs_namef(const char *path);
|
@ -1,6 +1,7 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <mem.h>
|
||||
|
||||
// Standard function required by gcc
|
||||
// Just the naíve implementations for now
|
||||
@ -44,3 +45,24 @@ size_t strlen(const char *s)
|
||||
while(*s++) len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
int strncmp(const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
while(n && *s1 && (*s1==*s2))
|
||||
s1++, s2++, n--;
|
||||
return *(const unsigned char*)s1-*(const unsigned char*)s2;
|
||||
}
|
||||
|
||||
int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
while(*s1 && (*s1==*s2))
|
||||
s1++, s2++;
|
||||
return *(const unsigned char*)s1-*(const unsigned char*)s2;
|
||||
}
|
||||
|
||||
char *strdup(const char *s)
|
||||
{
|
||||
char *ret = kmalloc(strlen(s)+1);
|
||||
memcpy(ret, s, strlen(s)+1);
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user