summaryrefslogtreecommitdiff
path: root/kernel/fs
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2024-04-02 12:03:52 +0200
committerAnton Kling <anton@kling.gg>2024-04-02 12:03:52 +0200
commite25a47fcc4db09ab9b845a691297da67243e6049 (patch)
treedfb7c473e001fa93a1a8018c36992a5bc77ae5c3 /kernel/fs
parent2229fd91f7230ae7068814ae029b733945852eb1 (diff)
Kernel: Use "struct list" to handle file descriptors instead of a fixed sized array
Diffstat (limited to 'kernel/fs')
-rw-r--r--kernel/fs/ext2.c6
-rw-r--r--kernel/fs/fifo.c8
-rw-r--r--kernel/fs/tmpfs.c17
-rw-r--r--kernel/fs/vfs.c43
4 files changed, 35 insertions, 39 deletions
diff --git a/kernel/fs/ext2.c b/kernel/fs/ext2.c
index 167c2aa..e815e79 100644
--- a/kernel/fs/ext2.c
+++ b/kernel/fs/ext2.c
@@ -806,8 +806,10 @@ vfs_inode_t *ext2_mount(void) {
cache = kcalloc(3000, sizeof(struct BLOCK_CACHE));
// TODO: Can this be done better? Maybe create a seperate function in
// the VFS?
- mount_fd = current_task->file_descriptors[fd];
- current_task->file_descriptors[fd] = NULL;
+ mount_fd = get_vfs_fd(fd, NULL);
+ // Remove the FD from the current task
+ // FIXME: This is a hacky solution
+ list_set(&current_task->file_descriptors, fd, NULL);
parse_superblock();
return vfs_create_inode(
0 /*inode_num*/, 0 /*type*/, 0 /*has_data*/, 0 /*can_write*/,
diff --git a/kernel/fs/fifo.c b/kernel/fs/fifo.c
index f2ad933..a0a9248 100644
--- a/kernel/fs/fifo.c
+++ b/kernel/fs/fifo.c
@@ -1,4 +1,5 @@
#include "fifo.h"
+#include <assert.h>
#include <errno.h>
#define STARTING_SIZE 4096
@@ -63,13 +64,12 @@ FIFO_FILE *create_fifo_object(void) {
}
int create_fifo(void) {
- int fd_n = 0;
- for (; current_task->file_descriptors[fd_n]; fd_n++)
- ;
vfs_fd_t *fd = kmalloc(sizeof(vfs_fd_t));
+ int fd_n;
+ assert(list_add(&current_task->file_descriptors, fd, &fd_n));
+
fd->flags = O_RDWR | O_NONBLOCK;
- current_task->file_descriptors[fd_n] = fd;
fd->inode = kmalloc(sizeof(vfs_inode_t));
fd->inode->internal_object = (void *)create_fifo_object();
diff --git a/kernel/fs/tmpfs.c b/kernel/fs/tmpfs.c
index f8e6712..e31a08e 100644
--- a/kernel/fs/tmpfs.c
+++ b/kernel/fs/tmpfs.c
@@ -37,6 +37,7 @@ int tmp_read(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd) {
}
void dual_pipe(int fd[2]) {
+ vfs_fd_t *fd_ptrs[2];
for (int i = 0; i < 2; i++) {
tmp_inode *pipe = kmalloc(sizeof(tmp_inode));
pipe->fifo = create_fifo_object();
@@ -53,12 +54,12 @@ void dual_pipe(int fd[2]) {
NULL /*send_signal*/);
assert(inode);
- vfs_fd_t *fd_ptr;
- fd[i] = vfs_create_fd(O_RDWR | O_NONBLOCK, 0, 0 /*is_tty*/, inode, &fd_ptr);
+ fd[i] =
+ vfs_create_fd(O_RDWR | O_NONBLOCK, 0, 0 /*is_tty*/, inode, &fd_ptrs[i]);
assert(-1 != fd[i]);
}
- vfs_inode_t *f_inode = current_task->file_descriptors[fd[0]]->inode;
- vfs_inode_t *s_inode = current_task->file_descriptors[fd[1]]->inode;
+ vfs_inode_t *f_inode = fd_ptrs[0]->inode;
+ vfs_inode_t *s_inode = fd_ptrs[1]->inode;
tmp_inode *f_pipe = f_inode->internal_object;
tmp_inode *s_pipe = s_inode->internal_object;
f_pipe->read_inode = s_inode;
@@ -68,6 +69,7 @@ void dual_pipe(int fd[2]) {
}
void pipe(int fd[2]) {
+ vfs_fd_t *fd_ptrs[2];
for (int i = 0; i < 2; i++) {
tmp_inode *pipe = kmalloc(sizeof(tmp_inode));
pipe->fifo = create_fifo_object();
@@ -84,12 +86,11 @@ void pipe(int fd[2]) {
NULL /*send_signal*/);
assert(inode);
- vfs_fd_t *fd_ptr;
- fd[i] = vfs_create_fd(O_RDWR, 0, 0 /*is_tty*/, inode, &fd_ptr);
+ fd[i] = vfs_create_fd(O_RDWR, 0, 0 /*is_tty*/, inode, &fd_ptrs[i]);
assert(-1 != fd[i]);
}
- vfs_inode_t *f_inode = current_task->file_descriptors[fd[0]]->inode;
- vfs_inode_t *s_inode = current_task->file_descriptors[fd[1]]->inode;
+ vfs_inode_t *f_inode = fd_ptrs[0]->inode;
+ vfs_inode_t *s_inode = fd_ptrs[1]->inode;
tmp_inode *f_pipe = f_inode->internal_object;
tmp_inode *s_pipe = s_inode->internal_object;
f_pipe->read_inode = s_inode;
diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c
index c167e8f..bff0cb6 100644
--- a/kernel/fs/vfs.c
+++ b/kernel/fs/vfs.c
@@ -12,17 +12,12 @@ vfs_fd_t *get_vfs_fd(int fd, process_t *p) {
if (!p) {
p = current_task;
}
- if (fd >= 100) {
- klog("get_vfs_fd(): Tried to get out of range fd", LOG_WARN);
- dump_backtrace(12);
- return NULL;
- }
- if (fd < 0) {
- klog("get_vfs_fd(): Tried to get out of range fd", LOG_WARN);
- dump_backtrace(12);
+
+ vfs_fd_t *r;
+ if (!list_get(&p->file_descriptors, fd, (void **)&r)) {
return NULL;
}
- return p->file_descriptors[fd];
+ return r;
}
vfs_inode_t *vfs_create_inode(
@@ -62,16 +57,6 @@ vfs_inode_t *vfs_create_inode(
int vfs_create_fd(int flags, int mode, int is_tty, vfs_inode_t *inode,
vfs_fd_t **fd) {
- process_t *p = (process_t *)current_task;
- int i;
- for (i = 0; i < 100; i++) {
- if (!p->file_descriptors[i]) {
- break;
- }
- }
- if (p->file_descriptors[i]) {
- return -1;
- }
inode->ref++;
vfs_fd_t *r = kmalloc(sizeof(vfs_fd_t));
r->flags = flags;
@@ -80,11 +65,12 @@ int vfs_create_fd(int flags, int mode, int is_tty, vfs_inode_t *inode,
r->reference_count = 1;
r->is_tty = is_tty;
r->offset = 0;
- p->file_descriptors[i] = r;
if (fd) {
*fd = r;
}
- return i;
+ int index;
+ list_add(&current_task->file_descriptors, r, &index);
+ return index;
}
int vfs_create_file(const char *file) {
@@ -304,7 +290,7 @@ int vfs_close_process(process_t *p, int fd) {
assert(0 < fd_ptr->reference_count);
// Remove process reference
fd_ptr->reference_count--;
- p->file_descriptors[fd] = 0;
+ list_set(&p->file_descriptors, fd, NULL);
// If no references left then free the contents
if (0 == fd_ptr->reference_count) {
if (fd_ptr->inode->close) {
@@ -417,9 +403,16 @@ vfs_vm_object_t *vfs_get_vm_object(int fd, u64 length, u64 offset) {
}
int vfs_dup2(int org_fd, int new_fd) {
- current_task->file_descriptors[new_fd] =
- current_task->file_descriptors[org_fd];
- current_task->file_descriptors[new_fd]->reference_count++;
+ vfs_fd_t *orig;
+ if (!list_get(&current_task->file_descriptors, org_fd, (void **)&orig)) {
+ assert(0);
+ return -1;
+ }
+ if (!list_set(&current_task->file_descriptors, new_fd, orig)) {
+ assert(0);
+ return -1;
+ }
+ orig->reference_count++;
return 1;
}