Redesign the VFS

This commit is contained in:
2025-09-03 17:32:08 +02:00
parent 8a12f23b69
commit afa4d383e0
7 changed files with 161 additions and 382 deletions

View File

@ -8,7 +8,6 @@
#include "hshtb.h"
#include "assert.h"
#include "errors.h"
#include "fs/kvfs/kvfs.h"
#include "fs/portlfs/portlfs.h"
#include "storedev/storedev.h"
#include "baseimg/baseimg.h"
@ -16,16 +15,6 @@
VfsTable VFS_TABLE;
void vfs_init_kvfs(VfsMountPoint *mp) {
mp->read = &kvfs_read;
mp->stat = &kvfs_stat;
mp->write = &kvfs_write;
mp->remove = &kvfs_remove;
mp->check = &kvfs_check;
mp->cleanup = &kvfs_cleanup;
mp->create = &kvfs_create;
}
void vfs_init_littlefs(VfsMountPoint *mp) {
struct lfs_config *cfg = dlmalloc(sizeof(*cfg));
hal_memset(cfg, 0, sizeof(*cfg));
@ -52,13 +41,8 @@ void vfs_init_littlefs(VfsMountPoint *mp) {
ERR("vfs", "Little FS mount failed\n");
}
mp->read = &littlefs_read;
mp->stat = &littlefs_stat;
mp->write = &littlefs_write;
mp->remove = &littlefs_remove;
mp->check = &littlefs_check;
mp->cleanup = &littlefs_cleanup;
mp->create = &littlefs_create;
mp->open = &littlefs_open;
}
int32_t vfs_mount(char *mountpoint, int32_t fstype, StoreDev *backingsd) {
@ -76,9 +60,6 @@ int32_t vfs_mount(char *mountpoint, int32_t fstype, StoreDev *backingsd) {
mp->backingsd = backingsd;
mp->fstype = fstype;
switch (fstype) {
case VFS_KVFS:
vfs_init_kvfs(mp);
break;
case VFS_LITTLEFS:
vfs_init_littlefs(mp);
break;
@ -111,7 +92,7 @@ int32_t vfs_unmount(char *mountpoint) {
return E_OK;
}
int32_t vfs_read(char *mountpoint, const char *path, uint8_t *const buffer, size_t n, size_t off) {
VfsObj *vfs_open(char *mountpoint, const char *path, uint32_t flags) {
VfsMountPoint *mp = NULL;
spinlock_acquire(&VFS_TABLE.spinlock);
@ -119,92 +100,33 @@ int32_t vfs_read(char *mountpoint, const char *path, uint8_t *const buffer, size
spinlock_release(&VFS_TABLE.spinlock);
if (mp == NULL) {
return E_NOENTRY;
return NULL;
}
return mp->read(mp, path, buffer, n, off);
return mp->open(mp, path, flags);
}
int32_t vfs_stat(char *mountpoint, const char *path, VfsStat *stat) {
VfsMountPoint *mp = NULL;
spinlock_acquire(&VFS_TABLE.spinlock);
HSHTB_GET(&VFS_TABLE, mountpoints, mountpoint, label, mp);
spinlock_release(&VFS_TABLE.spinlock);
if (mp == NULL) {
return E_NOENTRY;
void vfs_close(VfsObj *vobj) {
if (vobj->refs < 0) {
return;
}
return mp->stat(mp, path, stat);
}
int32_t vfs_create(char *mountpoint, const char *path, int32_t type) {
VfsMountPoint *mp = NULL;
spinlock_acquire(&VFS_TABLE.spinlock);
HSHTB_GET(&VFS_TABLE, mountpoints, mountpoint, label, mp);
spinlock_release(&VFS_TABLE.spinlock);
if (mp == NULL) {
return E_NOENTRY;
vobj->refs--;
if (vobj->refs == 0) {
vobj->cleanup(vobj);
}
return mp->create(mp, path, type);
}
int32_t vfs_write(char *mountpoint, const char *path, const uint8_t *const buffer, size_t n, size_t off) {
VfsMountPoint *mp = NULL;
spinlock_acquire(&VFS_TABLE.spinlock);
HSHTB_GET(&VFS_TABLE, mountpoints, mountpoint, label, mp);
spinlock_release(&VFS_TABLE.spinlock);
if (mp == NULL) {
return E_NOENTRY;
}
return mp->write(mp, path, buffer, n, off);
}
int32_t vfs_remove(char *mountpoint, const char *path) {
VfsMountPoint *mp = NULL;
spinlock_acquire(&VFS_TABLE.spinlock);
HSHTB_GET(&VFS_TABLE, mountpoints, mountpoint, label, mp);
spinlock_release(&VFS_TABLE.spinlock);
if (mp == NULL) {
return E_NOENTRY;
}
return mp->remove(mp, path);
}
int32_t tmpvars_init(void) {
RamSdInitExtra extra = { .capacity = KVFS_NODES_MAX * KVFS_BUFFER_SIZE };
StoreDev *backingsd = storedev_create(STOREDEV_RAMSD, &extra);
if (backingsd == NULL) {
return E_NOMEMORY;
}
return vfs_mount("tmpvars", VFS_KVFS, backingsd);
}
int32_t base_init(void) {
RamSdInitExtra extra = { .capacity = baseimg_getsize(), .preallocbuffer = (uint8_t*)baseimg_getaddr() };
StoreDev *backingsd = storedev_create(STOREDEV_RAMSD, &extra);
if (backingsd == NULL) {
return E_NOMEMORY;
}
return vfs_mount("base", VFS_LITTLEFS, backingsd);
}
void vfs_init(void) {
hal_memset(&VFS_TABLE, 0, sizeof(VFS_TABLE));
spinlock_init(&VFS_TABLE.spinlock);
tmpvars_init();
base_init();
RamSdInitExtra extra = { .capacity = baseimg_getsize(), .preallocbuffer = (uint8_t *)baseimg_getaddr() };
StoreDev *backingsd = storedev_create(STOREDEV_RAMSD, &extra);
if (backingsd == NULL) {
return;
}
vfs_mount("base", VFS_LITTLEFS, backingsd);
LOG("vfs", "init\n");
@ -213,16 +135,5 @@ void vfs_init(void) {
VfsMountPoint *vmp = &VFS_TABLE.mountpoints[i];
LOG("vfs", "mount point %s: %s, backing device: %s\n",
vmp->label, vfs_strings[vmp->fstype], storedev_strings[vmp->backingsd->sdtype]);
if (vmp->check != NULL) {
bool ok = vmp->check();
if (ok) {
LOG("vfs", "check = %s\n", "OK");
} else {
ERR("vfs", "check = %s\n", "FAIL");
}
} else {
LOG("vfs", "check skipped\n");
}
}
}

View File

@ -5,7 +5,6 @@
#include <stddef.h>
#include <stdbool.h>
#include "spinlock/spinlock.h"
#include "fs/kvfs/kvfs.h"
#include "fs/portlfs/portlfs.h"
#include "storedev/storedev.h"
@ -13,12 +12,10 @@
#define VFS_MOUNTPOINTS_MAX 30
enum {
VFS_KVFS,
VFS_LITTLEFS,
};
static const char *vfs_strings[] = {
"KVFS",
"Little FS",
};
@ -27,27 +24,41 @@ enum {
VFS_TYPE_FILE,
};
enum {
VFS_FLAG_READ = 1<<0,
VFS_FLAG_WRITE = 1<<1,
VFS_FLAG_MAKE = 1<<2,
};
#define VFS_PATH_MAX 1024
typedef struct VfsStat {
size_t size;
int32_t type;
} VfsStat;
typedef struct VfsObj {
SpinLock spinlock;
int32_t refs;
void *extra;
size_t extrasize;
struct VfsMountPoint *vmp;
char path[VFS_PATH_MAX];
int32_t (*read)(struct VfsObj *vobj, uint8_t *const buffer, size_t n, size_t off);
int32_t (*stat)(struct VfsObj *vobj, struct VfsStat *stat);
void (*cleanup)(struct VfsObj *vobj);
} VfsObj;
typedef struct VfsMountPoint {
bool taken;
uint8_t label[VFS_MOUNTPOINT_LABEL_MAX];
int32_t fstype;
StoreDev *backingsd;
int32_t (*read)(struct VfsMountPoint *vmp, const char *path, uint8_t *const buffer, size_t n, size_t off);
int32_t (*stat)(struct VfsMountPoint *vmp, const char *path, struct VfsStat *stat);
int32_t (*write)(struct VfsMountPoint *vmp, const char *path, const uint8_t *const buffer, size_t n, size_t off);
int32_t (*remove)(struct VfsMountPoint *vmp, const char *path);
int32_t (*create)(struct VfsMountPoint *vmp, const char *path, int32_t type);
VfsObj *(*open)(struct VfsMountPoint *vmp, const char *path, uint32_t flags);
int32_t (*cleanup)(struct VfsMountPoint *vmp);
bool (*check)(void);
union {
Kvfs kvfs;
LittleFs littlefs;
} fs;
SpinLock spinlock;
@ -61,12 +72,9 @@ typedef struct {
extern VfsTable VFS_TABLE;
void vfs_init(void);
int32_t vfs_read(char *mountpoint, const char *path, uint8_t *const buffer, size_t n, size_t off);
int32_t vfs_stat(char *mountpoint, const char *path, VfsStat *stat);
int32_t vfs_write(char *mountpoint, const char *path, const uint8_t *const buffer, size_t n, size_t off);
int32_t vfs_remove(char *mountpoint, const char *path);
int32_t vfs_create(char *mountpoint, const char *path, int32_t type);
int32_t vfs_unmount(char *mountpoint);
int32_t vfs_mount(char *mountpoint, int32_t fstype, StoreDev *backingsd);
void vfs_close(VfsObj *vobj);
VfsObj *vfs_open(char *mountpoint, const char *path, uint32_t flags);
#endif // VFS_VFS_H_