From: Tulio A M Mendes Date: Mon, 25 May 2026 21:05:48 +0000 (-0300) Subject: vfs: remove g_fat_root global, allocate root per mount (P3.1, P3.2, P3.3) X-Git-Url: https://projects.tadryanom.me/?a=commitdiff_plain;h=99f5fa66e7ec20d64741daaa11a591e463e41e70;p=AdrOS.git vfs: remove g_fat_root global, allocate root per mount (P3.1, P3.2, P3.3) - Remove g_fat_root global from fat.c - Allocate root node dynamically in fat_mount() and ext2_mount() - Add root field to vfs_superblock_t for cleanup on umount - Update fat_kill_sb and ext2_kill_sb to free root node - Remove g_fat_root check from fat_close_impl --- diff --git a/include/fs.h b/include/fs.h index c1ea44a1..d4238b1b 100644 --- a/include/fs.h +++ b/include/fs.h @@ -42,6 +42,7 @@ typedef struct vfs_superblock { 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) */ + struct fs_node* root; /* VFS root node (for cleanup on umount) */ } vfs_superblock_t; /* Mount result structure - returned by filesystem mount functions */ diff --git a/src/kernel/ext2.c b/src/kernel/ext2.c index 02f60c43..829401d3 100644 --- a/src/kernel/ext2.c +++ b/src/kernel/ext2.c @@ -1552,6 +1552,7 @@ vfs_mount_result_t ext2_mount(const block_device_t* bdev, uint32_t partition_lba vfs_sb->bdev = bdev; vfs_sb->lba = partition_lba; vfs_sb->private_data = em; + vfs_sb->root = &root->vfs; /* fstype will be set by caller */ kprintf("[EXT2] Mounted at LBA %u (%u blocks, %u inodes, %u groups, %uB/block)\n", diff --git a/src/kernel/fat.c b/src/kernel/fat.c index 6e3839bd..cbcf5b4b 100644 --- a/src/kernel/fat.c +++ b/src/kernel/fat.c @@ -112,7 +112,6 @@ struct fat_node { uint32_t dir_entry_offset; /* byte offset of dirent within parent dir data */ }; -static struct fat_node g_fat_root; static uint8_t g_sec_buf[FAT_SECTOR_SIZE]; /* ---- Low-level sector I/O ---- */ @@ -516,7 +515,6 @@ static const struct inode_operations fat_dir_iops = { static void fat_close_impl(fs_node_t* node) { if (!node) return; struct fat_node* fn = (struct fat_node*)node; - if (fn == &g_fat_root) return; kfree(fn); } @@ -1210,21 +1208,28 @@ vfs_mount_result_t fat_mount(const block_device_t* bdev, uint32_t partition_lba) } /* Build root node */ - memset(&g_fat_root, 0, sizeof(g_fat_root)); - g_fat_root.mount = fm; - memcpy(g_fat_root.vfs.name, "fat", 4); - g_fat_root.vfs.flags = FS_DIRECTORY; - g_fat_root.vfs.inode = 0; - g_fat_root.first_cluster = (fm->type == FAT_TYPE_32) ? fm->root_cluster : 0; - g_fat_root.parent_cluster = 0; - g_fat_root.dir_entry_offset = 0; - g_fat_root.vfs.f_ops = &fat_dir_fops; - g_fat_root.vfs.i_ops = &fat_dir_iops; + struct fat_node* root = (struct fat_node*)kmalloc(sizeof(struct fat_node)); + if (!root) { + kprintf("[FAT] Failed to allocate root node\n"); + kfree(fm); + return result; + } + memset(root, 0, sizeof(*root)); + root->mount = fm; + memcpy(root->vfs.name, "fat", 4); + root->vfs.flags = FS_DIRECTORY; + root->vfs.inode = 0; + root->first_cluster = (fm->type == FAT_TYPE_32) ? fm->root_cluster : 0; + root->parent_cluster = 0; + root->dir_entry_offset = 0; + root->vfs.f_ops = &fat_dir_fops; + root->vfs.i_ops = &fat_dir_iops; /* Build superblock */ vfs_superblock_t* sb = (vfs_superblock_t*)kmalloc(sizeof(vfs_superblock_t)); if (!sb) { kprintf("[FAT] Failed to allocate superblock\n"); + kfree(root); kfree(fm); return result; } @@ -1232,12 +1237,13 @@ vfs_mount_result_t fat_mount(const block_device_t* bdev, uint32_t partition_lba) sb->bdev = bdev; sb->lba = partition_lba; sb->private_data = fm; + sb->root = &root->vfs; /* fstype will be set by caller */ kprintf("[FAT] Mounted FAT%u at LBA %u (%u clusters)\n", (unsigned)fm->type, partition_lba, fm->total_clusters); - result.root = &g_fat_root.vfs; + result.root = &root->vfs; result.sb = sb; return result; } diff --git a/src/kernel/init.c b/src/kernel/init.c index 47c29c47..591252f2 100644 --- a/src/kernel/init.c +++ b/src/kernel/init.c @@ -97,15 +97,29 @@ int init_mount_fs(const char* fstype, const block_device_t* bdev, uint32_t lba, } static void fat_kill_sb(vfs_superblock_t* sb) { - if (sb && sb->private_data) { - fat_umount((struct fat_mount*)sb->private_data); + if (sb) { + /* Free the root node allocated in fat_mount */ + if (sb->root) { + kfree(sb->root); + } + /* Free the mount structure */ + if (sb->private_data) { + fat_umount((struct fat_mount*)sb->private_data); + } kfree(sb); } } static void ext2_kill_sb(vfs_superblock_t* sb) { - if (sb && sb->private_data) { - ext2_umount((struct ext2_mount*)sb->private_data); + if (sb) { + /* Free the root node allocated in ext2_mount */ + if (sb->root) { + kfree(sb->root); + } + /* Free the mount structure */ + if (sb->private_data) { + ext2_umount((struct ext2_mount*)sb->private_data); + } kfree(sb); } }