Merge devfs into dev.c, add stat()

This commit is contained in:
Mark
2020-01-09 15:10:22 +02:00
parent c39c4dca2a
commit 9da01f0d46
9 changed files with 141 additions and 92 deletions
-1
View File
@@ -67,7 +67,6 @@ OBJS+=$(O)/sys/debug.o \
$(O)/sys/net/arp.o \
$(O)/sys/net/in.o \
$(O)/sys/net/netdev.o \
$(O)/sys/vfs/devfs.o \
$(O)/sys/vfs/pseudo.o \
$(O)/sys/vfs/pty.o \
$(O)/sys/reboot.o
+1
View File
@@ -15,6 +15,7 @@ int sys_chdir(const char *filename);
int sys_mkdir(const char *pathname, int mode);
int sys_unlink(const char *pathname);
int sys_rmdir(const char *pathname);
int sys_stat(const char *filename, struct stat *st);
int sys_access(const char *path, int mode);
+1 -1
View File
@@ -137,7 +137,7 @@ 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 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);
+1
View File
@@ -9,6 +9,7 @@
#define SYSCALL_NR_GETCWD 79
#define SYSCALL_NR_CHDIR 80
#define SYSCALL_NR_MKDIR 83
#define SYSCALL_NR_RMDIR 84
#define SYSCALL_NR_CREAT 85
#define SYSCALL_NR_UNLINK 87
#define SYSCALL_NR_READDIR 89
+8 -1
View File
@@ -81,7 +81,14 @@ int sys_unlink(const char *pathname) {
struct thread *thr = get_cpu()->thread;
_assert(thr);
return vfs_unlink(&thr->ioctx, pathname);
return vfs_unlink(&thr->ioctx, pathname, 0);
}
int sys_rmdir(const char *pathname) {
struct thread *thr = get_cpu()->thread;
_assert(thr);
return vfs_unlink(&thr->ioctx, pathname, 1);
}
int sys_chdir(const char *filename) {
+1
View File
@@ -25,6 +25,7 @@ const void *amd64_syscall_jmp_table[256] = {
[SYSCALL_NR_UNLINK] = sys_unlink,
[SYSCALL_NR_MKDIR] = sys_mkdir,
[SYSCALL_NR_CREAT] = sys_creat,
[SYSCALL_NR_RMDIR] = sys_rmdir,
// Process
[SYSCALL_NR_EXIT] = sys_exit,
+121
View File
@@ -4,6 +4,14 @@
#include "sys/panic.h"
#include "sys/debug.h"
#include "sys/string.h"
#include "sys/fs/devfs.h"
#include "sys/fs/vfs.h"
#include "sys/string.h"
#include "sys/fs/fs.h"
#include "sys/attr.h"
#include "sys/heap.h"
static struct vfs_node *devfs_root_node = NULL;
static struct dev_entry *dev_begin = NULL;
static struct dev_entry *dev_end = NULL;
@@ -81,3 +89,116 @@ void dev_entry_add(struct dev_entry *ent) {
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 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);
}
-84
View File
@@ -1,84 +0,0 @@
#include "sys/fs/devfs.h"
#include "sys/fs/vfs.h"
#include "sys/string.h"
#include "sys/fs/fs.h"
#include "sys/debug.h"
#include "sys/panic.h"
#include "sys/attr.h"
#include "sys/heap.h"
static int devfs_node_mapper(fs_t *devfs, struct vfs_node **root);
static struct fs_class _devfs = {
.name = "devfs",
.opt = FS_NODE_MAPPER,
.mapper = devfs_node_mapper
};
static struct vnode_operations _devfs_vnode_op = {
};
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;
}
// TODO: handle devices added post-mapper
static int devfs_node_mapper(fs_t *devfs, struct vfs_node **root) {
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;
return 0;
}
static __init void devfs_init(void) {
fs_class_register(&_devfs);
}
+8 -5
View File
@@ -1076,11 +1076,7 @@ int vfs_truncate(struct vfs_ioctx *ctx, struct ofile *of, size_t length) {
return vn->op->truncate(of, length);
}
// XXX: Linux seems to differentiate between
// unlink() and rmdir(). I think just
// passing a flag whether sys_rmdir or
// sys_unlink was called.
int vfs_unlink(struct vfs_ioctx *ctx, const char *path) {
int vfs_unlink(struct vfs_ioctx *ctx, const char *path, int is_rmdir) {
// XXX: validate this with removing mounted roots
_assert(path);
// Find the vnode to unlink
@@ -1094,6 +1090,13 @@ int vfs_unlink(struct vfs_ioctx *ctx, const char *path) {
_assert(vnode && vnode->op);
vnode_ref(vnode);
if (vnode->type != VN_DIR && is_rmdir) {
return -ENOTDIR;
}
if (vnode->type == VN_DIR && !is_rmdir) {
return -EISDIR;
}
// Get node parent
struct vfs_node *node = vnode->tree_node;
_assert(node);