]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
vfs: Fase 3 - filesystem type registry and superblock
authorTulio A M Mendes <[email protected]>
Mon, 25 May 2026 16:27:57 +0000 (13:27 -0300)
committerTulio A M Mendes <[email protected]>
Wed, 3 Jun 2026 04:02:35 +0000 (01:02 -0300)
- 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)

include/fs.h
src/kernel/fs.c
src/kernel/init.c
src/kernel/syscall.c

index 766664a736dfae0380f2f49b7ac4a9fadb6bc7e2..80291687f4dd9694712e27868d555144126b444a 100644 (file)
 #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);
 
index 938a5c4e6a562be55546a3eded828c0aad02bea4..a0265fbbd3efcdb3c1115b6851c75b4e965101c1 100644 (file)
@@ -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;
+}
index c79426a714cea2e8ff8eb73f3188aba66d6c4db9..e7ac8230de46625d38f5b41743f92c682f959ba7 100644 (file)
@@ -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"
 /* ---- 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);
 
index 6555463a3cc3404d8e44ec2a4572cccbffc93d46..1b46ea066c4a09dddc9393bafc4237e88496d67e 100644 (file)
@@ -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;