lock_lfvx/bk_idk/components/bk_vfs/bk_filesystem.c
2025-10-10 16:07:00 +08:00

216 lines
4.2 KiB
C

#include "os/os.h"
#include "os/str.h"
#include "os/mem.h"
#include <stdlib.h>
#include <string.h>
#include "bk_filesystem.h"
#include "bk_fdtable.h"
#include "bk_file_utils.h"
#define MAX_FS_TYPES 3
static struct filesystem_proto g_filesystem_impls[MAX_FS_TYPES];
#define MAX_FS_MOUNTS 4
static struct bk_filesystem g_filesystem_table[MAX_FS_MOUNTS];
int bk_filesystem_init(void) {
int i;
for (i = 0; i < MAX_FS_TYPES; i++) {
g_filesystem_impls[i].fs_type = NULL;
}
for (i = 0; i < MAX_FS_MOUNTS; i++) {
g_filesystem_table[i].mount_point = NULL;
}
return 0;
}
int bk_register_filesystem(const char *fs_type, struct bk_filesystem_ops *fs_ops, struct bk_file_ops *f_ops) {
int i;
if (!fs_type || !fs_ops || !f_ops)
return -1;
for (i = 0; i < MAX_FS_TYPES; i++) {
if (g_filesystem_impls[i].fs_type == NULL) {
g_filesystem_impls[i].fs_type = os_strdup(fs_type);
g_filesystem_impls[i].fs_ops = fs_ops;
g_filesystem_impls[i].f_ops = f_ops;
return 0;
}
}
return -1;
}
static struct filesystem_proto *bk_find_filesystem_impl(const char *fs_type) {
int i;
if (!fs_type)
return NULL;
for (i = 0; i < MAX_FS_TYPES; i++) {
if (g_filesystem_impls[i].fs_type != NULL) {
if (strcmp(g_filesystem_impls[i].fs_type, fs_type) == 0) {
return &g_filesystem_impls[i];
}
}
}
return NULL;
}
int bk_vfs_mount(const char *source, const char *target,
const char *fs_type, unsigned long mount_flags,
const void *data) {
struct filesystem_proto *impl;
struct bk_filesystem *fs = NULL;
int i;
int ret;
ret = bk_vfs_init();
if (ret)
return -1;
impl = bk_find_filesystem_impl(fs_type);
if (!impl) {
return -1;
}
if (!impl->fs_ops->mount) {
return -1;
}
for (i = 0; i < MAX_FS_MOUNTS; i++) {
if (g_filesystem_table[i].mount_point == NULL) {
fs = &g_filesystem_table[i];
break;
}
}
if (!fs) {
return -1;
}
fs->mount_point = os_strdup(target);
fs->fs_ops = impl->fs_ops;
fs->f_ops = impl->f_ops;
ret = fs->fs_ops->mount(fs, mount_flags, data);
if (ret) {
os_free(fs->mount_point);
fs->mount_point = NULL;
return -1;
} else {
return 0;
}
}
int bk_vfs_umount(const char *target) {
struct bk_filesystem *fs = NULL;
int ret = -1;
int i;
for (i = 0; i < MAX_FS_MOUNTS; i++) {
if (g_filesystem_table[i].mount_point != NULL) {
if (strcmp(g_filesystem_table[i].mount_point, target) == 0) {
fs = &g_filesystem_table[i];
break;
}
}
}
if (!fs) {
return -1;
}
if (fs->fs_ops->unmount) {
ret = fs->fs_ops->unmount(fs);
}
os_free(fs->mount_point);
fs->mount_point = NULL;
return ret;
}
int bk_vfs_umount2(const char *target, int flags) {
struct bk_filesystem *fs = NULL;
int ret = -1;
int i;
for (i = 0; i < MAX_FS_MOUNTS; i++) {
if (g_filesystem_table[i].mount_point != NULL) {
if (strcmp(g_filesystem_table[i].mount_point, target) == 0) {
fs = &g_filesystem_table[i];
break;
}
}
}
if (!fs) {
return -1;
}
if (fs->fs_ops->unmount2) {
ret = fs->fs_ops->unmount2(fs, flags);
}
os_free(fs->mount_point);
fs->mount_point = NULL;
return ret;
}
struct bk_filesystem *bk_vfs_lookup(const char *path) {
struct bk_filesystem *fs = NULL;
int i;
for (i = 0; i < MAX_FS_MOUNTS; i++) {
if (g_filesystem_table[i].mount_point != NULL) {
if (strncmp(g_filesystem_table[i].mount_point, path, strlen(g_filesystem_table[i].mount_point)) == 0) {
fs = &g_filesystem_table[i];
break;
}
}
}
return fs;
}
int bk_vfs_mkfs(const char *partition_name, const char *fs_type, const void *data) {
struct filesystem_proto *impl;
int ret;
ret = bk_vfs_init();
if (ret)
return -1;
impl = bk_find_filesystem_impl(fs_type);
if (!impl) {
return -1;
}
if (!impl->fs_ops->mkfs) {
return -1;
}
return impl->fs_ops->mkfs(partition_name, data);
}
int bk_vfs_statfs(const char *path, struct statfs *buf) {
struct bk_filesystem *fs;
fs = bk_vfs_lookup(path);
if (!fs || !fs->fs_ops || !fs->fs_ops->statfs)
return -1;
return fs->fs_ops->statfs(fs, buf);
}