diff --git a/fs/fs_class.c b/fs/fs_class.c index 2923b12..b819397 100644 --- a/fs/fs_class.c +++ b/fs/fs_class.c @@ -1,54 +1,49 @@ +#include "sys/mem/slab.h" +#include "sys/assert.h" #include "user/errno.h" #include "sys/string.h" -#include "fs/fs.h" #include "sys/debug.h" +#include "fs/fs.h" -// #include -// #include -// #include +static LIST_HEAD(fs_class_list); +static LIST_HEAD(fs_mount_list); -static struct fs_class *fses[10] = { NULL }; -static struct fs mounts[10]; +static struct slab_cache *fs_mount_cache; struct fs *fs_create(struct fs_class *cls, struct blkdev *blk, uint32_t flags, const char *opt) { - struct fs *fs = NULL; - // XXX: I hate heap allocations, but why not use one? - for (size_t i = 0; i < 10; ++i) { - if (mounts[i].cls == NULL) { - mounts[i].cls = cls; - mounts[i].blk = blk; - fs = &mounts[i]; - break; - } - } - - if (!fs) { - return NULL; + if (!fs_mount_cache) { + kdebug("Initialize filesystem instance (mount) cache\n"); + fs_mount_cache = slab_cache_get(sizeof(struct fs)); + _assert(fs_mount_cache); } + struct fs *fs = slab_calloc(fs_mount_cache); + _assert(fs); + list_head_init(&fs->link); + fs->cls = cls; + fs->blk = blk; fs->flags = flags; - // Try to initialize filesystem instance at device if (cls->init) { if (cls->init(fs, opt) != 0) { - fs->cls = NULL; - kerror("%s init failed\n", cls->name); + kerror("%s: filesystem instance init failed\n", cls->name); + slab_free(fs_mount_cache, fs); return NULL; } } else { - kwarn("%s provides no init function\n", cls->name); + kwarn("%s: filesystem type has no init func\n", cls->name); } + list_add(&fs->link, &fs_mount_list); + return fs; } struct fs_class *fs_class_by_name(const char *name) { - for (size_t i = 0; i < 10; ++i) { - if (!fses[i]) { - break; - } - if (!strcmp(name, fses[i]->name)) { - return fses[i]; + struct fs_class *cls; + list_for_each_entry(cls, &fs_class_list, link) { + if (!strcmp(cls->name, name)) { + return cls; } } return NULL; @@ -59,12 +54,7 @@ int fs_class_register(struct fs_class *cls) { return -EEXIST; } - for (size_t i = 0; i < 10; ++i) { - if (!fses[i]) { - fses[i] = cls; - return 0; - } - } - - return -ENOMEM; + list_head_init(&cls->link); + list_add(&cls->link, &fs_class_list); + return 0; } diff --git a/include/fs/fs.h b/include/fs/fs.h index 0d49dd7..85eb3e1 100644 --- a/include/fs/fs.h +++ b/include/fs/fs.h @@ -1,5 +1,6 @@ #pragma once #include "sys/types.h" +#include "sys/list.h" struct statvfs; struct blkdev; @@ -15,6 +16,8 @@ struct fs_class { int (*init) (struct fs *fs, const char *opt); void (*destroy) (struct fs *fs); int (*statvfs) (struct fs *fs, struct statvfs *st); + + struct list_head link; }; // The actual filesystem instance, @@ -29,6 +32,8 @@ struct fs { void *fs_private; struct fs_class *cls; + + struct list_head link; }; struct fs *fs_create(struct fs_class *cls, struct blkdev *blk, uint32_t flags, const char *opt);