A better set of functions for struct ofile
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user