Remove old VFS implementation

This commit is contained in:
Mark
2020-01-10 14:09:45 +02:00
parent f134a72dff
commit 565f67188a
19 changed files with 2087 additions and 2221 deletions
+13 -12
View File
@@ -48,13 +48,23 @@ OBJS+=$(O)/sys/debug.o \
$(O)/sys/string.o \
$(O)/sys/panic.o \
$(O)/sys/errno.o \
$(O)/sys/vfs/fs_class.o \
$(O)/sys/chr.o \
$(O)/sys/blk.o \
$(O)/sys/dev.o \
$(O)/sys/tty.o \
$(O)/sys/chr.o \
$(O)/sys/vfs/fs_class.o \
$(O)/sys/vfs/node.o \
$(O)/sys/vfs/vfs.o \
$(O)/sys/ring.o \
$(O)/sys/net/eth.o \
$(O)/sys/net/arp.o \
$(O)/sys/net/in.o \
$(O)/sys/net/netdev.o \
$(O)/sys/reboot.o \
$(O)/sys/random.o
# $(O)/sys/vfs/pseudo.o \
$(O)/sys/tty.o \
$(O)/sys/vfs/pty.o \
$(O)/sys/vfs/ext2/ext2alloc.o \
$(O)/sys/vfs/ext2/ext2blk.o \
$(O)/sys/vfs/ext2/ext2.o \
@@ -62,15 +72,6 @@ OBJS+=$(O)/sys/debug.o \
$(O)/sys/vfs/ext2/ext2vnop.o \
$(O)/sys/vfs/tar.o \
$(O)/sys/blk/ram.o \
$(O)/sys/ring.o \
$(O)/sys/net/eth.o \
$(O)/sys/net/arp.o \
$(O)/sys/net/in.o \
$(O)/sys/net/netdev.o \
$(O)/sys/vfs/pseudo.o \
$(O)/sys/vfs/pty.o \
$(O)/sys/reboot.o \
$(O)/sys/random.o
ifeq ($(VESA_ENABLE),1)
OBJS+=$(O)/sys/psf.o \
+2 -2
View File
@@ -2,7 +2,7 @@
#include "sys/types.h"
#include "sys/dev.h"
struct vfs_node;
struct vnode;
struct blkdev {
void *dev_data;
@@ -17,7 +17,7 @@ struct blkdev {
ssize_t blk_read(struct blkdev *blk, void *buf, size_t off, size_t count);
ssize_t blk_write(struct blkdev *blk, const void *buf, size_t off, size_t count);
int blk_mount_auto(struct vfs_node *at, struct blkdev *blkdev, const char *opt);
int blk_mount_auto(struct vnode *at, struct blkdev *blkdev, const char *opt);
struct blkdev *blk_by_name(const char *name);
int blk_enumerate_partitions(struct blkdev *blk);
+2 -2
View File
@@ -141,7 +141,7 @@ int ext2_free_inode(fs_t *ext2, uint32_t ino);
int ext2_alloc_inode(fs_t *ext2, uint32_t *ino);
// Implemented in ext2dir.c
int ext2_dir_add_inode(fs_t *ext2, vnode_t *dir, const char *name, uint32_t ino);
int ext2_dir_remove_inode(fs_t *ext2, vnode_t *dir, const char *name, uint32_t ino);
int ext2_dir_add_inode(fs_t *ext2, struct vnode *dir, const char *name, uint32_t ino);
int ext2_dir_remove_inode(fs_t *ext2, struct vnode *dir, const char *name, uint32_t ino);
extern struct vnode_operations ext2_vnode_ops;
+3 -3
View File
@@ -19,7 +19,7 @@ struct fs_class {
int opt;
vnode_t *(*get_root) (fs_t *fs);
struct vnode *(*get_root) (fs_t *fs);
int (*mount) (fs_t *fs, const char *opt);
int (*umount) (fs_t *fs);
int (*statvfs) (fs_t *fs, struct statvfs *st);
@@ -30,7 +30,7 @@ struct fs_class {
// one per each mount
struct fs {
// Mount details here
vnode_t *mnt_at;
struct vnode *mnt_at;
// Block device on which the filesystem resides
struct blkdev *blk;
@@ -41,7 +41,7 @@ struct fs {
struct fs_class *cls;
};
struct fs *fs_create(struct fs_class *cls, struct blkdev *blk, vnode_t *mnt_at);
struct fs *fs_create(struct fs_class *cls, struct blkdev *blk, struct vnode *mnt_at);
void fs_release(struct fs *fs);
struct fs_class *fs_class_by_name(const char *name);
int fs_class_register(struct fs_class *cls);
+29 -23
View File
@@ -8,9 +8,11 @@
#include "dirent.h"
#include "sys/stat.h"
#define NODE_MAXLEN 256
struct ofile;
struct vfs_ioctx;
typedef struct vnode vnode_t;
struct vnode;
typedef struct fs fs_t;
enum vnode_type {
@@ -18,7 +20,7 @@ enum vnode_type {
VN_DIR,
VN_BLK,
VN_CHR,
VN_LNK
// VN_LNK
};
/**
@@ -26,28 +28,28 @@ enum vnode_type {
*/
struct vnode_operations {
// File tree traversal, node instance operations
int (*find) (vnode_t *node, const char *path, vnode_t **res);
void (*destroy) (vnode_t *node);
int (*find) (struct vnode *node, const char *path, struct vnode **res);
void (*destroy) (struct vnode *node);
// Symlink
int (*readlink) (vnode_t *node, char *path);
int (*symlink) (vnode_t *at, struct vfs_ioctx *ctx, const char *name, const char *dst);
// int (*readlink) (struct vnode *node, char *path);
// int (*symlink) (struct vnode *at, struct vfs_ioctx *ctx, const char *name, const char *dst);
// File entry operations
int (*access) (vnode_t *node, uid_t *uid, gid_t *gid, mode_t *mode);
int (*creat) (vnode_t *node, struct vfs_ioctx *ctx, const char *name, mode_t mode, int opt, vnode_t **res);
int (*mkdir) (vnode_t *at, const char *name, mode_t mode);
int (*unlink) (vnode_t *at, vnode_t *vn, const char *name);
int (*stat) (vnode_t *node, struct stat *st);
int (*chmod) (vnode_t *node, mode_t mode);
int (*chown) (vnode_t *node, uid_t uid, gid_t gid);
int (*access) (struct vnode *node, uid_t *uid, gid_t *gid, mode_t *mode);
int (*creat) (struct vnode *node, struct vfs_ioctx *ctx, const char *name, mode_t mode, int opt, struct vnode **res);
int (*mkdir) (struct vnode *at, const char *name, mode_t mode);
int (*unlink) (struct vnode *at, struct vnode *vn, const char *name);
int (*stat) (struct vnode *node, struct stat *st);
int (*chmod) (struct vnode *node, mode_t mode);
int (*chown) (struct vnode *node, uid_t uid, gid_t gid);
// Directory access
int (*opendir) (vnode_t *node, int opt);
int (*opendir) (struct vnode *node, int opt);
int (*readdir) (struct ofile *fd);
// File access
int (*open) (vnode_t *node, int opt);
int (*open) (struct vnode *node, int opt);
void (*close) (struct ofile *fd);
ssize_t (*read) (struct ofile *fd, void *buf, size_t count);
ssize_t (*write) (struct ofile *fd, const void *buf, size_t count);
@@ -57,24 +59,28 @@ struct vnode_operations {
struct vnode {
enum vnode_type type;
char name[NODE_MAXLEN];
struct vnode *first_child;
struct vnode *next_child;
struct vnode *parent;
uint32_t refcount;
uint64_t ino;
fs_t *fs;
// Private filesystem-specific data (like inode struct)
void *fs_data;
// Private filesystem-specific number (like inode number)
uint32_t fs_number;
/*
* (struct blkdev *) if type == VN_BLK
* (struct chrdev *) if type == VN_CHR
*/
void *dev;
void *tree_node;
struct vnode_operations *op;
};
void vnode_ref(vnode_t *vn);
void vnode_unref(vnode_t *vn);
void vnode_free(vnode_t *vn);
struct vnode *vnode_create(const char *name);
//void vnode_ref(vnode_t *vn);
//void vnode_unref(vnode_t *vn);
//void vnode_free(vnode_t *vn);
+1 -3
View File
@@ -4,8 +4,6 @@
struct ofile {
int flags;
vnode_t *vnode;
struct vnode *vnode;
size_t pos;
// Dirent buffer
char dirent_buf[512];
};
+2 -2
View File
@@ -5,8 +5,8 @@
struct pty {
int number;
vnode_t *master;
vnode_t *slave;
struct vnode *master;
struct vnode *slave;
// TODO: winsize/termios
struct chrdev dev_master;
+75 -90
View File
@@ -15,21 +15,21 @@
* with any location in the filesystem tree,
* we use this struct to keep things in order.
*/
struct vfs_node {
char name[256];
// Current vnode unless mnt, otherwise the root node of
// the mounted filesystem
vnode_t *vnode;
// Real vnode if mountpoint
vnode_t *real_vnode;
// Is 1 when node is a mountpoint
int ismount;
// Parent ref
struct vfs_node *parent;
// Linked list of children
struct vfs_node *child;
struct vfs_node *cdr;
};
//struct vfs_node {
// char name[256];
// // Current vnode unless mnt, otherwise the root node of
// // the mounted filesystem
// vnode_t *vnode;
// // Real vnode if mountpoint
// vnode_t *real_vnode;
// // Is 1 when node is a mountpoint
// int ismount;
// // Parent ref
// struct vfs_node *parent;
// // Linked list of children
// struct vfs_node *child;
// struct vfs_node *cdr;
//};
/**
* @brief Process-specific I/O context details
@@ -38,7 +38,7 @@ struct vfs_node {
*/
struct vfs_ioctx {
// Process' current working directory
vnode_t *cwd_vnode;
struct vnode *cwd_vnode;
uid_t uid;
gid_t gid;
};
@@ -74,78 +74,63 @@ void vfs_dump_tree(void);
* @param path The result path
* @param vn vnode
*/
void vfs_vnode_path(char *path, vnode_t *vn);
void vfs_vnode_path(char *path, struct vnode *vn);
// Tree node ops
/**
* @brief Free internal VFS node struct
* @param n Tree node
*/
void vfs_node_free(struct vfs_node *n);
/**
* @brief Allocate a new node and associate it with
* a vnode
* @param name Name to be given to the tree node
* @param vn The vnode to bind it to
* @return Non-NULL (struct vfs_node *) on success, NULL otherwise
*/
struct vfs_node *vfs_node_create(const char *name, vnode_t *vn);
int vfs_mount_internal(struct vfs_node *at, void *blkdev, const char *fs_name, const char *opt);
/**
* @brief Create a mountpoint in a filesystem tree so that
* a "source" directory actually refers to the root
* node of a "target" filesystem.
* @param ctx I/O context
* @param at Path to create mountpoint at
* @param blk Block device on which a filesystem shall be mounted
* @param fs_name Filesystem name
* @param fs_opt Filesystem mounting options
* @return 0 on success,
* -EACCES if the caller context's UID is not zero,
* -EBUSY if trying to create a mountpoint at a
* directory which is not empty,
* -ENOENT if the directory does not exist
*/
int vfs_mount(struct vfs_ioctx *ctx, const char *at, void *blk, const char *fs_name, const char *fs_opt);
/**
* @brief Destroy a mountpoint in a filesystem tree
* @param ctx I/O context
* @param target Path to unmount
* @return 0 on success,
* -EBUSY if there are any used filesystem objects inside
* the mountpoint,
* -EACCES if the caller context's UID is not zero,
* -ENOENT if the directory does not exist
*/
int vfs_umount(struct vfs_ioctx *ctx, const char *target);
/**
* @brief Read symlink's destination path into a buffer
* @param ctx I/O context
* @param path
*/
int vfs_readlink(struct vfs_ioctx *ctx, const char *path, char *buf);
int vfs_readlinkat(struct vfs_ioctx *ctx, vnode_t *at, const char *path, char *buf);
int vfs_symlink(struct vfs_ioctx *ctx, const char *target, const char *linkpath);
// File ops
int vfs_truncate(struct vfs_ioctx *ctx, struct ofile *fd, size_t length);
int vfs_creat(struct vfs_ioctx *ctx, struct ofile *fd, const char *path, int mode, int opt);
int vfs_open(struct vfs_ioctx *ctx, struct ofile *fd, const char *path, int mode, int opt);
int vfs_open_node(struct vfs_ioctx *ctx, struct ofile *fd, vnode_t *vn, int opt);
void vfs_close(struct vfs_ioctx *ctx, struct ofile *fd);
ssize_t vfs_read(struct vfs_ioctx *ctx, struct ofile *fd, void *buf, size_t count);
ssize_t vfs_write(struct vfs_ioctx *ctx, struct ofile *fd, const void *buf, size_t count);
int vfs_unlink(struct vfs_ioctx *ctx, const char *path, int is_rmdir);
int vfs_stat(struct vfs_ioctx *ctx, const char *path, struct stat *st);
int vfs_statat(struct vfs_ioctx *ctx, vnode_t *at, const char *path, struct stat *st);
int vfs_chmod(struct vfs_ioctx *ctx, const char *path, mode_t mode);
int vfs_chown(struct vfs_ioctx *ctx, const char *path, uid_t uid, gid_t gid);
int vfs_access(struct vfs_ioctx *ctx, const char *path, int mode);
// Directroy ops
int vfs_mkdir(struct vfs_ioctx *ctx, const char *path, mode_t mode);
struct dirent *vfs_readdir(struct vfs_ioctx *ctx, struct ofile *fd);
int vfs_statvfs(struct vfs_ioctx *ctx, const char *path, struct statvfs *st);
//int vfs_mount_internal(struct vfs_node *at, void *blkdev, const char *fs_name, const char *opt);
////**
// * @brief Create a mountpoint in a filesystem tree so that
// * a "source" directory actually refers to the root
// * node of a "target" filesystem.
// * @param ctx I/O context
// * @param at Path to create mountpoint at
// * @param blk Block device on which a filesystem shall be mounted
// * @param fs_name Filesystem name
// * @param fs_opt Filesystem mounting options
// * @return 0 on success,
// * -EACCES if the caller context's UID is not zero,
// * -EBUSY if trying to create a mountpoint at a
// * directory which is not empty,
// * -ENOENT if the directory does not exist
// */
//int vfs_mount(struct vfs_ioctx *ctx, const char *at, void *blk, const char *fs_name, const char *fs_opt);
///**
// * @brief Destroy a mountpoint in a filesystem tree
// * @param ctx I/O context
// * @param target Path to unmount
// * @return 0 on success,
// * -EBUSY if there are any used filesystem objects inside
// * the mountpoint,
// * -EACCES if the caller context's UID is not zero,
// * -ENOENT if the directory does not exist
// */
//int vfs_umount(struct vfs_ioctx *ctx, const char *target);
//
///**
// * @brief Read symlink's destination path into a buffer
// * @param ctx I/O context
// * @param path
// */
//int vfs_readlink(struct vfs_ioctx *ctx, const char *path, char *buf);
//int vfs_readlinkat(struct vfs_ioctx *ctx, vnode_t *at, const char *path, char *buf);
//int vfs_symlink(struct vfs_ioctx *ctx, const char *target, const char *linkpath);
//
//// File ops
//int vfs_truncate(struct vfs_ioctx *ctx, struct ofile *fd, size_t length);
//int vfs_creat(struct vfs_ioctx *ctx, struct ofile *fd, const char *path, int mode, int opt);
//int vfs_open(struct vfs_ioctx *ctx, struct ofile *fd, const char *path, int mode, int opt);
//int vfs_open_node(struct vfs_ioctx *ctx, struct ofile *fd, vnode_t *vn, int opt);
//void vfs_close(struct vfs_ioctx *ctx, struct ofile *fd);
//ssize_t vfs_read(struct vfs_ioctx *ctx, struct ofile *fd, void *buf, size_t count);
//ssize_t vfs_write(struct vfs_ioctx *ctx, struct ofile *fd, const void *buf, size_t count);
//int vfs_unlink(struct vfs_ioctx *ctx, const char *path, int is_rmdir);
//
//int vfs_stat(struct vfs_ioctx *ctx, const char *path, struct stat *st);
//int vfs_statat(struct vfs_ioctx *ctx, vnode_t *at, const char *path, struct stat *st);
//int vfs_chmod(struct vfs_ioctx *ctx, const char *path, mode_t mode);
//int vfs_chown(struct vfs_ioctx *ctx, const char *path, uid_t uid, gid_t gid);
//int vfs_access(struct vfs_ioctx *ctx, const char *path, int mode);
//// Directroy ops
//int vfs_mkdir(struct vfs_ioctx *ctx, const char *path, mode_t mode);
//struct dirent *vfs_readdir(struct vfs_ioctx *ctx, struct ofile *fd);
//
//int vfs_statvfs(struct vfs_ioctx *ctx, const char *path, struct statvfs *st);
+1 -1
View File
@@ -33,7 +33,7 @@ uint32_t ps2_irq_keyboard(void *ctx) {
char key_char = ps2_key_table_0[key];
if (key_char != 0) {
tty_buffer_write(0, key_char);
//tty_buffer_write(0, key_char);
}
}
+1 -1
View File
@@ -48,7 +48,7 @@ static uint32_t rs232_irq(void *ctx) {
c = '\n';
}
tty_buffer_write(0, c);
//tty_buffer_write(0, c);
}
return has_data ? IRQ_HANDLED : IRQ_UNHANDLED;
+3 -3
View File
@@ -61,11 +61,11 @@ void kernel_main(struct amd64_loader_data *data) {
pci_init();
vfs_init();
tty_init();
//tty_init();
if (data->initrd_ptr) {
// Create ram0 block device
ramblk_init(MM_VIRTUALIZE(data->initrd_ptr), data->initrd_len);
tarfs_init();
//ramblk_init(MM_VIRTUALIZE(data->initrd_ptr), data->initrd_len);
//tarfs_init();
}
// Initial random seed
+84 -84
View File
@@ -73,114 +73,114 @@ void init_func(void *arg) {
kdebug("Entering [init]\n");
// Mount rootfs if available
struct blkdev *root_blk = blk_by_name("ram0");
//struct blkdev *root_blk = blk_by_name("ram0");
struct vfs_ioctx ioctx = {0};
struct ofile fd;
struct stat st;
int res;
ext2_class_init();
//ext2_class_init();
if (root_blk) {
if ((res = vfs_mount(&ioctx, "/", root_blk, "ustar", NULL)) != 0) {
panic("mount rootfs: %s\n", kstrerror(res));
}
//if (root_blk) {
// if ((res = vfs_mount(&ioctx, "/", root_blk, "ustar", NULL)) != 0) {
// panic("mount rootfs: %s\n", kstrerror(res));
// }
// Mount devfs
if ((res = vfs_mount(&ioctx, "/dev", NULL, "devfs", NULL)) != 0) {
panic("mount devfs: %s\n", kstrerror(res));
}
// // Mount devfs
// if ((res = vfs_mount(&ioctx, "/dev", NULL, "devfs", NULL)) != 0) {
// panic("mount devfs: %s\n", kstrerror(res));
// }
// Try to mount /dev/sda1 at /mnt (don't panic on failure, though)
struct blkdev *sda1_blk = blk_by_name("sda1");
if (sda1_blk) {
kinfo("Trying to mount /dev/sda1 -> /mnt\n");
// // Try to mount /dev/sda1 at /mnt (don't panic on failure, though)
// struct blkdev *sda1_blk = blk_by_name("sda1");
// if (sda1_blk) {
// kinfo("Trying to mount /dev/sda1 -> /mnt\n");
if ((res = vfs_mount(&ioctx, "/mnt", sda1_blk, "auto", NULL)) != 0) {
kwarn("/dev/sda1: %s\n", kstrerror(res));
}
} else {
// Maybe an IDE drive?
sda1_blk = blk_by_name("hda1");
if (sda1_blk) {
kinfo("Trying to mount /dev/hda1 -> /mnt\n");
// if ((res = vfs_mount(&ioctx, "/mnt", sda1_blk, "auto", NULL)) != 0) {
// kwarn("/dev/sda1: %s\n", kstrerror(res));
// }
// } else {
// // Maybe an IDE drive?
// sda1_blk = blk_by_name("hda1");
// if (sda1_blk) {
// kinfo("Trying to mount /dev/hda1 -> /mnt\n");
if ((res = vfs_mount(&ioctx, "/mnt", sda1_blk, "auto", NULL)) != 0) {
kwarn("/dev/sda1: %s\n", kstrerror(res));
}
}
}
// if ((res = vfs_mount(&ioctx, "/mnt", sda1_blk, "auto", NULL)) != 0) {
// kwarn("/dev/sda1: %s\n", kstrerror(res));
// }
// }
// }
if ((res = vfs_stat(&ioctx, "/init", &st)) != 0) {
panic("/init: %s\n", kstrerror(res));
}
// if ((res = vfs_stat(&ioctx, "/init", &st)) != 0) {
// panic("/init: %s\n", kstrerror(res));
// }
if ((st.st_mode & S_IFMT) != S_IFREG) {
panic("/init: not a regular file\n");
}
// if ((st.st_mode & S_IFMT) != S_IFREG) {
// panic("/init: not a regular file\n");
// }
if (!(st.st_mode & 0111)) {
panic("/init: not executable\n");
}
// if (!(st.st_mode & 0111)) {
// panic("/init: not executable\n");
// }
kdebug("/init is %S\n", st.st_size);
// kdebug("/init is %S\n", st.st_size);
void *exec_buf = kmalloc(st.st_size);
size_t pos = 0;
ssize_t bread;
assert(exec_buf, "Failed to allocate buffer for reading\n");
// void *exec_buf = kmalloc(st.st_size);
// size_t pos = 0;
// ssize_t bread;
// assert(exec_buf, "Failed to allocate buffer for reading\n");
if ((res = vfs_open(&ioctx, &fd, "/init", 0, O_RDONLY)) != 0) {
panic("open(): %s\n", kstrerror(res));
}
// if ((res = vfs_open(&ioctx, &fd, "/init", 0, O_RDONLY)) != 0) {
// panic("open(): %s\n", kstrerror(res));
// }
while ((bread = vfs_read(&ioctx, &fd, (char *) exec_buf + pos, MIN(512, st.st_size - pos))) > 0) {
pos += bread;
}
// while ((bread = vfs_read(&ioctx, &fd, (char *) exec_buf + pos, MIN(512, st.st_size - pos))) > 0) {
// pos += bread;
// }
vfs_close(&ioctx, &fd);
// vfs_close(&ioctx, &fd);
kdebug("Successfully read init\n");
// kdebug("Successfully read init\n");
struct thread *init_thread = (struct thread *) kmalloc(sizeof(struct thread));
_assert(init_thread);
mm_space_t thread_space = amd64_mm_pool_alloc();
_assert(thread_space);
mm_space_clone(thread_space, mm_kernel, MM_CLONE_FLG_KERNEL);
// struct thread *init_thread = (struct thread *) kmalloc(sizeof(struct thread));
// _assert(init_thread);
// mm_space_t thread_space = amd64_mm_pool_alloc();
// _assert(thread_space);
// mm_space_clone(thread_space, mm_kernel, MM_CLONE_FLG_KERNEL);
if (thread_init(
init_thread,
thread_space,
0,
0,
0,
0,
0,
0,
NULL) < 0) {
panic("Failed to setup init task\n");
}
// if (thread_init(
// init_thread,
// thread_space,
// 0,
// 0,
// 0,
// 0,
// 0,
// 0,
// NULL) < 0) {
// panic("Failed to setup init task\n");
// }
if ((res = elf_load(init_thread, exec_buf)) < 0) {
panic("Failed to load binary: %s\n", kstrerror(res));
}
// if ((res = elf_load(init_thread, exec_buf)) < 0) {
// panic("Failed to load binary: %s\n", kstrerror(res));
// }
// Free memory
kfree(exec_buf);
// // Free memory
// kfree(exec_buf);
// FIXME: this way of opening requires devfs to be mounted at /dev, I guess
// I can just have dev_entry have a vnode for each of them (and remove
// ones used in devfs mapper)
// Set tty0 input
if ((res = vfs_open(&init_thread->ioctx, &init_thread->fds[0], "/dev/tty0", O_RDONLY, 0)) < 0) {
panic("Failed to set up tty0 for input: %s\n", kstrerror(res));
}
if ((res = vfs_open(&init_thread->ioctx, &init_thread->fds[1], "/dev/tty0", O_WRONLY, 0)) < 0) {
panic("Failed to set up tty0 for output: %s\n", kstrerror(res));
}
// // FIXME: this way of opening requires devfs to be mounted at /dev, I guess
// // I can just have dev_entry have a vnode for each of them (and remove
// // ones used in devfs mapper)
// // Set tty0 input
// if ((res = vfs_open(&init_thread->ioctx, &init_thread->fds[0], "/dev/tty0", O_RDONLY, 0)) < 0) {
// panic("Failed to set up tty0 for input: %s\n", kstrerror(res));
// }
// if ((res = vfs_open(&init_thread->ioctx, &init_thread->fds[1], "/dev/tty0", O_WRONLY, 0)) < 0) {
// panic("Failed to set up tty0 for output: %s\n", kstrerror(res));
// }
kdebug("Done\n");
sched_add(init_thread);
}
// kdebug("Done\n");
// sched_add(init_thread);
//}
while (1) {
asm volatile ("sti; hlt");
+28 -27
View File
@@ -153,7 +153,7 @@ void thread_cleanup(struct thread *t) {
// Release files
for (size_t i = 0; i < 4; ++i) {
if (t->fds[i].vnode) {
vfs_close(&t->ioctx, &t->fds[i]);
//vfs_close(&t->ioctx, &t->fds[i]);
}
}
@@ -190,32 +190,33 @@ int sys_execve(const char *filename, const char *const argv[], const char *const
ssize_t bread;
int res;
if ((res = vfs_stat(&thr->ioctx, filename, &st)) < 0) {
return res;
}
//if ((res = vfs_stat(&thr->ioctx, filename, &st)) < 0) {
// return res;
//}
if ((st.st_mode & S_IFMT) != S_IFREG) {
return -ENOEXEC;
}
//if ((st.st_mode & S_IFMT) != S_IFREG) {
// return -ENOEXEC;
//}
if (!(st.st_mode & 0111)) {
return -ENOEXEC;
}
//if (!(st.st_mode & 0111)) {
// return -ENOEXEC;
//}
file_buf = kmalloc(st.st_size);
if (!file_buf) {
return -ENOMEM;
}
//file_buf = kmalloc(st.st_size);
//if (!file_buf) {
// return -ENOMEM;
//}
if ((res = vfs_open(&thr->ioctx, &fd, filename, 0, O_RDONLY)) != 0) {
return res;
}
return -EINVAL;
//if ((res = vfs_open(&thr->ioctx, &fd, filename, 0, O_RDONLY)) != 0) {
// return res;
//}
while ((bread = vfs_read(&thr->ioctx, &fd, (char *) file_buf + pos, MIN(512, st.st_size - pos))) > 0) {
pos += bread;
}
//while ((bread = vfs_read(&thr->ioctx, &fd, (char *) file_buf + pos, MIN(512, st.st_size - pos))) > 0) {
// pos += bread;
//}
vfs_close(&thr->ioctx, &fd);
//vfs_close(&thr->ioctx, &fd);
mm_space_t space = thr->space;
@@ -355,12 +356,12 @@ int sys_fork(void) {
memset(&thr_dst->ioctx, 0, sizeof(thr_dst->ioctx));
memset(thr_dst->fds, 0, sizeof(thr_dst->fds));
if ((res = vfs_open(&thr_dst->ioctx, &thr_dst->fds[0], "/dev/tty0", O_RDONLY, 0)) < 0) {
panic("Failed to set up tty0 for input: %s\n", kstrerror(res));
}
if ((res = vfs_open(&thr_dst->ioctx, &thr_dst->fds[1], "/dev/tty0", O_WRONLY, 0)) < 0) {
panic("Failed to set up tty0 for output: %s\n", kstrerror(res));
}
//if ((res = vfs_open(&thr_dst->ioctx, &thr_dst->fds[0], "/dev/tty0", O_RDONLY, 0)) < 0) {
// panic("Failed to set up tty0 for input: %s\n", kstrerror(res));
//}
//if ((res = vfs_open(&thr_dst->ioctx, &thr_dst->fds[1], "/dev/tty0", O_WRONLY, 0)) < 0) {
// panic("Failed to set up tty0 for output: %s\n", kstrerror(res));
//}
sched_add(thr_dst);
+23 -166
View File
@@ -10,215 +10,72 @@
#include "sys/debug.h"
ssize_t sys_read(int fd, void *buf, size_t lim) {
if (fd >= 4 || fd < 0) {
return -EBADF;
}
struct thread *thr = get_cpu()->thread;
_assert(thr);
return -EINVAL;
//if (fd >= 4 || fd < 0) {
// return -EBADF;
//}
//struct thread *thr = get_cpu()->thread;
//_assert(thr);
struct ofile *of = &thr->fds[fd];
//struct ofile *of = &thr->fds[fd];
if (!of->vnode) {
return -EBADF;
}
//if (!of->vnode) {
// return -EBADF;
//}
return vfs_read(&thr->ioctx, of, buf, lim);
//return vfs_read(&thr->ioctx, of, buf, lim);
}
ssize_t sys_write(int fd, const void *buf, size_t lim) {
if (fd >= 4 || fd < 0) {
return -EBADF;
}
struct thread *thr = get_cpu()->thread;
_assert(thr);
struct ofile *of = &thr->fds[fd];
if (!of->vnode) {
return -EBADF;
}
return vfs_write(&thr->ioctx, of, buf, lim);
return -EINVAL;
}
ssize_t sys_readdir(int fd, struct dirent *ent) {
if (fd >= 4 || fd < 0) {
return -EBADF;
}
struct thread *thr = get_cpu()->thread;
_assert(thr);
struct ofile *of = &thr->fds[fd];
if (!of->vnode) {
return -EBADF;
}
struct dirent *src = vfs_readdir(&thr->ioctx, of);
if (!src) {
return -1;
}
// XXX: safe?
memcpy(ent, src, sizeof(struct dirent) + strlen(src->d_name));
return src->d_reclen;
return -EINVAL;
}
int sys_creat(const char *pathname, int mode) {
return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
return -EINVAL;
}
int sys_mkdir(const char *pathname, int mode) {
struct thread *thr = get_cpu()->thread;
_assert(thr);
return vfs_mkdir(&thr->ioctx, pathname, mode);
return -EINVAL;
}
int sys_unlink(const char *pathname) {
struct thread *thr = get_cpu()->thread;
_assert(thr);
return vfs_unlink(&thr->ioctx, pathname, 0);
return -EINVAL;
}
int sys_rmdir(const char *pathname) {
struct thread *thr = get_cpu()->thread;
_assert(thr);
return vfs_unlink(&thr->ioctx, pathname, 1);
return -EINVAL;
}
int sys_chdir(const char *filename) {
struct thread *thr = get_cpu()->thread;
_assert(thr);
_assert(filename);
return vfs_chdir(&thr->ioctx, filename);
return -EINVAL;
}
// Kinda incompatible with linux, but who cares as long as it's
// POSIX on the libc side
int sys_getcwd(char *buf, size_t lim) {
struct thread *thr = get_cpu()->thread;
_assert(thr);
_assert(buf);
char tmpbuf[512];
size_t len;
vfs_vnode_path(tmpbuf, thr->ioctx.cwd_vnode);
len = strlen(tmpbuf);
if (lim < len + 1) {
return -1;
}
strcpy(buf, tmpbuf);
return 0;
return -EINVAL;
}
int sys_open(const char *filename, int flags, int mode) {
struct thread *thr = get_cpu()->thread;
_assert(thr);
int fd = -1;
for (int i = 0; i < 4; ++i) {
if (!thr->fds[i].vnode) {
fd = i;
break;
}
}
if (fd != -1) {
struct ofile *of = &thr->fds[fd];
int res = vfs_open(&thr->ioctx, of, filename, mode, flags);
if (res != 0) {
of->vnode = NULL;
return res;
}
return fd;
} else {
return -1;
}
return -EINVAL;
}
void sys_close(int fd) {
if (fd >= 4 || fd < 0) {
return;
}
struct thread *thr = get_cpu()->thread;
_assert(thr);
struct ofile *of = &thr->fds[fd];
if (!of->vnode) {
return;
}
vfs_close(&thr->ioctx, of);
of->vnode = NULL;
}
int sys_stat(const char *filename, struct stat *st) {
struct thread *thr = get_cpu()->thread;
_assert(thr);
int res = vfs_stat(&thr->ioctx, filename, st);
return res;
return -EINVAL;
}
int sys_access(const char *path, int mode) {
struct thread *thr = get_cpu()->thread;
_assert(thr);
return vfs_access(&thr->ioctx, path, mode);
return -EINVAL;
}
int sys_openpty(int *master, int *slave) {
struct thread *thr = get_cpu()->thread;
_assert(thr);
// Find two free file descriptors
int fd_master = -1, fd_slave = -1;
int res;
for (int i = 0; i < 4; ++i) {
if (!thr->fds[i].vnode) {
if (fd_master == -1) {
fd_master = i;
continue;
}
fd_slave = i;
break;
}
}
if (fd_master == -1 || fd_slave == -1) {
return -EMFILE;
}
struct ofile *of_master = &thr->fds[fd_master];
struct ofile *of_slave = &thr->fds[fd_slave];
struct pty *pty = pty_create();
_assert(pty);
of_master->vnode = pty->master;
of_master->flags = O_RDWR;
of_master->pos = 0;
of_slave->vnode = pty->slave;
of_slave->flags = O_RDWR;
of_slave->pos = 0;
*master = fd_master;
*slave = fd_slave;
return 0;
return -EINVAL;
}
+4 -4
View File
@@ -79,12 +79,12 @@ struct blk_part {
uint64_t lba_size;
};
int blk_mount_auto(struct vfs_node *at, struct blkdev *blk, const char *opt) {
int blk_mount_auto(struct vnode *at, struct blkdev *blk, const char *opt) {
int res;
if ((res = vfs_mount_internal(at, blk, "ext2", opt)) == 0) {
return 0;
}
//if ((res = vfs_mount_internal(at, blk, "ext2", opt)) == 0) {
// return 0;
//}
return -1;
}
+111 -111
View File
@@ -90,115 +90,115 @@ struct dev_entry *dev_iter(void) {
return dev_begin;
}
static int devfs_node_mapper(fs_t *devfs, struct vfs_node **root);
static int devfs_node_stat(vnode_t *node, struct stat *st);
//static int devfs_node_mapper(fs_t *devfs, struct vfs_node **root);
//static int devfs_node_stat(vnode_t *node, struct stat *st);
static struct fs_class _devfs = {
.name = "devfs",
.opt = FS_NODE_MAPPER,
.mapper = devfs_node_mapper
};
static struct vnode_operations _devfs_vnode_op = {
.stat = devfs_node_stat
};
static int devfs_node_stat(vnode_t *node, struct stat *st) {
// TODO: device modes (permissions)
st->st_size = 0;
st->st_blocks = 0;
st->st_blksize = 0;
st->st_atime = 0;
st->st_mtime = 0;
st->st_ctime = 0;
st->st_dev = 0;
st->st_rdev = 0;
st->st_ino = 0;
st->st_nlink = 1;
st->st_uid = 0;
st->st_gid = 0;
if (node == devfs_root_node->vnode) {
st->st_mode = S_IFDIR | 0755;
} else {
struct dev_entry *ent = node->fs_data;
_assert(ent);
if (ent->dev_class == DEV_CLASS_BLOCK) {
st->st_mode = S_IFBLK | 0600;
} else {
st->st_mode = S_IFCHR | 0600;
}
}
return 0;
}
static vnode_t *devfs_create_vnode(fs_t *fs, struct vfs_node *node) {
vnode_t *res = (vnode_t *) kmalloc(sizeof(vnode_t));
res->tree_node = node;
res->fs = fs;
res->fs_data = NULL;
res->refcount = 0;
res->op = &_devfs_vnode_op;
res->type = VN_DIR;
return res;
}
static int devfs_node_mapper(fs_t *devfs, struct vfs_node **root) {
_assert(!devfs_root_node);
struct vfs_node *_root;
struct dev_entry *it;
// Make a root node
_root = (struct vfs_node *) kmalloc(sizeof(struct vfs_node));
_root->child = NULL;
_root->cdr = NULL;
_root->ismount = 0;
_root->parent = NULL;
_root->real_vnode = NULL;
_root->vnode = NULL;
// TODO: directory-categories (like "by-uuid" or something)
for (it = dev_iter(); it; it = it->cdr) {
struct vfs_node *ent_node = kmalloc(sizeof(struct vfs_node));
ent_node->child = NULL;
ent_node->ismount = 0;
ent_node->real_vnode = NULL;
strcpy(ent_node->name, it->dev_name);
// Create a vnode for device
vnode_t *ent_vnode = devfs_create_vnode(devfs, ent_node);
if (it->dev_class == DEV_CLASS_BLOCK) {
ent_vnode->type = VN_BLK;
} else if (it->dev_class == DEV_CLASS_CHAR) {
ent_vnode->type = VN_CHR;
} else {
panic("Unsupported device class\n");
}
ent_vnode->fs_data = it;
ent_vnode->dev = it->dev;
ent_node->vnode = ent_vnode;
ent_node->parent = _root;
ent_node->cdr = _root->child;
_root->child = ent_node;
}
vnode_t *vnode = devfs_create_vnode(devfs, _root);
_root->vnode = vnode;
*root = _root;
devfs_root_node = _root;
return 0;
}
static __init void devfs_init(void) {
fs_class_register(&_devfs);
}
//static struct fs_class _devfs = {
// .name = "devfs",
// .opt = FS_NODE_MAPPER,
// .mapper = devfs_node_mapper
//};
//
//static struct vnode_operations _devfs_vnode_op = {
// .stat = devfs_node_stat
//};
//
//static int devfs_node_stat(vnode_t *node, struct stat *st) {
// // TODO: device modes (permissions)
//
// st->st_size = 0;
// st->st_blocks = 0;
// st->st_blksize = 0;
//
// st->st_atime = 0;
// st->st_mtime = 0;
// st->st_ctime = 0;
//
// st->st_dev = 0;
// st->st_rdev = 0;
//
// st->st_ino = 0;
// st->st_nlink = 1;
//
// st->st_uid = 0;
// st->st_gid = 0;
//
// if (node == devfs_root_node->vnode) {
// st->st_mode = S_IFDIR | 0755;
// } else {
// struct dev_entry *ent = node->fs_data;
// _assert(ent);
// if (ent->dev_class == DEV_CLASS_BLOCK) {
// st->st_mode = S_IFBLK | 0600;
// } else {
// st->st_mode = S_IFCHR | 0600;
// }
// }
//
// return 0;
//}
//
//static vnode_t *devfs_create_vnode(fs_t *fs, struct vfs_node *node) {
// vnode_t *res = (vnode_t *) kmalloc(sizeof(vnode_t));
// res->tree_node = node;
// res->fs = fs;
// res->fs_data = NULL;
// res->refcount = 0;
// res->op = &_devfs_vnode_op;
// res->type = VN_DIR;
// return res;
//}
//
//static int devfs_node_mapper(fs_t *devfs, vnode_t **root) {
// _assert(!devfs_root_node);
// struct vfs_node *_root;
// struct dev_entry *it;
//
// // Make a root node
// _root = (struct vfs_node *) kmalloc(sizeof(struct vfs_node));
// _root->child = NULL;
// _root->cdr = NULL;
// _root->ismount = 0;
// _root->parent = NULL;
// _root->real_vnode = NULL;
// _root->vnode = NULL;
//
// // TODO: directory-categories (like "by-uuid" or something)
// for (it = dev_iter(); it; it = it->cdr) {
// struct vfs_node *ent_node = kmalloc(sizeof(struct vfs_node));
// ent_node->child = NULL;
// ent_node->ismount = 0;
// ent_node->real_vnode = NULL;
// strcpy(ent_node->name, it->dev_name);
//
// // Create a vnode for device
// vnode_t *ent_vnode = devfs_create_vnode(devfs, ent_node);
// if (it->dev_class == DEV_CLASS_BLOCK) {
// ent_vnode->type = VN_BLK;
// } else if (it->dev_class == DEV_CLASS_CHAR) {
// ent_vnode->type = VN_CHR;
// } else {
// panic("Unsupported device class\n");
// }
// ent_vnode->fs_data = it;
// ent_vnode->dev = it->dev;
//
// ent_node->vnode = ent_vnode;
//
// ent_node->parent = _root;
// ent_node->cdr = _root->child;
// _root->child = ent_node;
// }
//
// vnode_t *vnode = devfs_create_vnode(devfs, _root);
// _root->vnode = vnode;
//
// *root = _root;
// devfs_root_node = _root;
//
// return 0;
//}
//
//static __init void devfs_init(void) {
// fs_class_register(&_devfs);
//}
+1 -1
View File
@@ -9,7 +9,7 @@
static struct fs_class *fses[10] = { NULL };
static struct fs mounts[10];
struct fs *fs_create(struct fs_class *cls, struct blkdev *blk, vnode_t *at) {
struct fs *fs_create(struct fs_class *cls, struct blkdev *blk, struct vnode *at) {
for (size_t i = 0; i < 10; ++i) {
if (mounts[i].cls == NULL) {
mounts[i].cls = cls;
+127 -109
View File
@@ -7,119 +7,137 @@
#include "sys/heap.h"
#include "sys/string.h"
static void vfs_node_remove(struct vfs_node *node) {
// If node->parent == NULL, we've called this
// function on [root], which should not be possible
if (!node || !node->parent) {
return;
}
struct vnode *vnode_create(const char *name) {
struct vnode *node = (struct vnode *) kmalloc(sizeof(struct vnode));
_assert(node);
struct vfs_node *parent = node->parent;
node->parent = NULL;
node->first_child = NULL;
node->next_child = NULL;
if (parent->child == node) {
parent->child = node->cdr;
if (name) {
_assert(strlen(name) < NODE_MAXLEN);
strcpy(node->name, name);
} else {
for (struct vfs_node *it = parent->child; it; it = it->cdr) {
if (it->cdr == node) {
it->cdr = node->cdr;
break;
}
}
// TODO: handle case when for some reason node is absent in
// parent's children list
node->name[0] = 0;
}
// Decrement refcount for parent, unless it's [root]
if (parent->parent && !parent->child && !parent->vnode->refcount) {
vnode_free(parent->vnode);
}
// Just a wrapper around free()
vfs_node_free(node);
return node;
}
void vnode_free(vnode_t *vn) {
_assert(vn && vn->op);
_assert(!vn->refcount);
struct vfs_node *node = vn->tree_node;
struct vfs_node *link_node = NULL;
if (node->ismount) {
return;
}
if (vn->op->destroy) {
// This will free/release underlying fs_data
vn->op->destroy(vn);
}
if (node) {
vfs_node_remove(node);
}
memset(vn, 0, sizeof(vnode_t));
kfree(vn);
}
void vnode_ref(vnode_t *vn) {
// char buf[1024];
// vfs_vnode_path(buf, vn);
// printf("++refcount for %s\n", buf);
_assert(vn);
if (vn->type == VN_BLK || vn->type == VN_CHR) {
return;
}
_assert(vn->fs);
_assert(vn->fs->cls);
// FS_NODE_MAPPER means persistent vnodes
if (vn->fs->cls->opt & FS_NODE_MAPPER) {
return;
}
struct vfs_node *node = (struct vfs_node *) vn->tree_node;
if (node && !node->parent) {
// Don't change refcounter for root nodes
return;
}
++vn->refcount;
}
void vnode_unref(vnode_t *vn) {
_assert(vn);
if (vn->type == VN_BLK || vn->type == VN_CHR) {
return;
}
_assert(vn->fs);
_assert(vn->fs->cls);
// FS_NODE_MAPPER means persistent vnodes
if (vn->fs->cls->opt & FS_NODE_MAPPER) {
return;
}
struct vfs_node *node = (struct vfs_node *) vn->tree_node;
if (!node->parent) {
return;
}
if (vn->refcount > 0) {
--vn->refcount;
if (vn->refcount == 0) {
if (node->child) {
return;
}
// Free vnode
vnode_free(vn);
}
} else {
_assert(node->child);
kdebug("--refcount with 0 but child\n");
}
}
//static void vfs_node_remove(struct vfs_node *node) {
// // If node->parent == NULL, we've called this
// // function on [root], which should not be possible
// if (!node || !node->parent) {
// return;
// }
//
// struct vfs_node *parent = node->parent;
//
// if (parent->child == node) {
// parent->child = node->cdr;
// } else {
// for (struct vfs_node *it = parent->child; it; it = it->cdr) {
// if (it->cdr == node) {
// it->cdr = node->cdr;
// break;
// }
// }
//
// // TODO: handle case when for some reason node is absent in
// // parent's children list
// }
//
// // Decrement refcount for parent, unless it's [root]
// if (parent->parent && !parent->child && !parent->vnode->refcount) {
// vnode_free(parent->vnode);
// }
//
// // Just a wrapper around free()
// vfs_node_free(node);
//}
//
//void vnode_free(vnode_t *vn) {
// _assert(vn && vn->op);
// _assert(!vn->refcount);
// struct vfs_node *node = vn->tree_node;
// struct vfs_node *link_node = NULL;
//
// if (node->ismount) {
// return;
// }
//
// if (vn->op->destroy) {
// // This will free/release underlying fs_data
// vn->op->destroy(vn);
// }
//
// if (node) {
// vfs_node_remove(node);
// }
//
// memset(vn, 0, sizeof(vnode_t));
// kfree(vn);
//}
//
//void vnode_ref(vnode_t *vn) {
//// char buf[1024];
//// vfs_vnode_path(buf, vn);
//// printf("++refcount for %s\n", buf);
// _assert(vn);
// if (vn->type == VN_BLK || vn->type == VN_CHR) {
// return;
// }
// _assert(vn->fs);
// _assert(vn->fs->cls);
//
// // FS_NODE_MAPPER means persistent vnodes
// if (vn->fs->cls->opt & FS_NODE_MAPPER) {
// return;
// }
//
// struct vfs_node *node = (struct vfs_node *) vn->tree_node;
// if (node && !node->parent) {
// // Don't change refcounter for root nodes
// return;
// }
//
// ++vn->refcount;
//}
//
//void vnode_unref(vnode_t *vn) {
// _assert(vn);
// if (vn->type == VN_BLK || vn->type == VN_CHR) {
// return;
// }
//
// _assert(vn->fs);
// _assert(vn->fs->cls);
//
// // FS_NODE_MAPPER means persistent vnodes
// if (vn->fs->cls->opt & FS_NODE_MAPPER) {
// return;
// }
//
// struct vfs_node *node = (struct vfs_node *) vn->tree_node;
// if (!node->parent) {
// return;
// }
//
// if (vn->refcount > 0) {
// --vn->refcount;
//
// if (vn->refcount == 0) {
// if (node->child) {
// return;
// }
//
// // Free vnode
// vnode_free(vn);
// }
// } else {
// _assert(node->child);
//
// kdebug("--refcount with 0 but child\n");
// }
//}
+1577 -1577
View File
File diff suppressed because it is too large Load Diff