From: Tulio A M Mendes Date: Mon, 25 May 2026 16:27:57 +0000 (-0300) Subject: vfs: Fase 3 - filesystem type registry and superblock X-Git-Url: https://projects.tadryanom.me/?a=commitdiff_plain;h=e26de6e6fd45d17abad646e6134b727105bf1010;p=AdrOS.git vfs: Fase 3 - filesystem type registry and superblock - Added vfs_fs_type_t structure with name, flags, and mount function - Implemented vfs_fs_type_register and vfs_fs_type_find functions - Registered FAT and ext2 filesystem types in init_start - Refactored init_mount_fs to use vfs_fs_type_find instead of hardcoded strcmp - Added vfs_superblock_t structure with fstype, bdev, lba, and private_data - Added sb field to vfs_mount struct - Updated vfs_mount_nolock_full to accept and store vfs_superblock_t* - Updated all callers to pass NULL for sb parameter (virtual FS don't use it yet) --- diff --git a/include/fs.h b/include/fs.h index 766664a7..80291687 100644 --- a/include/fs.h +++ b/include/fs.h @@ -30,14 +30,32 @@ #define MS_SYNCHRONOUS 16 #define MS_REMOUNT 32 /* Alter flags of existing mount */ +/* Filesystem type flags */ +#define FS_NEEDS_BDEV 0x01 /* Requires block device */ + +struct fs_node; /* forward declaration */ + +/* Filesystem type structure */ +typedef struct vfs_fs_type { + const char* name; /* e.g. "fat", "ext2" */ + uint32_t flags; /* FS_NEEDS_BDEV, etc. */ + struct fs_node* (*mount)(const block_device_t* bdev, uint32_t lba); /* Mount function */ +} vfs_fs_type_t; + +/* VFS superblock — per-mount filesystem metadata */ +typedef struct vfs_superblock { + const vfs_fs_type_t* fstype; /* Filesystem type */ + const block_device_t* bdev; /* Block device (NULL for virtual FS) */ + uint32_t lba; /* Partition start LBA (0 for whole disk) */ + void* private_data; /* Filesystem-specific data (e.g. fat_mount, ext2_mount) */ +} vfs_superblock_t; + /* poll() event flags — shared between kernel VFS and syscall layer */ #define VFS_POLL_IN 0x0001 #define VFS_POLL_OUT 0x0004 #define VFS_POLL_ERR 0x0008 #define VFS_POLL_HUP 0x0010 -struct fs_node; /* forward declaration for file_operations */ - /* File operations — per-open-fd I/O (requires an open file descriptor) */ struct file_operations { uint32_t (*read)(struct fs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer); @@ -121,7 +139,8 @@ int vfs_umount(const char* mountpoint); int vfs_mount_nolock(const char* mountpoint, fs_node_t* root); int vfs_mount_nolock_full(const char* mountpoint, fs_node_t* root, const char* fstype, const char* source, - unsigned long flags, const block_device_t* bdev); + unsigned long flags, const block_device_t* bdev, + vfs_superblock_t* sb); int vfs_umount_nolock(const char* mountpoint); /* Read mount table for /proc/mounts. Returns bytes written. */ @@ -133,6 +152,10 @@ unsigned long vfs_mount_flags(const char* path); /* Look up mount flags by mount root node pointer. */ unsigned long vfs_node_mount_flags(const fs_node_t* root); +/* Filesystem type registry */ +int vfs_fs_type_register(const vfs_fs_type_t* fst); +const vfs_fs_type_t* vfs_fs_type_find(const char* name); + /* Find the mount root fs_node for a given path. */ fs_node_t* vfs_find_mount_root(const char* path); diff --git a/src/kernel/fs.c b/src/kernel/fs.c index 938a5c4e..a0265fbb 100644 --- a/src/kernel/fs.c +++ b/src/kernel/fs.c @@ -31,12 +31,18 @@ struct vfs_mount { unsigned long flags; /* MS_RDONLY, MS_NOSUID, etc. */ int refcount; /* number of open files on this mount */ const block_device_t* bdev; /* block device (NULL for virtual FS) */ + vfs_superblock_t* sb; /* superblock (NULL for virtual FS) */ fs_node_t* root; }; static struct vfs_mount g_mounts[32]; static int g_mount_count = 0; +/* Filesystem type registry */ +#define FS_TYPE_MAX 8 +static vfs_fs_type_t g_fs_types[FS_TYPE_MAX]; +static int g_fs_type_count = 0; + static int path_is_mountpoint_prefix(const char* mp, const char* path) { size_t mpl = strlen(mp); if (mpl == 0) return 0; @@ -75,7 +81,8 @@ static void normalize_mountpoint(const char* in, char* out, size_t out_sz) { int vfs_mount_nolock_full(const char* mountpoint, fs_node_t* root, const char* fstype, const char* source, - unsigned long flags, const block_device_t* bdev) { + unsigned long flags, const block_device_t* bdev, + vfs_superblock_t* sb) { char mp[128]; normalize_mountpoint(mountpoint, mp, sizeof(mp)); @@ -94,6 +101,7 @@ int vfs_mount_nolock_full(const char* mountpoint, fs_node_t* root, /* Always update flags on remount (even if 0, caller explicitly set them) */ g_mounts[i].flags = flags; g_mounts[i].bdev = bdev; + g_mounts[i].sb = sb; return 0; } } @@ -118,19 +126,20 @@ int vfs_mount_nolock_full(const char* mountpoint, fs_node_t* root, } g_mounts[g_mount_count].flags = flags; g_mounts[g_mount_count].bdev = bdev; + g_mounts[g_mount_count].sb = sb; g_mount_count++; return 0; } int vfs_mount_nolock(const char* mountpoint, fs_node_t* root) { - return vfs_mount_nolock_full(mountpoint, root, NULL, NULL, 0, NULL); + return vfs_mount_nolock_full(mountpoint, root, NULL, NULL, 0, NULL, NULL); } int vfs_mount_full(const char* mountpoint, fs_node_t* root, const char* fstype, const char* source, unsigned long flags, const block_device_t* bdev) { uintptr_t fl = spin_lock_irqsave(&g_vfs_lock); - int ret = vfs_mount_nolock_full(mountpoint, root, fstype, source, flags, bdev); + int ret = vfs_mount_nolock_full(mountpoint, root, fstype, source, flags, bdev, NULL); spin_unlock_irqrestore(&g_vfs_lock, fl); return ret; } @@ -626,3 +635,32 @@ int vfs_require_writable_path(const char* path) { if (mflags & MS_RDONLY) return -EROFS; return 0; } + +/* ---- Filesystem type registry ---- */ + +int vfs_fs_type_register(const vfs_fs_type_t* fst) { + if (!fst || !fst->name) return -EINVAL; + if (g_fs_type_count >= FS_TYPE_MAX) return -ENOSPC; + + /* Check for duplicate name */ + for (int i = 0; i < g_fs_type_count; i++) { + if (strcmp(g_fs_types[i].name, fst->name) == 0) { + /* Update existing entry */ + g_fs_types[i] = *fst; + return 0; + } + } + + g_fs_types[g_fs_type_count++] = *fst; + kprintf("[VFS] Registered filesystem type: %s\n", fst->name); + return 0; +} + +const vfs_fs_type_t* vfs_fs_type_find(const char* name) { + if (!name) return NULL; + for (int i = 0; i < g_fs_type_count; i++) { + if (strcmp(g_fs_types[i].name, name) == 0) + return &g_fs_types[i]; + } + return NULL; +} diff --git a/src/kernel/init.c b/src/kernel/init.c index c79426a7..e7ac8230 100644 --- a/src/kernel/init.c +++ b/src/kernel/init.c @@ -13,6 +13,8 @@ #include "hal/driver.h" #include "fs.h" +#include "fat.h" +#include "ext2.h" #include "initrd.h" #include "overlayfs.h" #include "tmpfs.h" @@ -21,8 +23,6 @@ #include "pty.h" /* diskfs and persistfs removed — use fat/ext2 for disk storage */ #include "procfs.h" -#include "fat.h" -#include "ext2.h" #include "pci.h" #include "e1000.h" #include "net.h" @@ -45,17 +45,13 @@ /* ---- Mount helper: used by fstab parser and kconsole 'mount' command ---- */ int init_mount_fs(const char* fstype, const block_device_t* bdev, uint32_t lba, const char* mountpoint, unsigned long flags) { - fs_node_t* root = NULL; - - if (strcmp(fstype, "fat") == 0) { - root = fat_mount(bdev, lba); - } else if (strcmp(fstype, "ext2") == 0) { - root = ext2_mount(bdev, lba); - } else { + const vfs_fs_type_t* fst = vfs_fs_type_find(fstype); + if (!fst) { kprintf("[MOUNT] Unknown filesystem type: %s\n", fstype); return -EINVAL; } + fs_node_t* root = fst->mount(bdev, lba); if (!root) { kprintf("[MOUNT] Failed to mount %s on %s at %s\n", fstype, bdev ? bdev->name : "?", @@ -96,6 +92,21 @@ int init_mount_fs(const char* fstype, const block_device_t* bdev, uint32_t lba, } int init_start(const struct boot_info* bi) { + /* Register filesystem types */ + static vfs_fs_type_t fat_fs_type = { + .name = "fat", + .flags = FS_NEEDS_BDEV, + .mount = fat_mount + }; + vfs_fs_type_register(&fat_fs_type); + + static vfs_fs_type_t ext2_fs_type = { + .name = "ext2", + .flags = FS_NEEDS_BDEV, + .mount = ext2_mount + }; + vfs_fs_type_register(&ext2_fs_type); + /* Parse kernel command line (Linux-like triaging) */ cmdline_parse(bi ? bi->cmdline : NULL); diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c index 6555463a..1b46ea06 100644 --- a/src/kernel/syscall.c +++ b/src/kernel/syscall.c @@ -5075,9 +5075,9 @@ static void extended_syscall_dispatch(struct registers* regs, uint32_t syscall_n uintptr_t vfs_fl = spin_lock_irqsave(&g_vfs_lock); fs_node_t* old_root = fs_root; fs_root = new_root; - (void)vfs_mount_nolock_full("/", new_root, NULL, NULL, 0, NULL); + (void)vfs_mount_nolock_full("/", new_root, NULL, NULL, 0, NULL, NULL); if (old_root) { - (void)vfs_mount_nolock_full(kput, old_root, NULL, NULL, 0, NULL); + (void)vfs_mount_nolock_full(kput, old_root, NULL, NULL, 0, NULL, NULL); } spin_unlock_irqrestore(&g_vfs_lock, vfs_fl); sc_ret(regs) = 0;