From 8bc9542f9dadb9a99f92c20af3291a048e3a75fd Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Wed, 21 Aug 2024 11:58:32 -0400 Subject: kernel: vfs: Add sys_close() Signed-off-by: Ian Moffett --- sys/include/sys/syscall.h | 1 + sys/include/sys/vfs.h | 1 + sys/kern/kern_syscall.c | 1 + sys/kern/vfs_syscalls.c | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 38 insertions(+) diff --git a/sys/include/sys/syscall.h b/sys/include/sys/syscall.h index 9aa96e7..4df3825 100644 --- a/sys/include/sys/syscall.h +++ b/sys/include/sys/syscall.h @@ -39,6 +39,7 @@ #define SYS_exit 1 #define SYS_open 2 #define SYS_read 3 +#define SYS_close 4 #if defined(_KERNEL) /* Syscall return value and arg type */ diff --git a/sys/include/sys/vfs.h b/sys/include/sys/vfs.h index 52d35f3..776ee66 100644 --- a/sys/include/sys/vfs.h +++ b/sys/include/sys/vfs.h @@ -36,6 +36,7 @@ #if defined(_KERNEL) scret_t sys_open(struct syscall_args *scargs); +scret_t sys_close(struct syscall_args *args); scret_t sys_read(struct syscall_args *scargs); #endif /* _KERNEL */ diff --git a/sys/kern/kern_syscall.c b/sys/kern/kern_syscall.c index 416a8ec..b36c6af 100644 --- a/sys/kern/kern_syscall.c +++ b/sys/kern/kern_syscall.c @@ -37,6 +37,7 @@ scret_t(*g_sctab[])(struct syscall_args *) = { sys_exit, /* SYS_exit */ sys_open, /* SYS_open */ sys_read, /* SYS_read */ + sys_close, /* SYS_close */ }; const size_t MAX_SYSCALLS = NELEM(g_sctab); diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 937ae87..77070ab 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -139,6 +140,40 @@ sys_open(struct syscall_args *scargs) return filedes->fdno; } +/* + * arg0: fd + */ +scret_t +sys_close(struct syscall_args *args) +{ + struct filedesc *filedes; + struct proc *td; + int fd = args->arg0; + + if ((filedes = fd_get(fd)) == NULL) { + return -EBADF; + } + + /* Return if other threads still hold a ref */ + if (atomic_dec_int(&filedes->refcnt) > 0) { + return 0; + } + + td = this_td(); + + /* + * Each file descriptor structure references a vnode, + * we want to reclaim it or at the very least drop + * one of its references. After we've cleaned up within + * the file descriptor, we can clear it from the fd table + * and free up the memory for it. + */ + vfs_release_vnode(filedes->vp); + td->fds[fd] = NULL; + dynfree(filedes); + return 0; +} + /* * arg0: fd * arg1: buf -- cgit v1.2.3