Protect busy VfsObjs during opening and deleting

This commit is contained in:
2025-11-10 20:23:03 +01:00
parent a349154545
commit 7e3b162591
4 changed files with 73 additions and 1 deletions

View File

@ -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() };