A better set of functions for struct ofile

This commit is contained in:
Mark
2020-07-05 17:41:12 +03:00
parent 061d514beb
commit eae186bbf2
10 changed files with 78 additions and 63 deletions
+1
View File
@@ -78,6 +78,7 @@ OBJS+=$(O)/fs/vfs.o \
$(O)/fs/vfs_ops.o \
$(O)/fs/vfs_access.o \
$(O)/fs/fs_class.o \
$(O)/fs/ofile.o \
$(O)/fs/node.o \
$(O)/fs/tar.o \
$(O)/fs/sysfs.o \
+45
View File
@@ -0,0 +1,45 @@
#include "sys/mem/slab.h"
#include "sys/assert.h"
#include "fs/ofile.h"
#include "fs/vfs.h"
static struct slab_cache *ofile_cache = NULL;
struct ofile *ofile_create(void) {
struct ofile *of;
if (!ofile_cache) {
ofile_cache = slab_cache_get(sizeof(struct ofile));
}
// Also sets refcount to zero
of = slab_calloc(ofile_cache);
_assert(of);
return of;
}
void ofile_destroy(struct ofile *of) {
_assert(!of->refcount);
slab_free(ofile_cache, of);
}
void ofile_close(struct vfs_ioctx *ioctx, struct ofile *of) {
// An ofile should be open before closing
_assert(of->refcount > 0);
--of->refcount;
if (of->refcount == 0) {
if (of->flags & OF_SOCKET) {
//net_close(&thr->ioctx, thr->fds[fd]);
} else {
vfs_close(ioctx, of);
}
ofile_destroy(of);
}
}
struct ofile *ofile_dup(struct ofile *of) {
_assert(of);
_assert(of->refcount >= 0);
++of->refcount;
return of;
}
+2 -8
View File
@@ -75,7 +75,6 @@ static int vfs_opendir(struct vfs_ioctx *ctx, struct ofile *fd) {
fd->flags |= OF_MEMDIR | OF_MEMDIR_DOT;
fd->file.pos = (size_t) node->first_child;
++fd->file.refcount;
++node->open_count;
return 0;
@@ -89,7 +88,6 @@ static int vfs_opendir(struct vfs_ioctx *ctx, struct ofile *fd) {
return res;
}
++fd->file.refcount;
++node->open_count;
return 0;
@@ -196,7 +194,6 @@ int vfs_open_vnode(struct vfs_ioctx *ctx, struct ofile *fd, struct vnode *node,
return -EACCES;
}
fd->file.refcount = 0;
fd->file.pos = 0;
fd->file.vnode = node;
fd->flags = OF_DIRECTORY | OF_READABLE;
@@ -228,7 +225,6 @@ int vfs_open_vnode(struct vfs_ioctx *ctx, struct ofile *fd, struct vnode *node,
}
}
fd->file.refcount = 0;
fd->file.pos = 0;
fd->file.vnode = node;
fd->flags = 0;
@@ -253,7 +249,6 @@ int vfs_open_vnode(struct vfs_ioctx *ctx, struct ofile *fd, struct vnode *node,
}
}
++fd->file.refcount;
++fd->file.vnode->open_count;
return 0;
@@ -479,13 +474,12 @@ void vfs_close(struct vfs_ioctx *ctx, struct ofile *fd) {
_assert(ctx);
_assert(fd);
_assert(!(fd->flags & OF_SOCKET));
_assert(!(fd->refcount));
_assert(fd->file.vnode);
_assert(fd->file.refcount > 0);
--fd->file.vnode->open_count;
--fd->file.refcount;
if (!fd->file.refcount && fd->file.vnode->op && fd->file.vnode->op->close) {
if (fd->file.vnode->op && fd->file.vnode->op->close) {
fd->file.vnode->op->close(fd);
}
}
+8 -1
View File
@@ -11,11 +11,13 @@
#define OF_MEMDIR_DOTDOT (1 << 5)
#define OF_SOCKET (1 << 6)
struct vfs_ioctx;
struct ofile {
int flags;
int refcount;
union {
struct {
int refcount;
struct vnode *vnode;
size_t pos;
void *priv_data;
@@ -23,3 +25,8 @@ struct ofile {
struct socket socket;
};
};
struct ofile *ofile_create(void);
struct ofile *ofile_dup(struct ofile *of);
void ofile_destroy(struct ofile *of);
void ofile_close(struct vfs_ioctx *ctx, struct ofile *of);
+2 -7
View File
@@ -24,11 +24,8 @@ static struct vnode_operations pipe_vnode_ops = {
};
int pipe_create(struct ofile **_read, struct ofile **_write) {
// TODO: ofile_create
struct ofile *read_end = kmalloc(sizeof(struct ofile));
_assert(read_end);
struct ofile *write_end = kmalloc(sizeof(struct ofile));
_assert(write_end);
struct ofile *read_end = ofile_create();
struct ofile *write_end = ofile_create();
struct ring *pipe_ring = kmalloc(sizeof(struct ring));
_assert(pipe_ring);
@@ -41,12 +38,10 @@ int pipe_create(struct ofile **_read, struct ofile **_write) {
read_end->flags = OF_READABLE;
read_end->file.vnode = vnode;
read_end->file.refcount = 1;
read_end->file.priv_data = pipe_ring;
write_end->flags = OF_WRITABLE;
write_end->file.vnode = vnode;
write_end->file.refcount = 1;
write_end->file.priv_data = pipe_ring;
*_read = read_end;
+7 -9
View File
@@ -31,8 +31,8 @@ static void user_init_func(void *arg) {
}
// Open STDOUT_FILENO and STDERR_FILENO
struct ofile *fd_stdout = kmalloc(sizeof(struct ofile));
struct ofile *fd_stdin = kmalloc(sizeof(struct ofile));
struct ofile *fd_stdout = ofile_create();
struct ofile *fd_stdin = ofile_create();
if ((res = dev_find(DEV_CLASS_CHAR, "tty0", &tty_dev)) != 0) {
kerror("tty0: %s\n", kstrerror(res));
@@ -49,14 +49,12 @@ static void user_init_func(void *arg) {
panic("Fail\n");
}
thread_self->fds[0] = fd_stdin;
thread_self->fds[1] = fd_stdout;
thread_self->fds[2] = fd_stdout;
// Duplicate the FD
++fd_stdout->file.refcount;
thread_self->fds[0] = ofile_dup(fd_stdin);
thread_self->fds[1] = ofile_dup(fd_stdout);
thread_self->fds[2] = ofile_dup(fd_stdout);
_assert(fd_stdin->file.refcount == 1);
_assert(fd_stdout->file.refcount == 2);
_assert(fd_stdin->refcount == 1);
_assert(fd_stdout->refcount == 2);
const char *argp[] = {
"/init", NULL
+1 -1
View File
@@ -384,7 +384,7 @@ int sys_module_unload(const char *name) {
int sys_module_load(const char *path, const char *params) {
struct vfs_ioctx kernel_ioctx = {0, 0, 0};
int res;
struct ofile fd;
struct ofile fd = {0};
struct thread *thr = thread_self;
if (thr->ioctx.uid != 0) {
+7 -18
View File
@@ -143,15 +143,16 @@ int sys_open(const char *filename, int flags, int mode) {
return -EMFILE;
}
struct ofile *ofile = kmalloc(sizeof(struct ofile));
_assert(ofile);
struct ofile *ofile = ofile_create();
if ((res = vfs_open(&thr->ioctx, ofile, filename, flags, mode)) != 0) {
kfree(ofile);
ofile_destroy(ofile);
return res;
}
thr->fds[fd] = ofile;
thr->fds[fd] = ofile_dup(ofile);
_assert(thr->fds[fd]->refcount == 1);
return fd;
}
@@ -167,16 +168,7 @@ void sys_close(int fd) {
return;
}
if (thr->fds[fd]->flags & OF_SOCKET) {
net_close(&thr->ioctx, thr->fds[fd]);
kfree(thr->fds[fd]);
} else {
vfs_close(&thr->ioctx, thr->fds[fd]);
_assert(thr->fds[fd]->file.refcount >= 0);
if (!thr->fds[fd]->file.refcount) {
kfree(thr->fds[fd]);
}
}
ofile_close(&thr->ioctx, thr->fds[fd]);
thr->fds[fd] = NULL;
}
@@ -294,10 +286,7 @@ int sys_dup2(int from, int to) {
sys_close(to);
_assert(!thr->fds[to]);
thr->fds[to] = thr->fds[from];
if (!(thr->fds[from]->flags & OF_SOCKET)) {
++thr->fds[from]->file.refcount;
}
thr->fds[to] = ofile_dup(thr->fds[from]);
return to;
}
+2 -3
View File
@@ -38,11 +38,10 @@ int sys_socket(int domain, int type, int protocol) {
return -EMFILE;
}
struct ofile *ofile = kmalloc(sizeof(struct ofile));
_assert(ofile);
struct ofile *ofile = ofile_create();
if ((res = net_open(&thr->ioctx, ofile, domain, type, protocol)) != 0) {
kfree(ofile);
ofile_destroy(ofile);
return res;
}
+3 -16
View File
@@ -80,17 +80,13 @@ static void thread_ioctx_empty(struct thread *thr) {
void thread_ioctx_fork(struct thread *dst, struct thread *src) {
thread_ioctx_empty(dst);
// TODO: increase refcount (when cwd has one)
dst->ioctx.cwd_vnode = src->ioctx.cwd_vnode;
dst->ioctx.gid = src->ioctx.gid;
dst->ioctx.uid = src->ioctx.uid;
for (int i = 0; i < THREAD_MAX_FDS; ++i) {
if (src->fds[i]) {
dst->fds[i] = src->fds[i];
if (!(dst->fds[i]->flags & OF_SOCKET)) {
++dst->fds[i]->file.refcount;
}
dst->fds[i] = ofile_dup(src->fds[i]);
}
}
}
@@ -165,16 +161,7 @@ void thread_cleanup(struct thread *thr) {
kdebug("Cleaning up %d\n", thr->pid);
for (size_t i = 0; i < THREAD_MAX_FDS; ++i) {
if (thr->fds[i]) {
if (thr->fds[i]->flags & OF_SOCKET) {
net_close(&thr->ioctx, thr->fds[i]);
} else {
vfs_close(&thr->ioctx, thr->fds[i]);
_assert(thr->fds[i]->file.refcount >= 0);
if (thr->fds[i]->file.refcount == 0) {
kfree(thr->fds[i]);
}
}
ofile_close(&thr->ioctx, thr->fds[i]);
thr->fds[i] = NULL;
}
}
@@ -569,7 +556,7 @@ static int procv_setup(struct thread *thr,
int sys_execve(const char *path, const char **argv, const char **envp) {
struct thread *thr = thread_self;
_assert(thr);
struct ofile fd;
struct ofile fd = {0};
struct stat st;
uintptr_t entry;
size_t argc;