mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-30 08:17:58 +00:00
fix(kernel/vfs): support multiple roots
This commit is contained in:
parent
a1b58bacd8
commit
3315d79742
@ -132,7 +132,7 @@ namespace vfs
|
|||||||
|
|
||||||
FileNode *CacheSearchReturnLast(FileNode *Parent, const char **Path);
|
FileNode *CacheSearchReturnLast(FileNode *Parent, const char **Path);
|
||||||
FileNode *CacheRecursiveSearch(FileNode *Root, const char *NameOrPath, bool IsName);
|
FileNode *CacheRecursiveSearch(FileNode *Root, const char *NameOrPath, bool IsName);
|
||||||
FileNode *CacheLookup(const char *Path);
|
FileNode *CacheLookup(FileNode *Parent, const char *Path);
|
||||||
FileNode *CreateCacheNode(FileNode *Parent, Inode *Node, const char *Name, mode_t Mode);
|
FileNode *CreateCacheNode(FileNode *Parent, Inode *Node, const char *Name, mode_t Mode);
|
||||||
|
|
||||||
int RemoveCacheNode(FileNode *Node);
|
int RemoveCacheNode(FileNode *Node);
|
||||||
|
@ -131,6 +131,7 @@ namespace vfs
|
|||||||
public:
|
public:
|
||||||
dev_t DeviceID = -1;
|
dev_t DeviceID = -1;
|
||||||
ino_t NextInode = 0;
|
ino_t NextInode = 0;
|
||||||
|
std::string RootName;
|
||||||
|
|
||||||
int Lookup(struct Inode *Parent, const char *Name, struct Inode **Result);
|
int Lookup(struct Inode *Parent, const char *Name, struct Inode **Result);
|
||||||
int Create(struct Inode *Parent, const char *Name, mode_t Mode, struct Inode **Result);
|
int Create(struct Inode *Parent, const char *Name, mode_t Mode, struct Inode **Result);
|
||||||
@ -146,4 +147,4 @@ namespace vfs
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MountRAMFS(Inode *Parent, const char *Name, size_t Index);
|
bool MountRAMFS(FileNode *Parent, const char *Name, size_t Index);
|
||||||
|
31
Kernel/include/subsystems.hpp
Normal file
31
Kernel/include/subsystems.hpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Fennix Kernel.
|
||||||
|
|
||||||
|
Fennix Kernel is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
Fennix Kernel is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Subsystem
|
||||||
|
{
|
||||||
|
namespace Linux
|
||||||
|
{
|
||||||
|
void InitializeSubSystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Windows
|
||||||
|
{
|
||||||
|
void InitializeSubSystem();
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <filesystem/ustar.hpp>
|
#include <filesystem/ustar.hpp>
|
||||||
|
#include <subsystems.hpp>
|
||||||
#include <kshell.hpp>
|
#include <kshell.hpp>
|
||||||
#include <power.hpp>
|
#include <power.hpp>
|
||||||
#include <lock.hpp>
|
#include <lock.hpp>
|
||||||
@ -69,12 +70,13 @@ int SpawnLinuxInit()
|
|||||||
"/startup/init"};
|
"/startup/init"};
|
||||||
|
|
||||||
const char *foundPath = nullptr;
|
const char *foundPath = nullptr;
|
||||||
|
FileNode *root = fs->GetRoot(1);
|
||||||
for (const std::string &path : fallbackPaths)
|
for (const std::string &path : fallbackPaths)
|
||||||
{
|
{
|
||||||
if (!fs->PathExists(path.c_str(), fs->GetRoot(1)))
|
const char *str = path.c_str();
|
||||||
|
if (!fs->PathExists(str, root))
|
||||||
continue;
|
continue;
|
||||||
|
foundPath = str;
|
||||||
foundPath = path.c_str();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,6 +137,10 @@ void KernelMainThread()
|
|||||||
// ->Rename("Kernel Shell");
|
// ->Rename("Kernel Shell");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
KPrint("Loading Subsystems");
|
||||||
|
Subsystem::Linux::InitializeSubSystem();
|
||||||
|
Subsystem::Windows::InitializeSubSystem();
|
||||||
|
|
||||||
KPrint("Executing %s", Config.InitPath);
|
KPrint("Executing %s", Config.InitPath);
|
||||||
int ExitCode = -1;
|
int ExitCode = -1;
|
||||||
Tasking::PCB *initProc;
|
Tasking::PCB *initProc;
|
||||||
@ -164,9 +170,7 @@ Exit:
|
|||||||
|
|
||||||
KPrint("Dropping to kernel shell");
|
KPrint("Dropping to kernel shell");
|
||||||
TaskManager->Sleep(1000);
|
TaskManager->Sleep(1000);
|
||||||
TaskManager->CreateThread(thisProcess,
|
TaskManager->CreateThread(thisProcess, Tasking::IP(KShellThread))->Rename("Kernel Shell");
|
||||||
Tasking::IP(KShellThread))
|
|
||||||
->Rename("Kernel Shell");
|
|
||||||
CPU::Halt(true);
|
CPU::Halt(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,12 +175,13 @@ namespace vfs
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileNode *Virtual::CacheLookup(const char *Path)
|
FileNode *Virtual::CacheLookup(FileNode *Parent, const char *Path)
|
||||||
{
|
{
|
||||||
debug("Cache lookup for \"%s\"", Path);
|
debug("Cache lookup for \"%s\"", Path);
|
||||||
FileNode *rootNode = thisProcess ? thisProcess->Info.RootNode : this->GetRoot(0);
|
if (Parent == nullptr)
|
||||||
|
Parent = thisProcess ? thisProcess->Info.RootNode : this->GetRoot(0);
|
||||||
|
|
||||||
FileNode *ret = CacheRecursiveSearch(rootNode, Path, false);
|
FileNode *ret = CacheRecursiveSearch(Parent, Path, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -137,14 +137,22 @@ namespace vfs
|
|||||||
{
|
{
|
||||||
char *path = strdup(Path);
|
char *path = strdup(Path);
|
||||||
char *lastSlash = strrchr(path, '/');
|
char *lastSlash = strrchr(path, '/');
|
||||||
|
if (lastSlash)
|
||||||
|
{
|
||||||
if (lastSlash == path)
|
if (lastSlash == path)
|
||||||
lastSlash++;
|
lastSlash++;
|
||||||
*lastSlash = '\0';
|
*lastSlash = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
FileNode *parentNode = this->GetByPath(path, Parent);
|
FileNode *parentNode = this->GetByPath(path, Parent);
|
||||||
|
if (parentNode == nullptr && Parent != nullptr)
|
||||||
|
parentNode = Parent;
|
||||||
free(path);
|
free(path);
|
||||||
lastSlash = strrchr(Path, '/');
|
lastSlash = strrchr(Path, '/');
|
||||||
|
if (lastSlash)
|
||||||
lastSlash++;
|
lastSlash++;
|
||||||
|
else
|
||||||
|
lastSlash = (char *)Path;
|
||||||
return this->CreateCacheNode(parentNode, Node, lastSlash, Node->Mode);
|
return this->CreateCacheNode(parentNode, Node, lastSlash, Node->Mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,8 +168,13 @@ namespace vfs
|
|||||||
FileNode *Virtual::GetByPath(const char *Path, FileNode *Parent)
|
FileNode *Virtual::GetByPath(const char *Path, FileNode *Parent)
|
||||||
{
|
{
|
||||||
debug("GetByPath: %s", Path);
|
debug("GetByPath: %s", Path);
|
||||||
if (Parent == nullptr || this->PathIsAbsolute(Path))
|
if (Parent == nullptr)
|
||||||
|
{
|
||||||
|
if (fs->PathIsRelative(Path))
|
||||||
|
Parent = thisProcess ? thisProcess->CWD : thisProcess->Info.RootNode;
|
||||||
|
else
|
||||||
Parent = thisProcess ? thisProcess->Info.RootNode : this->GetRoot(0);
|
Parent = thisProcess ? thisProcess->Info.RootNode : this->GetRoot(0);
|
||||||
|
}
|
||||||
|
|
||||||
if (strcmp(Path, ".") == 0)
|
if (strcmp(Path, ".") == 0)
|
||||||
return Parent;
|
return Parent;
|
||||||
@ -214,6 +227,7 @@ namespace vfs
|
|||||||
auto it = DeviceMap.find(__Parent->Node->Device);
|
auto it = DeviceMap.find(__Parent->Node->Device);
|
||||||
if (unlikely(it == DeviceMap.end()))
|
if (unlikely(it == DeviceMap.end()))
|
||||||
ReturnLogError(nullptr, "Device %d not found", __Parent->Node->Device);
|
ReturnLogError(nullptr, "Device %d not found", __Parent->Node->Device);
|
||||||
|
debug("found fs %s", it->second.fsi->Name);
|
||||||
|
|
||||||
if (it->second.fsi->Ops.Lookup == NULL)
|
if (it->second.fsi->Ops.Lookup == NULL)
|
||||||
ReturnLogError(nullptr, "Lookup not supported for %d", it->first);
|
ReturnLogError(nullptr, "Lookup not supported for %d", it->first);
|
||||||
@ -321,7 +335,7 @@ namespace vfs
|
|||||||
|
|
||||||
bool Virtual::PathExists(const char *Path, FileNode *Parent)
|
bool Virtual::PathExists(const char *Path, FileNode *Parent)
|
||||||
{
|
{
|
||||||
FileNode *fn = this->CacheLookup(Path);
|
FileNode *fn = this->CacheLookup(Parent, Path);
|
||||||
if (fn)
|
if (fn)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ namespace vfs
|
|||||||
cwk_path_get_basename(Name, &basename, &length);
|
cwk_path_get_basename(Name, &basename, &length);
|
||||||
if (basename == NULL)
|
if (basename == NULL)
|
||||||
{
|
{
|
||||||
if (strcmp(Name, "/") == 0)
|
if (strcmp(Name, RootName.c_str()) == 0)
|
||||||
{
|
{
|
||||||
auto &it = Files.at(0);
|
auto &it = Files.at(0);
|
||||||
*Result = &it->Node;
|
*Result = &it->Node;
|
||||||
@ -90,6 +90,7 @@ namespace vfs
|
|||||||
RAMFSInode *node = new RAMFSInode;
|
RAMFSInode *node = new RAMFSInode;
|
||||||
node->Name.assign(basename, length);
|
node->Name.assign(basename, length);
|
||||||
node->Mode = Mode;
|
node->Mode = Mode;
|
||||||
|
node->Node = inode;
|
||||||
|
|
||||||
auto file = Files.insert(std::make_pair(NextInode, node));
|
auto file = Files.insert(std::make_pair(NextInode, node));
|
||||||
assert(file.second == true);
|
assert(file.second == true);
|
||||||
@ -383,25 +384,15 @@ O2 int __ramfs_Destroy(FileSystemInfo *fsi)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MountRAMFS(Inode *Parent, const char *Name, size_t Index)
|
bool MountRAMFS(FileNode *Parent, const char *Name, size_t Index)
|
||||||
{
|
{
|
||||||
vfs::RAMFS *ramfs = new vfs::RAMFS;
|
vfs::RAMFS *ramfs = new vfs::RAMFS;
|
||||||
ramfs->DeviceID = fs->EarlyReserveDevice();
|
ramfs->DeviceID = fs->EarlyReserveDevice();
|
||||||
|
ramfs->RootName.assign(Name);
|
||||||
if (Parent == nullptr)
|
|
||||||
{
|
|
||||||
ramfs->Create(nullptr, Name, S_IFDIR | 0755, &Parent);
|
|
||||||
if (Parent == nullptr)
|
|
||||||
{
|
|
||||||
error("Failed to create root inode");
|
|
||||||
delete ramfs;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FileSystemInfo *fsi = new FileSystemInfo;
|
FileSystemInfo *fsi = new FileSystemInfo;
|
||||||
fsi->Name = "ramfs";
|
fsi->Name = "ramfs";
|
||||||
fsi->RootName = "/";
|
fsi->RootName = Name;
|
||||||
fsi->Flags = I_FLAG_ROOT | I_FLAG_MOUNTPOINT | I_FLAG_CACHE_KEEP;
|
fsi->Flags = I_FLAG_ROOT | I_FLAG_MOUNTPOINT | I_FLAG_CACHE_KEEP;
|
||||||
fsi->SuperOps.DeleteInode = __ramfs_DestroyInode;
|
fsi->SuperOps.DeleteInode = __ramfs_DestroyInode;
|
||||||
fsi->SuperOps.Destroy = __ramfs_Destroy;
|
fsi->SuperOps.Destroy = __ramfs_Destroy;
|
||||||
@ -415,7 +406,12 @@ bool MountRAMFS(Inode *Parent, const char *Name, size_t Index)
|
|||||||
fsi->Ops.Stat = __ramfs_Stat;
|
fsi->Ops.Stat = __ramfs_Stat;
|
||||||
fsi->PrivateData = ramfs;
|
fsi->PrivateData = ramfs;
|
||||||
|
|
||||||
fs->LateRegisterFileSystem(ramfs->DeviceID, fsi, Parent);
|
Inode *root = nullptr;
|
||||||
fs->AddRootAt(Parent, Index);
|
ramfs->Create(nullptr, Name, S_IFDIR | 0755, &root);
|
||||||
|
|
||||||
|
fs->LateRegisterFileSystem(ramfs->DeviceID, fsi, root);
|
||||||
|
fs->AddRootAt(root, Index);
|
||||||
|
|
||||||
|
fs->Mount(Parent, root, Name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <filesystem/ramfs.hpp>
|
||||||
|
|
||||||
#include "../../kernel.h"
|
#include "../../kernel.h"
|
||||||
|
|
||||||
namespace Subsystem::Linux
|
namespace Subsystem::Linux
|
||||||
@ -23,5 +25,23 @@ namespace Subsystem::Linux
|
|||||||
|
|
||||||
void InitializeSubSystem()
|
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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <filesystem/ramfs.hpp>
|
||||||
|
|
||||||
#include "../../kernel.h"
|
#include "../../kernel.h"
|
||||||
|
|
||||||
namespace Subsystem::Windows
|
namespace Subsystem::Windows
|
||||||
@ -23,5 +25,17 @@ namespace Subsystem::Windows
|
|||||||
|
|
||||||
void InitializeSubSystem()
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -588,20 +588,18 @@ namespace Tasking
|
|||||||
switch (Compatibility)
|
switch (Compatibility)
|
||||||
{
|
{
|
||||||
case TaskCompatibility::Native:
|
case TaskCompatibility::Native:
|
||||||
// this->Info.RootNode = fs->FileSystemRoots->GetChildren()[0];
|
this->Info.RootNode = fs->GetRoot(0);
|
||||||
break;
|
break;
|
||||||
case TaskCompatibility::Linux:
|
case TaskCompatibility::Linux:
|
||||||
// this->Info.RootNode = fs->FileSystemRoots->GetChildren()[1];
|
this->Info.RootNode = fs->GetRoot(1);
|
||||||
break;
|
break;
|
||||||
case TaskCompatibility::Windows:
|
case TaskCompatibility::Windows:
|
||||||
// this->Info.RootNode = fs->FileSystemRoots->GetChildren()[2];
|
this->Info.RootNode = fs->GetRoot(2);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(!"Invalid compatibility mode");
|
assert(!"Invalid compatibility mode");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* FIXME */
|
|
||||||
this->Info.RootNode = fs->GetRoot(0);
|
|
||||||
|
|
||||||
if (this->Parent->Threads.size() == 0)
|
if (this->Parent->Threads.size() == 0)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user