From e0c7bad47a54d865ef6194643e2cd20f6094e507 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Fri, 6 Jan 2023 20:45:30 +0100 Subject: kernel: turn the NULLFS into an always present special handle preparing for HANDLE_PROCFS --- src/kernel/proc.c | 14 ++++++++++++-- src/kernel/syscalls.c | 12 +++++------- src/shared/include/camellia/flags.h | 4 ++++ src/user/app/shell/shell.c | 7 +++++++ 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/kernel/proc.c b/src/kernel/proc.c index 85992d5..6bc7754 100644 --- a/src/kernel/proc.c +++ b/src/kernel/proc.c @@ -287,6 +287,14 @@ handle_t process_find_free_handle(struct process *proc, handle_t start_at) { } struct handle *process_handle_get(struct process *p, handle_t id) { + if (id == HANDLE_NULLFS) { + static struct handle h = (struct handle){ + .type = HANDLE_FS_FRONT, + .backend = NULL, + .refcount = 2, + }; + return &h; + } if (id < 0 || id >= HANDLE_MAX) return NULL; return p->_handles[id]; } @@ -311,7 +319,7 @@ handle_t process_handle_dup(struct process *p, handle_t from, handle_t to) { if (to == from) return to; toh = &p->_handles[to]; - fromh = (from >= 0 && from < HANDLE_MAX) ? p->_handles[from] : NULL; + fromh = process_handle_get(p, from); if (*toh) handle_close(*toh); *toh = fromh; @@ -321,7 +329,9 @@ handle_t process_handle_dup(struct process *p, handle_t from, handle_t to) { } struct handle *process_handle_take(struct process *p, handle_t hid) { - if (hid < 0 || hid >= HANDLE_MAX) return NULL; + if (hid < 0 || hid >= HANDLE_MAX) { + return process_handle_get(p, hid); + } struct handle *h = p->_handles[hid]; p->_handles[hid] = NULL; return h; diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index 88e98c6..2ace0f4 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -145,13 +145,11 @@ long _syscall_mount(handle_t hid, const char __user *path, long len) { len--; } - if (hid >= 0) { // mounting a real backend? - struct handle *handle = process_handle_get(process_current, hid); - if (!handle || handle->type != HANDLE_FS_FRONT) - goto fail; - backend = handle->backend; - backend->refcount++; - } // otherwise backend == NULL + struct handle *handle = process_handle_get(process_current, hid); + if (!handle || handle->type != HANDLE_FS_FRONT) + goto fail; + backend = handle->backend; + if (backend) backend->refcount++; // append to mount list // TODO move to kernel/vfs/mount.c diff --git a/src/shared/include/camellia/flags.h b/src/shared/include/camellia/flags.h index b7cc42d..632ac3e 100644 --- a/src/shared/include/camellia/flags.h +++ b/src/shared/include/camellia/flags.h @@ -27,3 +27,7 @@ * The idea is that if all flags which allow modifying the filesystem state require * OPEN_WRITE to be set, filesystem handlers could just check for the OPEN_WRITE flag. */ #define OPEN_CREATE 4 + + +/* special handles */ +#define HANDLE_NULLFS -2 diff --git a/src/user/app/shell/shell.c b/src/user/app/shell/shell.c index 909d625..8aa640b 100644 --- a/src/user/app/shell/shell.c +++ b/src/user/app/shell/shell.c @@ -46,6 +46,13 @@ void run_args(int argc, char **argv, struct redir *redir) { exit(1); } return; + } else if (!strcmp(argv[0], "shadow")) { + if (argc < 2) { + fprintf(stderr, "shadow: missing path\n"); + } else { + _syscall_mount(HANDLE_NULLFS, argv[1], strlen(argv[1])); + } + return; } else if (!strcmp(argv[0], "cd")) { if (chdir(argc > 1 ? argv[1] : "/") < 0) perror("cd"); -- cgit v1.2.3