summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordzwdz2022-08-04 23:06:57 +0200
committerdzwdz2022-08-04 23:06:57 +0200
commitce00d1677d7a419b427e7f11963eee982a55a231 (patch)
tree2662c3861226f6909b83d57ff8b6ac3b2ba5ec8d
parent26dc784103914b9d6ba36e0a96fa4b3af977626f (diff)
do some simple TODOs, organize the rest; general code maintainance
-rw-r--r--src/kernel/arch/amd64/driver/fsroot.c12
-rw-r--r--src/kernel/arch/amd64/driver/util.c16
-rw-r--r--src/kernel/arch/amd64/driver/util.h4
-rw-r--r--src/kernel/arch/amd64/driver/video.c15
-rw-r--r--src/kernel/arch/amd64/interrupts/isr_stub.s2
-rw-r--r--src/kernel/arch/amd64/paging.h2
-rw-r--r--src/kernel/arch/amd64/sysenter.s2
-rw-r--r--src/kernel/handle.c2
-rw-r--r--src/kernel/mem/alloc.c3
-rw-r--r--src/kernel/proc.c2
-rw-r--r--src/kernel/syscalls.c14
-rw-r--r--src/kernel/vfs/mount.c31
-rw-r--r--src/kernel/vfs/path.h3
-rw-r--r--src/kernel/vfs/request.c3
-rw-r--r--src/shared/include/camellia/execbuf.h2
-rw-r--r--src/shared/include/camellia/path.h3
-rw-r--r--src/user/app/find/find.c5
-rw-r--r--src/user/app/init/driver/tmpfs.c10
-rw-r--r--src/user/app/shell/builtins.c2
-rw-r--r--src/user/bootstrap/tar.c3
-rw-r--r--src/user/lib/file.c5
-rw-r--r--src/user/lib/fs/dir.c7
-rw-r--r--src/user/lib/fs/misc.c49
23 files changed, 95 insertions, 102 deletions
diff --git a/src/kernel/arch/amd64/driver/fsroot.c b/src/kernel/arch/amd64/driver/fsroot.c
index 512b7da..41fe136 100644
--- a/src/kernel/arch/amd64/driver/fsroot.c
+++ b/src/kernel/arch/amd64/driver/fsroot.c
@@ -2,6 +2,7 @@
#include <camellia/fsutil.h>
#include <kernel/arch/amd64/ata.h>
#include <kernel/arch/amd64/driver/fsroot.h>
+#include <kernel/arch/amd64/driver/util.h>
#include <kernel/mem/virt.h>
#include <kernel/panic.h>
#include <kernel/proc.h>
@@ -22,17 +23,6 @@ static bool exacteq(struct vfs_request *req, const char *str) {
return req->input.len == len && !memcmp(req->input.buf_kern, str, len);
}
-static int req_readcopy(struct vfs_request *req, const void *buf, size_t len) {
- assert(req->type == VFSOP_READ);
- fs_normslice(&req->offset, &req->output.len, len, false);
- virt_cpy_to(
- req->caller->pages, req->output.buf,
- buf + req->offset, req->output.len);
- /* read errors are ignored. TODO write docs */
- return req->output.len;
-}
-
-
static int handle(struct vfs_request *req) {
assert(req->caller);
int id = (int)(long __force)req->id;
diff --git a/src/kernel/arch/amd64/driver/util.c b/src/kernel/arch/amd64/driver/util.c
new file mode 100644
index 0000000..b03e582
--- /dev/null
+++ b/src/kernel/arch/amd64/driver/util.c
@@ -0,0 +1,16 @@
+#include <camellia/fsutil.h>
+#include <kernel/arch/amd64/driver/util.h>
+#include <kernel/mem/virt.h>
+#include <kernel/panic.h>
+#include <kernel/vfs/request.h>
+
+int req_readcopy(struct vfs_request *req, const void *buf, size_t len) {
+ if (!req->caller) return -1;
+ assert(req->type == VFSOP_READ);
+ fs_normslice(&req->offset, &req->output.len, len, false);
+ virt_cpy_to(
+ req->caller->pages, req->output.buf,
+ buf + req->offset, req->output.len);
+ /* read errors are ignored. TODO write a spec */
+ return req->output.len;
+}
diff --git a/src/kernel/arch/amd64/driver/util.h b/src/kernel/arch/amd64/driver/util.h
new file mode 100644
index 0000000..fd8d506
--- /dev/null
+++ b/src/kernel/arch/amd64/driver/util.h
@@ -0,0 +1,4 @@
+#pragma once
+
+struct vfs_request;
+int req_readcopy(struct vfs_request *req, const void *buf, size_t len);
diff --git a/src/kernel/arch/amd64/driver/video.c b/src/kernel/arch/amd64/driver/video.c
index 8ace3d4..2d1ac03 100644
--- a/src/kernel/arch/amd64/driver/video.c
+++ b/src/kernel/arch/amd64/driver/video.c
@@ -1,5 +1,6 @@
-#include <camellia/fsutil.h>
#include <camellia/errno.h>
+#include <camellia/fsutil.h>
+#include <kernel/arch/amd64/driver/util.h>
#include <kernel/arch/amd64/driver/video.h>
#include <kernel/mem/virt.h>
#include <kernel/panic.h>
@@ -12,18 +13,6 @@ enum {
H_FB,
};
-/* stolen from fsroot.c, TODO shared copy? i guess? */
-static int req_readcopy(struct vfs_request *req, const void *buf, size_t len) {
- if (!req->caller) return -1;
- assert(req->type == VFSOP_READ);
- fs_normslice(&req->offset, &req->output.len, len, false);
- virt_cpy_to(
- req->caller->pages, req->output.buf,
- buf + req->offset, req->output.len);
- /* read errors are ignored. TODO write docs */
- return req->output.len;
-}
-
static int handle(struct vfs_request *req) {
switch (req->type) {
case VFSOP_OPEN:
diff --git a/src/kernel/arch/amd64/interrupts/isr_stub.s b/src/kernel/arch/amd64/interrupts/isr_stub.s
index e45c1c1..c63bf2c 100644
--- a/src/kernel/arch/amd64/interrupts/isr_stub.s
+++ b/src/kernel/arch/amd64/interrupts/isr_stub.s
@@ -75,7 +75,7 @@ _isr_stage2:
iretq
.align 8
-// TODO overflow check
+// TODO stack overflow check
.skip 256 // seems to be enough
.global _isr_mini_stack
_isr_mini_stack:
diff --git a/src/kernel/arch/amd64/paging.h b/src/kernel/arch/amd64/paging.h
index f8de339..156c0c5 100644
--- a/src/kernel/arch/amd64/paging.h
+++ b/src/kernel/arch/amd64/paging.h
@@ -31,7 +31,7 @@ typedef union pe_generic_t {
void *as_ptr;
} pe_generic_t; // pageentry_generic
-struct pagedir { // on amd64 actually points to pml4. TODO more sensible type
+struct pagedir { /* on amd64 actually points to pml4. the name is like this for historical reasons */
pe_generic_t e[512];
} __attribute__((packed));
diff --git a/src/kernel/arch/amd64/sysenter.s b/src/kernel/arch/amd64/sysenter.s
index 1dfb422..8fa8acc 100644
--- a/src/kernel/arch/amd64/sysenter.s
+++ b/src/kernel/arch/amd64/sysenter.s
@@ -36,7 +36,7 @@ stored_rsp:
.skip 8
.global pagedir_current
-// a hack to maintain compat with the old arch api, TODO
+// TODO make into an argument of sysexit
pagedir_current:
.skip 8
diff --git a/src/kernel/handle.c b/src/kernel/handle.c
index ed7896d..3e31a12 100644
--- a/src/kernel/handle.c
+++ b/src/kernel/handle.c
@@ -39,8 +39,6 @@ void handle_close(struct handle *h) {
// TODO sanity check to check if refcount is true. handle_sanity?
- // TODO tests which would catch premature frees
- // by that i mean duplicating a handle and killing the original process
h->type = HANDLE_INVALID;
kfree(h);
}
diff --git a/src/kernel/mem/alloc.c b/src/kernel/mem/alloc.c
index e3eaf41..a6f6b6d 100644
--- a/src/kernel/mem/alloc.c
+++ b/src/kernel/mem/alloc.c
@@ -102,7 +102,8 @@ void *page_zalloc(size_t pages) {
// frees `pages` consecutive pages starting from *first
void page_free(void *first_addr, size_t pages) {
- if (first_addr < page_bitmap_start) // TODO unimplemented
+ // TODO put init's pages into the allocator
+ if (first_addr < page_bitmap_start)
return;
size_t first = (uintptr_t)(first_addr - page_bitmap_start) / PAGE_SIZE;
for (size_t i = 0; i < pages; i++) {
diff --git a/src/kernel/proc.c b/src/kernel/proc.c
index 3bf2b0d..6bc7057 100644
--- a/src/kernel/proc.c
+++ b/src/kernel/proc.c
@@ -65,7 +65,6 @@ struct process *process_fork(struct process *parent, int flags) {
parent->handled_req = NULL;
if ((flags & FORK_NEWFS) == 0 && parent->controlled) {
- // TODO would it be better to change the default to not sharing the controlled fs?
child->controlled = parent->controlled;
child->controlled->potential_handlers++;
child->controlled->refcount++;
@@ -149,7 +148,6 @@ void process_kill(struct process *p, int ret) {
p->execbuf.buf = NULL;
}
- if (p->parent)
pagedir_free(p->pages); // TODO put init's pages in the allocator
// TODO VULN unbounded recursion
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index ceba528..0ab6106 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -1,4 +1,5 @@
#include <camellia/errno.h>
+#include <camellia/execbuf.h>
#include <camellia/flags.h>
#include <camellia/syscalls.h>
#include <kernel/arch/generic.h>
@@ -32,7 +33,7 @@ long _syscall_await(void) {
{
if (iter->noreap) continue;
has_children = true;
- if (iter->state == PS_DEAD) // TODO this path used to crash, still untested
+ if (iter->state == PS_DEAD)
SYSCALL_RETURN(process_try2collect(iter));
}
@@ -276,10 +277,9 @@ long _syscall_fs_wait(char __user *buf, long max_len, struct fs_wait_response __
if (!backend) SYSCALL_RETURN(-1);
process_transition(process_current, PS_WAITS4REQUEST);
- assert(!backend->user.handler); // TODO allow multiple processes to wait on the same backend
+ if (backend->user.handler)
+ panic_unimplemented();
backend->user.handler = process_current;
- /* checking the validity of those pointers here would make
- * vfs_backend_accept simpler. TODO? */
process_current->awaited_req.buf = buf;
process_current->awaited_req.max_len = max_len;
process_current->awaited_req.res = res;
@@ -370,11 +370,11 @@ void _syscall_sleep(long ms) {
long _syscall_execbuf(void __user *ubuf, size_t len) {
if (len == 0) SYSCALL_RETURN(0);
- if (len > sizeof(uint64_t) * 6 * 4) // TODO specify max size somewhere
+ if (len > EXECBUF_MAX_LEN)
SYSCALL_RETURN(-1);
if (process_current->execbuf.buf)
- SYSCALL_RETURN(-1); /* no nesting */
- // actually TODO, nesting makes sense for infinite loops. maybe
+ SYSCALL_RETURN(-1);
+ // TODO consider supporting nesting execbufs
char *kbuf = kmalloc(len);
if (!virt_cpy_from(process_current->pages, kbuf, ubuf, len)) {
diff --git a/src/kernel/vfs/mount.c b/src/kernel/vfs/mount.c
index 77cc14b..de2d708 100644
--- a/src/kernel/vfs/mount.c
+++ b/src/kernel/vfs/mount.c
@@ -3,13 +3,25 @@
#include <kernel/vfs/mount.h>
#include <shared/mem.h>
-// TODO not the place where this should be done
static struct vfs_mount *mount_root = NULL;
struct vfs_mount *vfs_mount_seed(void) {
return mount_root;
}
+void vfs_mount_root_register(const char *path, struct vfs_backend *backend) {
+ struct vfs_mount *mount = kmalloc(sizeof *mount);
+ *mount = (struct vfs_mount){
+ .prev = mount_root,
+ .prefix = path,
+ .prefix_len = strlen(path),
+ .backend = backend,
+ .refs = 1,
+ };
+ mount_root = mount;
+}
+
+
struct vfs_mount *vfs_mount_resolve(
struct vfs_mount *top, const char *path, size_t path_len)
{
@@ -20,9 +32,8 @@ struct vfs_mount *vfs_mount_resolve(
continue;
/* ensure that there's no garbage after the match
- * recognize that e.g. /thisasdf doesn't get recognized as mounted under
- * /this */
-
+ * e.g. don't recognize /thisasdf as mounted under /this */
+
if (top->prefix_len == path_len) // can't happen if prefix == path
break;
if (path[top->prefix_len] == '/')
@@ -45,15 +56,3 @@ void vfs_mount_remref(struct vfs_mount *mnt) {
if (prev) vfs_mount_remref(prev);
}
-
-void vfs_mount_root_register(const char *path, struct vfs_backend *backend) {
- struct vfs_mount *mount = kmalloc(sizeof *mount);
- *mount = (struct vfs_mount){
- .prev = mount_root,
- .prefix = path,
- .prefix_len = strlen(path),
- .backend = backend,
- .refs = 1,
- };
- mount_root = mount;
-}
diff --git a/src/kernel/vfs/path.h b/src/kernel/vfs/path.h
index 8efa0d4..7484619 100644
--- a/src/kernel/vfs/path.h
+++ b/src/kernel/vfs/path.h
@@ -1,8 +1,7 @@
#pragma once
+#include <camellia/path.h>
#include <stddef.h>
-#define PATH_MAX 512
-
/** Reduce a path to its simplest form.
*
* @return length of the string in *out, always less than len. Negative if the path was invalid.
diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c
index d942fba..6883faa 100644
--- a/src/kernel/vfs/request.c
+++ b/src/kernel/vfs/request.c
@@ -114,7 +114,8 @@ void vfs_backend_user_accept(struct vfs_request *req) {
assert(req && req->backend && req->backend->user.handler);
handler = req->backend->user.handler;
assert(handler->state == PS_WAITS4REQUEST);
- assert(handler->handled_req == NULL);
+ if (handler->handled_req)
+ panic_unimplemented();
// the virt_cpy calls aren't present in all kernel backends
// it's a way to tell apart kernel and user backends apart
diff --git a/src/shared/include/camellia/execbuf.h b/src/shared/include/camellia/execbuf.h
index 9741f66..de7ae3b 100644
--- a/src/shared/include/camellia/execbuf.h
+++ b/src/shared/include/camellia/execbuf.h
@@ -1,6 +1,8 @@
#pragma once
/* the instruction format is bound to change, atm it's extremely inefficient */
+#define EXECBUF_MAX_LEN 4096
+
/* takes 6 arguments */
#define EXECBUF_SYSCALL 0xF0000001
/* takes 1 argument, changes %rip */
diff --git a/src/shared/include/camellia/path.h b/src/shared/include/camellia/path.h
new file mode 100644
index 0000000..ba6bccf
--- /dev/null
+++ b/src/shared/include/camellia/path.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define PATH_MAX 512
diff --git a/src/user/app/find/find.c b/src/user/app/find/find.c
index 502a190..6c5d31a 100644
--- a/src/user/app/find/find.c
+++ b/src/user/app/find/find.c
@@ -1,3 +1,4 @@
+#include <camellia/path.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -48,8 +49,8 @@ void recurse(char *path) {
}
void find(const char *path) {
- // TODO export PATH_MAX
- char *buf = malloc(4096);
+ // TODO bound checking
+ char *buf = malloc(PATH_MAX);
memcpy(buf, path, strlen(path)+1);
recurse(buf);
free(buf);
diff --git a/src/user/app/init/driver/tmpfs.c b/src/user/app/init/driver/tmpfs.c
index 5db78f1..96fdf39 100644
--- a/src/user/app/init/driver/tmpfs.c
+++ b/src/user/app/init/driver/tmpfs.c
@@ -53,11 +53,11 @@ static struct node *tmpfs_open(const char *path, struct fs_wait_response *res) {
}
void tmpfs_drv(void) {
- // TODO replace all the static allocations in drivers with mallocs
- static char buf[512];
+ const size_t buflen = 4096;
+ char *buf = malloc(buflen);
struct fs_wait_response res;
struct node *ptr;
- while (!_syscall_fs_wait(buf, sizeof buf, &res)) {
+ while (!_syscall_fs_wait(buf, buflen, &res)) {
switch (res.op) {
case VFSOP_OPEN:
ptr = tmpfs_open(buf, &res);
@@ -68,7 +68,7 @@ void tmpfs_drv(void) {
ptr = (void*)res.id;
if (ptr == &special_root) {
struct dirbuild db;
- dir_start(&db, res.offset, buf, sizeof buf);
+ dir_start(&db, res.offset, buf, buflen);
for (struct node *iter = root; iter; iter = iter->next)
dir_append(&db, iter->name);
_syscall_fs_respond(buf, dir_finish(&db), 0);
@@ -97,7 +97,7 @@ void tmpfs_drv(void) {
fs_normslice(&res.offset, &res.len, ptr->size, true);
if (res.offset + res.len >= ptr->capacity) {
- // TODO
+ // TODO expanding files
_syscall_fs_respond(NULL, -1, 0);
break;
}
diff --git a/src/user/app/shell/builtins.c b/src/user/app/shell/builtins.c
index d4de354..d409bfd 100644
--- a/src/user/app/shell/builtins.c
+++ b/src/user/app/shell/builtins.c
@@ -89,7 +89,7 @@ static void cmd_ls(int argc, char **argv) {
const size_t buflen = 4096;
char *buf = malloc(buflen);
- DEFAULT_ARGV("!stdin");
+ DEFAULT_ARGV("/");
for (int i = 1; i < argc; i++) {
char *path = (void*)argv[i];
int pathlen = strlen(path);
diff --git a/src/user/bootstrap/tar.c b/src/user/bootstrap/tar.c
index 2025ed1..150a993 100644
--- a/src/user/bootstrap/tar.c
+++ b/src/user/bootstrap/tar.c
@@ -61,7 +61,8 @@ static void tar_read(struct fs_wait_response *res, void *base, size_t base_len)
size_t meta_len;
int size;
- static char buf[BUF_SIZE]; // TODO reuse a single buffer
+ static char buf[BUF_SIZE];
+ // TODO reuse a single buffer for both tar_driver and tar_read
if (meta == root_fakemeta) type = '5'; /* see comment in tar_open() */
diff --git a/src/user/lib/file.c b/src/user/lib/file.c
index ffea99b..84242b2 100644
--- a/src/user/lib/file.c
+++ b/src/user/lib/file.c
@@ -115,7 +115,6 @@ size_t fread(void *restrict ptr, size_t size, size_t nitems, FILE *restrict f) {
return 0;
while (pos < total) {
- // TODO shouldn't repeat reads
long res = _syscall_read(f->fd, buf + pos, total - pos, f->pos);
if (res < 0) {
f->error = true;
@@ -184,7 +183,6 @@ int fseek(FILE *f, long offset, int whence) {
break;
case SEEK_END:
f->pos = -1;
- // TODO doesn't -1 put the cursor before the last byte? i need to fix up the drivers
break;
default:
errno = EINVAL;
@@ -194,7 +192,8 @@ int fseek(FILE *f, long offset, int whence) {
bool pos_neg = f->pos < 0;
f->pos += offset;
if (pos_neg && f->pos >= 0) {
- errno = ENOSYS; // TODO
+ // TODO getting the file size
+ errno = ENOSYS;
return -1;
}
f->eof = false;
diff --git a/src/user/lib/fs/dir.c b/src/user/lib/fs/dir.c
index 35028bd..802dd61 100644
--- a/src/user/lib/fs/dir.c
+++ b/src/user/lib/fs/dir.c
@@ -11,8 +11,8 @@ void dir_start(struct dirbuild *db, long offset, char *buf, size_t buflen) {
db->blen = buflen;
db->error = 0;
- if (offset < 0)
- db->error = -ENOSYS; // TODO
+ // TODO decide how negative directory offsets should be handled
+ if (offset < 0) db->error = -ENOSYS;
}
bool dir_append(struct dirbuild *db, const char *name) {
@@ -56,11 +56,12 @@ bool dir_append_from(struct dirbuild *db, handle_t h) {
}
if (ret == 0) {
// TODO no idea how much we've overread
+ // this messes up reading bind mounts of multiple directories
db->error = -ENOSYS;
return true;
}
- // TODO deduplicate
+ // TODO deduplicate entries
db->offset = 0;
db->bpos += ret;
diff --git a/src/user/lib/fs/misc.c b/src/user/lib/fs/misc.c
index e47d930..1fb5c3b 100644
--- a/src/user/lib/fs/misc.c
+++ b/src/user/lib/fs/misc.c
@@ -19,6 +19,21 @@ bool fork2_n_mount(const char *path) {
return false;
}
+static int dir_seglen(const char *path) {
+ /* in human terms:
+ * if path contains /, return its position + 1
+ * otherwise, return strlen */
+ int len = 0;
+ while (path[len]) {
+ if (path[len] == '/') {
+ len++;
+ break;
+ }
+ len++;
+ }
+ return len;
+}
+
void fs_passthru(const char *prefix) {
struct fs_wait_response res;
const size_t buf_len = 1024;
@@ -102,19 +117,7 @@ void fs_whitelist(const char **list) {
// TODO could be precomputed too
size_t len = strlen(*iter); // inefficient, whatever
if (blen < len && !memcmp(ipath, *iter, blen))
- {
- /* inject up to the next slash */
- // TODO separate out into its own function
- int ilen = 0;
- while ((*iter)[blen + ilen]) {
- if ((*iter)[blen + ilen] == '/') {
- ilen++;
- break;
- }
- ilen++;
- }
- dir_appendl(&db, (*iter) + blen, ilen);
- }
+ dir_appendl(&db, *iter + blen, dir_seglen(*iter + blen));
}
_syscall_fs_respond(buf, dir_finish(&db), 0);
break;
@@ -144,7 +147,6 @@ void fs_dir_inject(const char *path) {
struct fs_dir_handle *data;
const size_t buf_len = 1024;
char *buf = malloc(buf_len);
- int inject_len;
struct dirbuild db;
if (!buf) exit(1);
@@ -157,22 +159,10 @@ void fs_dir_inject(const char *path) {
res.len < path_len && !memcmp(path, buf, res.len))
{
/* opening a directory that we're injecting into */
-
data = malloc(sizeof *data);
data->delegate = _syscall_open(buf, res.len, res.flags);
data->inject = path + res.len;
-
- /* inject up to the next slash */
- inject_len = 0;
- while (data->inject[inject_len]) {
- if (data->inject[inject_len] == '/') {
- inject_len++; // include the slash
- break;
- }
- inject_len++;
- }
- data->inject_len = inject_len;
-
+ data->inject_len = dir_seglen(data->inject);
_syscall_fs_respond(data, 0, 0);
} else {
_syscall_fs_respond(NULL, _syscall_open(buf, res.len, res.flags), FSR_DELEGATE);
@@ -187,8 +177,9 @@ void fs_dir_inject(const char *path) {
break;
case VFSOP_READ:
- // TODO optimization - min(buf_len, res.capacity)
- dir_start(&db, res.offset, buf, buf_len);
+ if (res.capacity > buf_len)
+ res.capacity = buf_len;
+ dir_start(&db, res.offset, buf, res.capacity);
dir_appendl(&db, data->inject, data->inject_len);
if (data->delegate >= 0)
dir_append_from(&db, data->delegate);