Remove old VFS implementation
This commit is contained in:
+13
-12
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
struct ofile {
|
||||
int flags;
|
||||
vnode_t *vnode;
|
||||
struct vnode *vnode;
|
||||
size_t pos;
|
||||
// Dirent buffer
|
||||
char dirent_buf[512];
|
||||
};
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user