From 7e3b1625914464a6b37aa6c890141b4139b9d8d8 Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Mon, 10 Nov 2025 20:23:03 +0100 Subject: [PATCH] Protect busy VfsObjs during opening and deleting --- kernel/hal/hal.h | 1 + kernel/hal/util.c | 10 +++++++++ kernel/vfs/vfs.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++- kernel/vfs/vfs.h | 9 ++++++++ 4 files changed, 73 insertions(+), 1 deletion(-) diff --git a/kernel/hal/hal.h b/kernel/hal/hal.h index 9d7703d..6bb5f22 100644 --- a/kernel/hal/hal.h +++ b/kernel/hal/hal.h @@ -19,6 +19,7 @@ size_t hal_strspn(const char *s, const char *accept); char *hal_strcpy(char *dest, const char *src); char *hal_strchr(const char *s, int c); char *hal_strstr(const char *str, const char *substring); +char *hal_string_combine(char *dest, const char *src); void hal_wait(uint32_t ms); int32_t hal_randnum(void); diff --git a/kernel/hal/util.c b/kernel/hal/util.c index d069310..c86aa7f 100644 --- a/kernel/hal/util.c +++ b/kernel/hal/util.c @@ -140,3 +140,13 @@ char *hal_strstr(const char *str, const char *substring) return NULL; } + +char *hal_string_combine(char *dest, const char *src) { + size_t i, j; + for(i = 0; dest[i] != '\0'; i++); + for(j = 0; src[j] != '\0'; j++) { + dest[i+j] = src[j]; + } + dest[i+j] = '\0'; + return dest; +} diff --git a/kernel/vfs/vfs.c b/kernel/vfs/vfs.c index ca8f261..b357484 100644 --- a/kernel/vfs/vfs.c +++ b/kernel/vfs/vfs.c @@ -14,6 +14,28 @@ #include "dlmalloc/malloc.h" VfsTable VFS_TABLE; +VfsBusyObjs VFS_BUSY_VOBJS; + +#define CHECK_BUSY_VFSOBJ() \ + char *tmpbuf = dlmalloc(VFS_MOUNTPOINT_LABEL_MAX+1+VFS_PATH_MAX); \ + \ + hal_memset(tmpbuf, 0, VFS_MOUNTPOINT_LABEL_MAX+1+VFS_PATH_MAX); \ + hal_string_combine(tmpbuf, mountpoint); \ + hal_string_combine(tmpbuf, ":"); \ + hal_string_combine(tmpbuf, path); \ + \ + bool busy = false; \ + VfsObj *vobj, *vobjtmp; \ + spinlock_acquire(&VFS_BUSY_VOBJS.spinlock); \ + LL_FOREACH_SAFE(VFS_BUSY_VOBJS.vobjs, vobj, vobjtmp) { \ + if (hal_strcmp(vobj->path, tmpbuf) == 0) { \ + busy = true; \ + break; \ + } \ + } \ + spinlock_release(&VFS_BUSY_VOBJS.spinlock); \ + \ + dlfree(tmpbuf); void vfs_init_littlefs(VfsMountPoint *mp, bool format) { struct lfs_config *cfg = dlmalloc(sizeof(*cfg)); @@ -95,6 +117,12 @@ int32_t vfs_fetchdirent(char *mountpoint, const char *path, FsDirent *direntbuf, } int32_t vfs_delete(char *mountpoint, const char *path) { + CHECK_BUSY_VFSOBJ() + + if (busy) { + return E_NOTYET; + } + VfsMountPoint *mp = NULL; spinlock_acquire(&VFS_TABLE.spinlock); @@ -156,6 +184,12 @@ int32_t vfs_unmount(char *mountpoint) { } VfsObj *vfs_open(char *mountpoint, const char *path, uint32_t flags) { + CHECK_BUSY_VFSOBJ() + + if (busy) { + return NULL; + } + VfsMountPoint *mp = NULL; spinlock_acquire(&VFS_TABLE.spinlock); @@ -166,16 +200,34 @@ VfsObj *vfs_open(char *mountpoint, const char *path, uint32_t flags) { return NULL; } - return mp->open(mp, path, flags); + VfsObj *vobj1 = mp->open(mp, path, flags); + if (vobj1 == NULL) { + return NULL; + } + + hal_string_combine(vobj1->path, mountpoint); + hal_string_combine(vobj1->path, ":"); + hal_string_combine(vobj1->path, path); + + spinlock_acquire(&VFS_BUSY_VOBJS.spinlock); + LL_APPEND(VFS_BUSY_VOBJS.vobjs, vobj1); + spinlock_release(&VFS_BUSY_VOBJS.spinlock); + + return vobj1; } void vfs_close(VfsObj *vobj) { + spinlock_acquire(&VFS_BUSY_VOBJS.spinlock); + LL_REMOVE(VFS_BUSY_VOBJS.vobjs, vobj); + spinlock_release(&VFS_BUSY_VOBJS.spinlock); vobj->cleanup(vobj); } void vfs_init(void) { hal_memset(&VFS_TABLE, 0, sizeof(VFS_TABLE)); spinlock_init(&VFS_TABLE.spinlock); + hal_memset(&VFS_BUSY_VOBJS, 0, sizeof(VFS_BUSY_VOBJS)); + spinlock_init(&VFS_BUSY_VOBJS.spinlock); { RamSdInitExtra extra = { .capacity = baseimg_getsize(), .preallocbuffer = (uint8_t *)baseimg_getaddr() }; diff --git a/kernel/vfs/vfs.h b/kernel/vfs/vfs.h index 76c1753..6b6d6fa 100644 --- a/kernel/vfs/vfs.h +++ b/kernel/vfs/vfs.h @@ -30,7 +30,9 @@ enum { #define VFS_PATH_MAX 1024 typedef struct VfsObj { + struct VfsObj *next; SpinLock spinlock; + char path[VFS_MOUNTPOINT_LABEL_MAX+1+VFS_PATH_MAX]; void *extra; size_t extrasize; struct VfsMountPoint *vmp; @@ -40,6 +42,13 @@ typedef struct VfsObj { void (*cleanup)(struct VfsObj *vobj); } VfsObj; +typedef struct { + SpinLock spinlock; + VfsObj *vobjs; +} VfsBusyObjs; + +extern VfsBusyObjs VFS_BUSY_VOBJS; + typedef struct VfsMountPoint { int _hshtbstate; char label[VFS_MOUNTPOINT_LABEL_MAX];