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

@ -1,123 +0,0 @@
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include "spinlock/spinlock.h"
#include "errors.h"
#include "hal/hal.h"
#include "hshtb.h"
#include "kprintf.h"
#include "vfs/vfs.h"
#include "dlmalloc/malloc.h"
#include "util/util.h"
int32_t kvfs_read(struct VfsMountPoint *vmp, const char *key, uint8_t *const buffer, size_t n, size_t off) {
KvfsNode *node = NULL;
spinlock_acquire(&vmp->spinlock);
HSHTB_GET(&vmp->fs.kvfs, nodes, (char *)key, key_, node);
spinlock_release(&vmp->spinlock);
if (node == NULL) {
return E_NOENTRY;
}
spinlock_acquire(&node->spinlock);
vmp->backingsd->read(vmp->backingsd, buffer, n, off);
spinlock_release(&node->spinlock);
return E_OK;
}
int32_t kvfs_stat(struct VfsMountPoint *vmp, const char *key, struct VfsStat *stat) {
KvfsNode *node = NULL;
spinlock_acquire(&vmp->spinlock);
HSHTB_GET(&vmp->fs.kvfs, nodes, (char *)key, key_, node);
spinlock_release(&vmp->spinlock);
if (node == NULL) {
return E_NOENTRY;
}
stat->type = VFS_TYPE_FILE;
stat->size = KVFS_BUFFER_SIZE;
return E_OK;
}
int32_t kvfs_write(struct VfsMountPoint *vmp, const char *key, const uint8_t *const buffer, size_t n, size_t off) {
KvfsNode *node = NULL;
spinlock_acquire(&vmp->spinlock);
HSHTB_GET(&vmp->fs.kvfs, nodes, (char *)key, key_, node);
spinlock_release(&vmp->spinlock);
if (node == NULL) {
return E_NOENTRY;
}
spinlock_acquire(&node->spinlock);
vmp->backingsd->write(vmp->backingsd, buffer, n, off);
spinlock_release(&node->spinlock);
return E_OK;
}
int32_t kvfs_remove(struct VfsMountPoint *vmp, const char *key) {
KvfsNode *node = NULL;
spinlock_acquire(&vmp->spinlock);
HSHTB_GET(&vmp->fs.kvfs, nodes, (char *)key, key_, node);
spinlock_release(&vmp->spinlock);
if (node == NULL) {
return E_NOENTRY;
}
spinlock_acquire(&node->spinlock);
hal_memset(node, 0, sizeof(*node));
spinlock_release(&node->spinlock);
return E_OK;
}
int32_t kvfs_cleanup(struct VfsMountPoint *vmp) {
int32_t err = vmp->backingsd->cleanup(vmp->backingsd);
if (err != E_OK) {
return err;
}
return E_OK;
}
int32_t kvfs_create(struct VfsMountPoint *vmp, const char *path, int32_t type) {
(void)type;
KvfsNode *node = NULL;
spinlock_acquire(&vmp->spinlock);
HSHTB_ALLOC(&vmp->fs.kvfs, nodes, (char *)path, key_, node);
spinlock_release(&vmp->spinlock);
if (node == NULL) {
return E_NOMEMORY;
}
return E_OK;
}
bool kvfs_check(void) {
int32_t ret;
ret = vfs_create("tmpvars", "hello", VFS_TYPE_FILE);
if (ret != E_OK) return false;
char *hello = "WAWAWAWA!!!";
ret = vfs_write("tmpvars", "hello", hello, hal_strlen(hello)+1, 0);
if (ret != E_OK) return false;
char buf[20];
ret = vfs_read("tmpvars", "hello", buf, sizeof(buf), 0);
if (ret != E_OK) return false;
vfs_remove("tmpvars", "hello");
if (ret != E_OK) return false;
ret = vfs_read("tmpvars", "hello", buf, sizeof(buf), 0);
if (ret != E_NOENTRY) return false;
return true;
}

View File

@ -1,32 +0,0 @@
#ifndef FS_KVFS_KVFS_H_
#define FS_KVFS_KVFS_H_
#include <stdint.h>
#include <stdbool.h>
struct VfsMountPoint;
struct VfsStat;
#define KVFS_NODE_KEY_MAX 128
#define KVFS_NODES_MAX 256
#define KVFS_BUFFER_SIZE (1024 * 2)
typedef struct {
bool taken;
uint8_t key_[KVFS_NODE_KEY_MAX];
SpinLock spinlock;
} KvfsNode;
typedef struct {
KvfsNode nodes[KVFS_NODES_MAX];
} Kvfs;
int32_t kvfs_read(struct VfsMountPoint *vmp, const char *key, uint8_t *const buffer, size_t n, size_t off);
int32_t kvfs_stat(struct VfsMountPoint *vmp, const char *key, struct VfsStat *stat);
int32_t kvfs_write(struct VfsMountPoint *vmp, const char *key, const uint8_t *const buffer, size_t n, size_t off);
int32_t kvfs_remove(struct VfsMountPoint *vmp, const char *key);
int32_t kvfs_create(struct VfsMountPoint *vmp, const char *path, int32_t type);
int32_t kvfs_cleanup(struct VfsMountPoint *vmp);
bool kvfs_check(void);
#endif // FS_KVFS_KVFS_H_

View File

@ -5,81 +5,7 @@
#include "errors.h" #include "errors.h"
#include "kprintf.h" #include "kprintf.h"
#include "dlmalloc/malloc.h" #include "dlmalloc/malloc.h"
#include "hal/hal.h"
#define CHECK(err) \
do { \
int ok = (err); \
if (ok < 0) goto bad; \
} while(0)
int32_t littlefs_read(struct VfsMountPoint *vmp, const char *path, uint8_t *const buffer, size_t n, size_t off) {
spinlock_acquire(&vmp->spinlock);
LittleFs *fs = &vmp->fs.littlefs;
lfs_file_t file;
CHECK(lfs_file_open(&fs->instance, &file, path, LFS_O_RDONLY));
CHECK(lfs_file_seek(&fs->instance, &file, off, LFS_SEEK_SET));
CHECK(lfs_file_read(&fs->instance, &file, buffer + off, n));
CHECK(lfs_file_close(&fs->instance, &file));
spinlock_release(&vmp->spinlock);
return E_OK;
bad:
spinlock_release(&vmp->spinlock);
return E_BADIO;
}
int32_t littlefs_stat(struct VfsMountPoint *vmp, const char *path, struct VfsStat *stat) {
spinlock_acquire(&vmp->spinlock);
LittleFs *fs = &vmp->fs.littlefs;
struct lfs_info stat1;
CHECK(lfs_stat(&fs->instance, path, &stat1));
if (stat1.type == LFS_TYPE_REG) {
stat->type = VFS_TYPE_FILE;
} else if (stat1.type == LFS_TYPE_DIR) {
stat->type = VFS_TYPE_DIR;
}
stat->size = stat1.size;
spinlock_release(&vmp->spinlock);
return E_OK;
bad:
spinlock_release(&vmp->spinlock);
return E_BADIO;
}
int32_t littlefs_write(struct VfsMountPoint *vmp, const char *path, const uint8_t *const buffer, size_t n, size_t off) {
spinlock_acquire(&vmp->spinlock);
LittleFs *fs = &vmp->fs.littlefs;
lfs_file_t file;
CHECK(lfs_file_open(&fs->instance, &file, path, LFS_O_WRONLY));
CHECK(lfs_file_seek(&fs->instance, &file, off, LFS_SEEK_SET));
CHECK(lfs_file_write(&fs->instance, &file, buffer, n));
CHECK(lfs_file_close(&fs->instance, &file));
spinlock_release(&vmp->spinlock);
return E_OK;
bad:
spinlock_release(&vmp->spinlock);
return E_BADIO;
}
int32_t littlefs_remove(struct VfsMountPoint *vmp, const char *path) {
spinlock_acquire(&vmp->spinlock);
LittleFs *fs = &vmp->fs.littlefs;
CHECK(lfs_remove(&fs->instance, path));
spinlock_release(&vmp->spinlock);
return E_OK;
bad:
spinlock_release(&vmp->spinlock);
return E_BADIO;
}
int32_t littlefs_cleanup(struct VfsMountPoint *vmp) { int32_t littlefs_cleanup(struct VfsMountPoint *vmp) {
dlfree(vmp->fs.littlefs.instance.cfg); dlfree(vmp->fs.littlefs.instance.cfg);
@ -92,30 +18,106 @@ int32_t littlefs_cleanup(struct VfsMountPoint *vmp) {
return E_OK; return E_OK;
} }
int32_t littlefs_create(struct VfsMountPoint *vmp, const char *path, int32_t type) { void littlefs_vobj_cleanup(struct VfsObj *vobj) {
if (vobj->extra != NULL) {
lfs_file_close(&vobj->vmp->fs.littlefs.instance, (lfs_file_t *)vobj->extra);
dlfree(vobj->extra);
}
dlfree(vobj);
}
int32_t littlefs_vobj_read(struct VfsObj *vobj, uint8_t *const buffer, size_t n, size_t off) {
spinlock_acquire(&vobj->spinlock);
int ok = lfs_file_seek(&vobj->vmp->fs.littlefs.instance, (lfs_file_t *)vobj->extra, off, LFS_SEEK_SET);
if (ok < 0) {
spinlock_release(&vobj->spinlock);
return E_BADIO;
}
ok = lfs_file_read(&vobj->vmp->fs.littlefs.instance, (lfs_file_t *)vobj->extra, buffer, n);
if (ok < 0) {
spinlock_release(&vobj->spinlock);
return E_BADIO;
}
spinlock_release(&vobj->spinlock);
return E_OK;
}
int32_t littlefs_vobj_stat(struct VfsObj *vobj, struct VfsStat *stat) {
struct lfs_info statbuf;
spinlock_acquire(&vobj->spinlock);
int ok = lfs_stat(&vobj->vmp->fs.littlefs.instance, vobj->path, &statbuf);
if (ok < 0) {
spinlock_release(&vobj->spinlock);
return E_BADIO;
}
if (statbuf.type == LFS_TYPE_REG) {
stat->type = VFS_TYPE_FILE;
} else if (statbuf.type == LFS_TYPE_DIR) {
stat->type = VFS_TYPE_DIR;
}
stat->size = statbuf.size;
spinlock_release(&vobj->spinlock);
return E_OK;
}
struct VfsObj *littlefs_open(struct VfsMountPoint *vmp, const char *path, uint32_t flags) {
VfsObj *vobj = dlmalloc(sizeof(*vobj));
if (vobj == NULL) {
return NULL;
}
hal_memset(vobj, 0, sizeof(*vobj));
spinlock_init(&vobj->spinlock);
vobj->refs++;
int lfs_flags = 0;
lfs_file_t *file = dlmalloc(sizeof(*file));
if (file == NULL) {
dlfree(vobj);
return NULL;
}
spinlock_acquire(&vmp->spinlock); spinlock_acquire(&vmp->spinlock);
LittleFs *fs = &vmp->fs.littlefs; LittleFs *fs = &vmp->fs.littlefs;
switch (type) {
case VFS_TYPE_DIR: if (flags & VFS_FLAG_MAKE) {
CHECK(lfs_mkdir(&fs->instance, path)); lfs_flags |= LFS_O_CREAT;
break;
case VFS_TYPE_FILE: {
lfs_file_t file;
CHECK(lfs_file_open(&fs->instance, &file, path, LFS_O_CREAT | LFS_O_WRONLY));
CHECK(lfs_file_close(&fs->instance, &file));
} break;
} }
spinlock_release(&vmp->spinlock); if (flags == VFS_FLAG_READ) {
return E_OK; lfs_flags |= LFS_O_RDONLY;
bad: } else if (flags == VFS_FLAG_WRITE) {
spinlock_release(&vmp->spinlock); lfs_flags |= LFS_O_WRONLY;
return E_BADIO; } else if ((flags & VFS_FLAG_READ) && (flags & VFS_FLAG_WRITE)) {
} lfs_flags |= LFS_O_RDWR;
}
bool littlefs_check(void) { int ok = lfs_file_open(&fs->instance, file, path, lfs_flags);
return true;
if (ok < 0) {
dlfree(vobj);
dlfree(file);
spinlock_release(&vmp->spinlock);
return NULL;
}
vobj->extra = file;
vobj->extrasize = sizeof(*file);
vobj->vmp = vmp;
vobj->cleanup = &littlefs_vobj_cleanup;
vobj->read = &littlefs_vobj_read;
vobj->stat = &littlefs_vobj_stat;
hal_strcpy(vobj->path, path);
spinlock_release(&vmp->spinlock);
return vobj;
} }
int portlfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) { int portlfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) {

View File

@ -9,18 +9,14 @@
struct VfsMountPoint; struct VfsMountPoint;
struct VfsStat; struct VfsStat;
struct VfsObj;
typedef struct { typedef struct {
lfs_t instance; lfs_t instance;
} LittleFs; } LittleFs;
int32_t littlefs_read(struct VfsMountPoint *vmp, const char *path, uint8_t *const buffer, size_t n, size_t off);
int32_t littlefs_stat(struct VfsMountPoint *vmp, const char *path, struct VfsStat *stat);
int32_t littlefs_write(struct VfsMountPoint *vmp, const char *path, const uint8_t *const buffer, size_t n, size_t off);
int32_t littlefs_remove(struct VfsMountPoint *vmp, const char *path);
int32_t littlefs_create(struct VfsMountPoint *vmp, const char *path, int32_t type);
int32_t littlefs_cleanup(struct VfsMountPoint *vmp); int32_t littlefs_cleanup(struct VfsMountPoint *vmp);
bool littlefs_check(void); struct VfsObj *littlefs_open(struct VfsMountPoint *vmp, const char *path, uint32_t flags);
int portlfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size); int portlfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size);
int portlfs_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size); int portlfs_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size);

View File

@ -101,19 +101,36 @@ Proc *proc_spawnkern(void (*ent)(void), char *name) {
} }
Proc *proc_spawnuser(char *mountpoint, char *path) { Proc *proc_spawnuser(char *mountpoint, char *path) {
VfsStat stat; VfsObj *vobj = vfs_open(mountpoint, path, VFS_FLAG_READ);
if (vfs_stat(mountpoint, path, &stat) != E_OK) { if (vobj == NULL) {
return NULL; return NULL;
} }
VfsStat stat;
if (vobj->stat(vobj, &stat) != E_OK) {
vfs_close(vobj);
return NULL;
}
if (stat.type != VFS_TYPE_FILE) { if (stat.type != VFS_TYPE_FILE) {
vfs_close(vobj);
return NULL; return NULL;
} }
uint8_t *data = dlmalloc(stat.size); uint8_t *data = dlmalloc(stat.size);
if (vfs_read(mountpoint, path, data, stat.size, 0) != E_OK) { if (data == NULL) {
vfs_close(vobj);
return NULL; return NULL;
} }
if (vobj->read(vobj, data, stat.size, 0) != E_OK) {
dlfree(data);
vfs_close(vobj);
return NULL;
}
vfs_close(vobj);
Proc *proc = dlmalloc(sizeof(*proc)); Proc *proc = dlmalloc(sizeof(*proc));
hal_memset(proc, 0, sizeof(*proc)); hal_memset(proc, 0, sizeof(*proc));
ksprintf(proc->name, "%s:%s", mountpoint, path); ksprintf(proc->name, "%s:%s", mountpoint, path);

View File

@ -8,7 +8,6 @@
#include "hshtb.h" #include "hshtb.h"
#include "assert.h" #include "assert.h"
#include "errors.h" #include "errors.h"
#include "fs/kvfs/kvfs.h"
#include "fs/portlfs/portlfs.h" #include "fs/portlfs/portlfs.h"
#include "storedev/storedev.h" #include "storedev/storedev.h"
#include "baseimg/baseimg.h" #include "baseimg/baseimg.h"
@ -16,16 +15,6 @@
VfsTable VFS_TABLE; 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) { void vfs_init_littlefs(VfsMountPoint *mp) {
struct lfs_config *cfg = dlmalloc(sizeof(*cfg)); struct lfs_config *cfg = dlmalloc(sizeof(*cfg));
hal_memset(cfg, 0, 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"); 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->cleanup = &littlefs_cleanup;
mp->create = &littlefs_create; mp->open = &littlefs_open;
} }
int32_t vfs_mount(char *mountpoint, int32_t fstype, StoreDev *backingsd) { 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->backingsd = backingsd;
mp->fstype = fstype; mp->fstype = fstype;
switch (fstype) { switch (fstype) {
case VFS_KVFS:
vfs_init_kvfs(mp);
break;
case VFS_LITTLEFS: case VFS_LITTLEFS:
vfs_init_littlefs(mp); vfs_init_littlefs(mp);
break; break;
@ -111,7 +92,7 @@ int32_t vfs_unmount(char *mountpoint) {
return E_OK; 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; VfsMountPoint *mp = NULL;
spinlock_acquire(&VFS_TABLE.spinlock); 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); spinlock_release(&VFS_TABLE.spinlock);
if (mp == NULL) { 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) { void vfs_close(VfsObj *vobj) {
VfsMountPoint *mp = NULL; if (vobj->refs < 0) {
return;
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--;
return mp->stat(mp, path, stat); if (vobj->refs == 0) {
} vobj->cleanup(vobj);
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;
} }
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) { void vfs_init(void) {
hal_memset(&VFS_TABLE, 0, sizeof(VFS_TABLE)); hal_memset(&VFS_TABLE, 0, sizeof(VFS_TABLE));
spinlock_init(&VFS_TABLE.spinlock); spinlock_init(&VFS_TABLE.spinlock);
tmpvars_init(); RamSdInitExtra extra = { .capacity = baseimg_getsize(), .preallocbuffer = (uint8_t *)baseimg_getaddr() };
base_init(); StoreDev *backingsd = storedev_create(STOREDEV_RAMSD, &extra);
if (backingsd == NULL) {
return;
}
vfs_mount("base", VFS_LITTLEFS, backingsd);
LOG("vfs", "init\n"); LOG("vfs", "init\n");
@ -213,16 +135,5 @@ void vfs_init(void) {
VfsMountPoint *vmp = &VFS_TABLE.mountpoints[i]; VfsMountPoint *vmp = &VFS_TABLE.mountpoints[i];
LOG("vfs", "mount point %s: %s, backing device: %s\n", LOG("vfs", "mount point %s: %s, backing device: %s\n",
vmp->label, vfs_strings[vmp->fstype], storedev_strings[vmp->backingsd->sdtype]); 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 <stddef.h>
#include <stdbool.h> #include <stdbool.h>
#include "spinlock/spinlock.h" #include "spinlock/spinlock.h"
#include "fs/kvfs/kvfs.h"
#include "fs/portlfs/portlfs.h" #include "fs/portlfs/portlfs.h"
#include "storedev/storedev.h" #include "storedev/storedev.h"
@ -13,12 +12,10 @@
#define VFS_MOUNTPOINTS_MAX 30 #define VFS_MOUNTPOINTS_MAX 30
enum { enum {
VFS_KVFS,
VFS_LITTLEFS, VFS_LITTLEFS,
}; };
static const char *vfs_strings[] = { static const char *vfs_strings[] = {
"KVFS",
"Little FS", "Little FS",
}; };
@ -27,27 +24,41 @@ enum {
VFS_TYPE_FILE, 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 { typedef struct VfsStat {
size_t size; size_t size;
int32_t type; int32_t type;
} VfsStat; } 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 { typedef struct VfsMountPoint {
bool taken; bool taken;
uint8_t label[VFS_MOUNTPOINT_LABEL_MAX]; uint8_t label[VFS_MOUNTPOINT_LABEL_MAX];
int32_t fstype; int32_t fstype;
StoreDev *backingsd; StoreDev *backingsd;
int32_t (*read)(struct VfsMountPoint *vmp, const char *path, uint8_t *const buffer, size_t n, size_t off); VfsObj *(*open)(struct VfsMountPoint *vmp, const char *path, uint32_t flags);
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);
int32_t (*cleanup)(struct VfsMountPoint *vmp); int32_t (*cleanup)(struct VfsMountPoint *vmp);
bool (*check)(void);
union { union {
Kvfs kvfs;
LittleFs littlefs; LittleFs littlefs;
} fs; } fs;
SpinLock spinlock; SpinLock spinlock;
@ -61,12 +72,9 @@ typedef struct {
extern VfsTable VFS_TABLE; extern VfsTable VFS_TABLE;
void vfs_init(void); 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_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_ #endif // VFS_VFS_H_