fix(kernel/vfs): 🎉 a complete rewrite of the vfs

This is the fourth time re-writing the VFS, hope this will be the last. Tried to make it as modular as possible so this won't be necessary in the future. 🙏

This change required the entire kernel code to be modified.
This commit is contained in:
2025-05-13 15:59:12 +00:00
parent 83a7f83f81
commit 557c7e6235
83 changed files with 3252 additions and 2487 deletions

View File

@ -15,45 +15,88 @@
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <filesystem/ramfs.hpp>
#include <fs/ramfs.hpp>
#include "../../kernel.h"
#include <fs/ustar.hpp>
#include <ini.h>
namespace Subsystem::Linux
{
bool Initialized = false;
void __CreateStubRoot()
{
Node root = fs->GetRoot(0);
Node nmnt = fs->Lookup(root, "/mnt");
assert(MountAndRootRAMFS(nmnt, "linux", 1));
Node linux = fs->GetRoot(1);
Node bin = fs->Create(linux, "bin", 0755);
Node boot = fs->Create(linux, "boot", 0755);
Node dev = fs->Create(linux, "dev", 0755);
Node etc = fs->Create(linux, "etc", 0755);
Node home = fs->Create(linux, "home", 0755);
Node lib = fs->Create(linux, "lib", 0755);
Node lib64 = fs->Create(linux, "lib64", 0755);
Node media = fs->Create(linux, "media", 0755);
Node mnt = fs->Create(linux, "mnt", 0755);
Node opt = fs->Create(linux, "opt", 0755);
Node proc = fs->Create(linux, "proc", 0755);
UNUSED(bin);
UNUSED(boot);
UNUSED(dev);
UNUSED(etc);
UNUSED(home);
UNUSED(lib);
UNUSED(lib64);
UNUSED(media);
UNUSED(mnt);
UNUSED(opt);
UNUSED(proc);
}
void InitializeSubSystem()
{
if (fs->RootExists(1) == false)
{
FileNode *nmnt = fs->GetByPath("/mnt", fs->GetRoot(0));
assert(MountRAMFS(nmnt, "linux", 1));
FileNode *linux = fs->GetRoot(1);
Node root = fs->GetRoot(0);
Node cfg = fs->Lookup(root, "/sys/cfg/subsystem/linux");
if (cfg)
{
struct kstat st;
fs->Stat(cfg, &st);
FileNode *bin = fs->ForceCreate(linux, "bin", 0755);
FileNode *boot = fs->ForceCreate(linux, "boot", 0755);
FileNode *dev = fs->ForceCreate(linux, "dev", 0755);
FileNode *etc = fs->ForceCreate(linux, "etc", 0755);
FileNode *home = fs->ForceCreate(linux, "home", 0755);
FileNode *lib = fs->ForceCreate(linux, "lib", 0755);
FileNode *lib64 = fs->ForceCreate(linux, "lib64", 0755);
FileNode *media = fs->ForceCreate(linux, "media", 0755);
FileNode *mnt = fs->ForceCreate(linux, "mnt", 0755);
FileNode *opt = fs->ForceCreate(linux, "opt", 0755);
FileNode *proc = fs->ForceCreate(linux, "proc", 0755);
std::unique_ptr<char[]> buf(new char[st.Size]);
fs->Read(cfg, buf.get(), st.Size, 0);
UNUSED(bin);
UNUSED(boot);
UNUSED(dev);
UNUSED(etc);
UNUSED(home);
UNUSED(lib);
UNUSED(lib64);
UNUSED(media);
UNUSED(mnt);
UNUSED(opt);
UNUSED(proc);
ini_t *ini = ini_load(buf.get(), NULL);
int section = ini_find_section(ini, "rootfs", NULL);
int pathIdx = ini_find_property(ini, section, "path", NULL);
const char *uPath = ini_property_value(ini, section, pathIdx);
debug("path=%s", uPath);
ini_destroy(ini);
if (fs->Lookup(root, uPath) != false)
{
root = fs->Lookup(root, uPath);
// if (TestAndInitializeUSTAR(moduleAddress, moduleSize, 0))
// {
// }
}
else
{
warn("Couldn't find rootfs path %s", uPath);
__CreateStubRoot();
}
}
else
{
warn("Couldn't open /sys/cfg/subsystem/linux");
__CreateStubRoot();
}
}
}
}

View File

@ -816,7 +816,7 @@ static int linux_open(SysFrm *sf, const char *pathname, int flags, mode_t mode)
if (flags & 0200000 /* O_DIRECTORY */)
{
FileNode *node = fs->GetByPath(pPathname, pcb->CWD);
Node node = fs->Lookup(pcb->CWD, pPathname);
if (node == nullptr)
{
debug("Couldn't find %s", pPathname);
@ -1313,7 +1313,7 @@ static int linux_access(SysFrm *, const char *pathname, int mode)
debug("access(%s, %d)", (char *)pPathname, mode);
if (!fs->PathExists(pPathname, pcb->CWD))
if (!fs->Lookup(pcb->CWD, pPathname))
return -linux_ENOENT;
stub;
@ -1717,7 +1717,7 @@ __no_sanitize("undefined") static int linux_execve(SysFrm *sf, const char *pathn
safeEnvp[i + 1] = nullptr;
}
FileNode *file = fs->GetByPath(pPathname, pcb->CWD);
Node file = fs->Lookup(pcb->CWD, pPathname);
if (!file)
{
@ -1726,7 +1726,7 @@ __no_sanitize("undefined") static int linux_execve(SysFrm *sf, const char *pathn
}
char shebangMagic[2]{};
file->Read((uint8_t *)shebangMagic, 2, 0);
fs->Read(file, (uint8_t *)shebangMagic, 2, 0);
if (shebangMagic[0] == '#' && shebangMagic[1] == '!')
{
@ -1740,7 +1740,7 @@ __no_sanitize("undefined") static int linux_execve(SysFrm *sf, const char *pathn
while (true)
{
char c;
if (file->Read((uint8_t *)&c, 1, shebangOffset) == 0)
if (fs->Read(file, (uint8_t *)&c, 1, shebangOffset) == 0)
break;
if (c == '\n' || shebangLength == shebangLengthMax)
break;
@ -1870,7 +1870,7 @@ __no_sanitize("undefined") static int linux_execve(SysFrm *sf, const char *pathn
cwk_path_get_basename(pPathname, &baseName, nullptr);
pcb->Rename(baseName);
pcb->SetWorkingDirectory(file->Parent);
pcb->SetWorkingDirectory(fs->Convert(file->Parent));
pcb->SetExe(pPathname);
Tasking::Task *ctx = pcb->GetContext();
@ -2208,14 +2208,15 @@ static int linux_uname(SysFrm *, struct utsname *buf)
#endif
};
FileNode *rn = fs->GetByPath("/sys/cfg/cross/linux", pcb->Info.RootNode);
Node root = fs->GetRoot(0);
Node rn = fs->Lookup(root, "/sys/cfg/subsystem/linux");
if (rn)
{
struct kstat st{};
rn->Stat(&st);
struct kstat st;
fs->Stat(rn, &st);
char *sh = new char[st.Size];
rn->Read(sh, st.Size, 0);
fs->Read(rn, sh, st.Size, 0);
ini_t *ini = ini_load(sh, NULL);
int section = ini_find_section(ini, "uname", NULL);
@ -2250,7 +2251,7 @@ static int linux_uname(SysFrm *, struct utsname *buf)
delete[] sh;
}
else
warn("Couldn't open /sys/cfg/cross/linux");
warn("Couldn't open /sys/cfg/subsystem/linux");
memcpy(pBuf, &uname, sizeof(struct utsname));
return 0;
@ -2360,7 +2361,7 @@ static int linux_chdir(SysFrm *, const char *path)
if (!pPath)
return -linux_EFAULT;
FileNode *n = fs->GetByPath(pPath, pcb->CWD);
Node n = fs->Lookup(pcb->CWD, pPath);
if (!n)
return -linux_ENOENT;
@ -2378,8 +2379,8 @@ static int linux_fchdir(SysFrm *, int fd)
if (it == fdt->FileMap.end())
return -linux_EBADF;
pcb->SetWorkingDirectory(it->second.Node);
debug("Changed cwd to \"%s\"", it->second.Node->GetPath().c_str());
pcb->SetWorkingDirectory(it->second.node);
debug("Changed cwd to \"%s\"", it->second.node->GetPath().c_str());
return 0;
}
@ -2395,7 +2396,7 @@ static int linux_mkdir(SysFrm *, const char *pathname, mode_t mode)
mode &= ~pcb->FileCreationMask & 0777;
FileNode *n = fs->Create(pcb->CWD, pPathname, mode);
Node n = fs->Create(pcb->CWD, pPathname, mode);
if (!n)
return -linux_EEXIST;
return 0;
@ -2432,13 +2433,13 @@ static ssize_t linux_readlink(SysFrm *, const char *pathname,
ReturnLogError(-linux_EBADF, "Invalid fd %d", fd);
vfs::FileDescriptorTable::Fildes &fildes = it->second;
FileNode *node = fildes.Node;
Node node = fildes.node;
fdt->usr_close(fd);
if (!node->IsSymbolicLink())
return -linux_EINVAL;
return ConvertErrnoToLinux(node->ReadLink(pBuf, bufsiz));
return ConvertErrnoToLinux(fs->ReadLink(node, pBuf, bufsiz));
}
static int linux_fchmod(SysFrm *, int fd, mode_t mode)
@ -2480,7 +2481,7 @@ static int linux_chmod(SysFrm *sf, const char *pathname, mode_t mode)
if (pPathname == nullptr)
return -linux_EFAULT;
FileNode *node = fs->GetByPath(pPathname, pcb->CWD);
Node node = fs->Lookup(pcb->CWD, pPathname);
if (!node)
return -linux_ENOENT;
@ -3114,7 +3115,7 @@ __no_sanitize("undefined") static ssize_t linux_getdents64(SysFrm *,
}
vfs::FileDescriptorTable::Fildes &fildes = it->second;
if (!fildes.Node->IsDirectory())
if (!fildes.node->IsDirectory())
{
debug("Not a directory");
return -ENOTDIR;
@ -3138,8 +3139,7 @@ __no_sanitize("undefined") static ssize_t linux_getdents64(SysFrm *,
#endif
/* The structs are the same, no need for conversion. */
ssize_t ret = fildes.Node->ReadDir((struct kdirent *)pDirp, count, fildes.Offset,
count / sizeof(kdirent));
ssize_t ret = fs->ReadDirectory(fildes.node, (struct kdirent *)pDirp, count, fildes.Offset, count / sizeof(kdirent));
if (ret > 0)
fildes.Offset += ret;
@ -3324,7 +3324,7 @@ static int linux_openat(SysFrm *, int dirfd, const char *pathname, int flags, mo
if (dirfd == linux_AT_FDCWD)
{
FileNode *absoluteNode = fs->GetByPath(pPathname, pcb->CWD);
Node absoluteNode = fs->Lookup(pcb->CWD, pPathname);
if (!absoluteNode)
return -linux_ENOENT;
@ -3373,7 +3373,7 @@ static long linux_newfstatat(SysFrm *, int dirfd, const char *pathname,
case linux_AT_FDCWD:
{
debug("dirfd is AT_FDCWD for \"%s\"", pPathname);
FileNode *node = fs->GetByPath(pPathname, pcb->CWD);
Node node = fs->Lookup(pcb->CWD, pPathname);
if (!node)
return -linux_ENOENT;
@ -3390,7 +3390,7 @@ static long linux_newfstatat(SysFrm *, int dirfd, const char *pathname,
ReturnLogError(-linux_EBADF, "Invalid fd %d", dirfd);
vfs::FileDescriptorTable::Fildes &fildes = it->second;
FileNode *node = fs->GetByPath(pPathname, fildes.Node);
Node node = fs->Lookup(fildes.node, pPathname);
debug("node: %s", node->GetPath().c_str());
if (!node)
return -linux_ENOENT;

View File

@ -15,7 +15,7 @@
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#include <filesystem/ramfs.hpp>
#include <fs/ramfs.hpp>
#include "../../kernel.h"
@ -23,25 +23,30 @@ namespace Subsystem::Windows
{
bool Initialized = false;
void __CreateStubRoot()
{
Node root = fs->GetRoot(0);
Node nmnt = fs->Lookup(root, "/mnt");
assert(MountAndRootRAMFS(nmnt, "windows", 2));
Node win = fs->GetRoot(2);
Node windows = fs->Create(win, "Windows", 0755);
Node programFiles = fs->Create(windows, "Program Files", 0755);
Node programFilesX86 = fs->Create(windows, "Program Files (x86)", 0755);
Node programData = fs->Create(windows, "ProgramData", 0755);
Node users = fs->Create(windows, "Users", 0755);
UNUSED(windows);
UNUSED(programFiles);
UNUSED(programFilesX86);
UNUSED(programData);
UNUSED(users);
}
void InitializeSubSystem()
{
if (fs->RootExists(2) == false)
{
FileNode *nmnt = fs->GetByPath("/mnt", fs->GetRoot(0));
assert(MountRAMFS(nmnt, "windows", 2));
FileNode *win = fs->GetRoot(2);
FileNode *windows = fs->ForceCreate(win, "Windows", 0755);
FileNode *programFiles = fs->ForceCreate(windows, "Program Files", 0755);
FileNode *programFilesX86 = fs->ForceCreate(windows, "Program Files (x86)", 0755);
FileNode *programData = fs->ForceCreate(windows, "ProgramData", 0755);
FileNode *users = fs->ForceCreate(windows, "Users", 0755);
UNUSED(windows);
UNUSED(programFiles);
UNUSED(programFilesX86);
UNUSED(programData);
UNUSED(users);
}
}
}