diff options
author | Anton Kling <anton@kling.gg> | 2024-04-02 12:03:52 +0200 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-04-02 12:03:52 +0200 |
commit | e25a47fcc4db09ab9b845a691297da67243e6049 (patch) | |
tree | dfb7c473e001fa93a1a8018c36992a5bc77ae5c3 | |
parent | 2229fd91f7230ae7068814ae029b733945852eb1 (diff) |
Kernel: Use "struct list" to handle file descriptors instead of a fixed sized array
-rw-r--r-- | kernel/drivers/mouse.c | 2 | ||||
-rw-r--r-- | kernel/fs/ext2.c | 6 | ||||
-rw-r--r-- | kernel/fs/fifo.c | 8 | ||||
-rw-r--r-- | kernel/fs/tmpfs.c | 17 | ||||
-rw-r--r-- | kernel/fs/vfs.c | 43 | ||||
-rw-r--r-- | kernel/lib/list.c | 21 | ||||
-rw-r--r-- | kernel/lib/list.h | 2 | ||||
-rw-r--r-- | kernel/sched/scheduler.c | 45 | ||||
-rw-r--r-- | kernel/sched/scheduler.h | 4 | ||||
-rw-r--r-- | kernel/socket.c | 16 |
10 files changed, 84 insertions, 80 deletions
diff --git a/kernel/drivers/mouse.c b/kernel/drivers/mouse.c index 7096ae9..87a4955 100644 --- a/kernel/drivers/mouse.c +++ b/kernel/drivers/mouse.c @@ -43,7 +43,7 @@ void add_mouse(void) { // Don't look at this int fd = vfs_open("/dev/mouse", O_RDWR, 0); mouse_fd = get_vfs_fd(fd, NULL); - current_task->file_descriptors[fd] = NULL; + list_set(¤t_task->file_descriptors, fd, NULL); } void what(registers_t *r) { 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(¤t_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(¤t_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(¤t_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(¤t_task->file_descriptors, org_fd, (void **)&orig)) { + assert(0); + return -1; + } + if (!list_set(¤t_task->file_descriptors, new_fd, orig)) { + assert(0); + return -1; + } + orig->reference_count++; return 1; } diff --git a/kernel/lib/list.c b/kernel/lib/list.c index d189c86..c663230 100644 --- a/kernel/lib/list.c +++ b/kernel/lib/list.c @@ -17,6 +17,18 @@ void list_reset(struct list *list) { list->tail_index = -1; } +int list_clone(struct list *in, struct list *out) { + list_init(out); + for (int i = 0;; i++) { + void *output; + if (!list_get(in, i, &output)) { + break; + } + list_add(out, output, NULL); + } + return 1; +} + int list_add(struct list *list, void *entry, int *index) { if (list->tail_index + 1 >= list->capacity) { list->capacity += 25; @@ -30,6 +42,15 @@ int list_add(struct list *list, void *entry, int *index) { return 1; } +int list_set(struct list *list, int index, void *entry) { + if (index > list->tail_index) { + assert(0); + return 0; + } + list->entries[index] = entry; + return 1; +} + int list_get(const struct list *list, int index, void **out) { if (index > list->tail_index) { return 0; diff --git a/kernel/lib/list.h b/kernel/lib/list.h index b7085cd..b1f0127 100644 --- a/kernel/lib/list.h +++ b/kernel/lib/list.h @@ -9,6 +9,8 @@ struct list { int list_init(struct list *list); void list_reset(struct list *list); void list_free(struct list *list); +int list_clone(struct list *in, struct list *out); int list_add(struct list *list, void *entry, int *index); +int list_set(struct list *list, int index, void *entry); int list_get(const struct list *list, int index, void **out); #endif diff --git a/kernel/sched/scheduler.c b/kernel/sched/scheduler.c index 2fa9ad3..52e4848 100644 --- a/kernel/sched/scheduler.c +++ b/kernel/sched/scheduler.c @@ -118,6 +118,20 @@ process_t *create_process(process_t *p, u32 esp, u32 eip) { r->tcb = kcalloc(1, sizeof(struct TCB)); r->tcb->CR3 = r->cr3->physical_address; + if (p) { + list_clone(&p->file_descriptors, &r->file_descriptors); + for (int i = 0;; i++) { + vfs_fd_t *out; + if (!list_get(&p->file_descriptors, i, (void **)&out)) { + break; + } + if (out) { + out->reference_count++; + } + } + } else { + list_init(&r->file_descriptors); + } list_init(&r->read_list); list_init(&r->write_list); list_init(&r->disconnect_list); @@ -149,39 +163,9 @@ process_t *create_process(process_t *p, u32 esp, u32 eip) { strcpy(r->current_working_directory, "/"); } r->data_segment_end = (p) ? p->data_segment_end : NULL; - for (int i = 0; i < 100; i++) { - if (p) { - r->file_descriptors[i] = p->file_descriptors[i]; - if (r->file_descriptors[i]) { - r->file_descriptors[i]->reference_count++; - } - } else { - r->file_descriptors[i] = NULL; - } - } return r; } -int get_free_fd(process_t *p, int allocate) { - if (!p) { - 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; - } - if (allocate) { - vfs_fd_t *fd = p->file_descriptors[i] = kmalloc(sizeof(vfs_fd_t)); - fd->inode = kmalloc(sizeof(vfs_inode_t)); - } - return i; -} - void tasking_init(void) { current_task = ready_queue = create_process(NULL, 0, 0); current_task_TCB = current_task->tcb; @@ -216,6 +200,7 @@ void free_process(process_t *p) { list_free(&p->tcp_sockets); list_free(&p->tcp_listen); list_free(&p->event_queue); + list_free(&p->file_descriptors); kfree(p->tcb); } diff --git a/kernel/sched/scheduler.h b/kernel/sched/scheduler.h index b408f59..bdf32d4 100644 --- a/kernel/sched/scheduler.h +++ b/kernel/sched/scheduler.h @@ -62,7 +62,8 @@ struct Process { void *interrupt_handler; PageDirectory *cr3; struct IpcMailbox ipc_mailbox; - vfs_fd_t *file_descriptors[100]; + + struct list file_descriptors; struct list read_list; struct list write_list; @@ -97,7 +98,6 @@ struct Process { }; bool get_task_from_pid(u32 pid, process_t **out); -int get_free_fd(process_t *p, int allocate); void free_process(process_t *p); void *get_free_virtual_memory(size_t length); #endif diff --git a/kernel/socket.c b/kernel/socket.c index 4017ca1..589d99a 100644 --- a/kernel/socket.c +++ b/kernel/socket.c @@ -239,7 +239,7 @@ int uds_open(const char *path) { fifo_object_write((u8 *)&c, 1, 0, s->fifo_file); s->ptr_socket_fd->inode->has_data = 1; - s->incoming_fd = current_task->file_descriptors[fd[1]]; + s->incoming_fd = get_vfs_fd(fd[1], NULL); // vfs_close(fd[1]); return fd[0]; } @@ -247,7 +247,9 @@ int uds_open(const char *path) { int accept(int socket, struct sockaddr *address, socklen_t *address_len) { (void)address; (void)address_len; - vfs_inode_t *inode = current_task->file_descriptors[socket]->inode; + vfs_fd_t *fd_ptr = get_vfs_fd(socket, NULL); + assert(fd_ptr); + vfs_inode_t *inode = fd_ptr->inode; SOCKET *s = (SOCKET *)inode->internal_object; if (NULL == s->incoming_fd) { @@ -259,18 +261,16 @@ int accept(int socket, struct sockaddr *address, socklen_t *address_len) { poll(fds, 1, 0); } - int n = 0; - for (; current_task->file_descriptors[n]; n++) - ; - current_task->file_descriptors[n] = s->incoming_fd; - current_task->file_descriptors[n]->reference_count++; + int index; + assert(list_add(¤t_task->file_descriptors, s->incoming_fd, &index)); + s->incoming_fd->reference_count++; s->incoming_fd = NULL; // for (char c; 0 < vfs_pread(s->fifo_fd, &c, 1, 0);) // ; inode->has_data = 0; // s->ptr_fifo_fd->inode->has_data = 0; - return n; + return index; } int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { |