mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-25 22:14:34 +00:00
fix(kernel/vfs): ✨ fully implement ustar driver implementation + mounting system
This commit is contained in:
parent
70a08e46bd
commit
f06c0b19fa
@ -323,6 +323,28 @@ struct InodeOperations
|
|||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct FileSystemInfo;
|
struct FileSystemInfo;
|
||||||
|
|
||||||
|
struct FileSystemDevice
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @brief Inode
|
||||||
|
*
|
||||||
|
* If the device is a block device, this will be NULL.
|
||||||
|
*/
|
||||||
|
struct Inode *node;
|
||||||
|
struct InodeOperations *ops;
|
||||||
|
} inode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Block Device
|
||||||
|
*
|
||||||
|
* If the device is a block device, this will be non-NULL.
|
||||||
|
*/
|
||||||
|
struct BlockDevice *Block;
|
||||||
|
};
|
||||||
|
|
||||||
struct SuperBlockOperations
|
struct SuperBlockOperations
|
||||||
{
|
{
|
||||||
int (*AllocateInode)(struct FileSystemInfo *Info, struct Inode **Result);
|
int (*AllocateInode)(struct FileSystemInfo *Info, struct Inode **Result);
|
||||||
@ -360,7 +382,7 @@ struct SuperBlockOperations
|
|||||||
*
|
*
|
||||||
* @return Zero on success, otherwise an error code.
|
* @return Zero on success, otherwise an error code.
|
||||||
*/
|
*/
|
||||||
int (*Probe)(void *Device);
|
int (*Probe)(struct FileSystemDevice *Device);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mount the filesystem.
|
* Mount the filesystem.
|
||||||
@ -369,11 +391,11 @@ struct SuperBlockOperations
|
|||||||
*
|
*
|
||||||
* @param FS Filesystem to mount.
|
* @param FS Filesystem to mount.
|
||||||
* @param Root Pointer to the root inode.
|
* @param Root Pointer to the root inode.
|
||||||
* @param Device Device to mount.
|
* @param Device Device to mount. This pointer will be undefined after the function returns!
|
||||||
*
|
*
|
||||||
* @return Zero on success, otherwise an error code.
|
* @return Zero on success, otherwise an error code.
|
||||||
*/
|
*/
|
||||||
int (*Mount)(struct FileSystemInfo *FS, struct Inode **Root, void *Device);
|
int (*Mount)(struct FileSystemInfo *FS, struct Inode **Root, struct FileSystemDevice *Device);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unmount the filesystem.
|
* Unmount the filesystem.
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -524,6 +524,26 @@ namespace vfs
|
|||||||
return Target->__Close();
|
return Target->__Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FileSystemInfo *Virtual::Probe(FileSystemDevice *Device)
|
||||||
|
{
|
||||||
|
for (auto &&i : FileSystems)
|
||||||
|
{
|
||||||
|
if (i.second->SuperOps.Probe == nullptr)
|
||||||
|
{
|
||||||
|
debug("%s does not support probing", i.second->Name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = i.second->SuperOps.Probe(Device);
|
||||||
|
if (ret == 0)
|
||||||
|
return i.second;
|
||||||
|
debug("%s returned %d", i.second->Name, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("No filesystems matched");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
eNode Virtual::Mount(Node &Parent, Inode *inode, std::string Name, FileSystemInfo *fsi)
|
eNode Virtual::Mount(Node &Parent, Inode *inode, std::string Name, FileSystemInfo *fsi)
|
||||||
{
|
{
|
||||||
assert(Parent);
|
assert(Parent);
|
||||||
@ -541,6 +561,27 @@ namespace vfs
|
|||||||
return {ret, 0};
|
return {ret, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eNode Virtual::Mount(Node &Parent, std::string Name, FileSystemInfo *fsi, FileSystemDevice *Device)
|
||||||
|
{
|
||||||
|
Inode *inode;
|
||||||
|
int ret = fsi->SuperOps.Mount(fsi, &inode, Device);
|
||||||
|
if (ret != 0)
|
||||||
|
return {nullptr, ret};
|
||||||
|
|
||||||
|
return this->Mount(Parent, inode, Name, fsi);
|
||||||
|
|
||||||
|
// Node node = std::make_shared<NodeCache>();
|
||||||
|
// node->inode = nullptr; /* FIXME: ??? */
|
||||||
|
// node->fsi = fsi;
|
||||||
|
// node->Flags.MountPoint = true;
|
||||||
|
|
||||||
|
// node->Name = Name;
|
||||||
|
// node->Path = fs->NormalizePath(Parent, Parent->Path + "/" + Name);
|
||||||
|
// node->Parent = Parent;
|
||||||
|
// Parent->Children.push_back(node);
|
||||||
|
// return {node, 0};
|
||||||
|
}
|
||||||
|
|
||||||
int Virtual::Umount(Node &node)
|
int Virtual::Umount(Node &node)
|
||||||
{
|
{
|
||||||
if (!node->Flags.MountPoint)
|
if (!node->Flags.MountPoint)
|
||||||
|
@ -128,25 +128,25 @@ namespace vfs
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read directory entries
|
* @brief Read directory entries
|
||||||
*
|
*
|
||||||
* @note This function includes "." and ".."
|
* @note This function includes "." and ".."
|
||||||
*
|
*
|
||||||
* @param Target
|
* @param Target
|
||||||
* @param Buffer
|
* @param Buffer
|
||||||
* @param Size
|
* @param Size
|
||||||
* @param Offset
|
* @param Offset
|
||||||
* @param Entries
|
* @param Entries
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ssize_t ReadDirectory(Node &Target, kdirent *Buffer, size_t Size, off_t Offset, off_t Entries);
|
ssize_t ReadDirectory(Node &Target, kdirent *Buffer, size_t Size, off_t Offset, off_t Entries);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read directory entries
|
* @brief Read directory entries
|
||||||
*
|
*
|
||||||
* @note This function does NOT include "." and ".."
|
* @note This function does NOT include "." and ".."
|
||||||
*
|
*
|
||||||
* @param Target
|
* @param Target
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
std::list<Node> ReadDirectory(Node &Target);
|
std::list<Node> ReadDirectory(Node &Target);
|
||||||
|
|
||||||
@ -165,8 +165,76 @@ namespace vfs
|
|||||||
|
|
||||||
#pragma region Mounting
|
#pragma region Mounting
|
||||||
|
|
||||||
|
FileSystemInfo *Probe(FileSystemDevice *Device);
|
||||||
|
|
||||||
|
FileSystemInfo *Probe(Node &node)
|
||||||
|
{
|
||||||
|
FileSystemDevice dev;
|
||||||
|
dev.inode.node = node->inode;
|
||||||
|
dev.inode.ops = &node->fsi->Ops;
|
||||||
|
dev.Block = nullptr;
|
||||||
|
return this->Probe(&dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSystemInfo *Probe(BlockDevice *Device)
|
||||||
|
{
|
||||||
|
FileSystemDevice dev;
|
||||||
|
dev.inode.node = nullptr;
|
||||||
|
dev.inode.ops = nullptr;
|
||||||
|
dev.Block = Device;
|
||||||
|
return this->Probe(&dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Mount a filesystem
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param Parent Parent Node
|
||||||
|
* @param inode Inode from the filesystem as root of the mount point
|
||||||
|
* @param Name Name of the mount point
|
||||||
|
* @param fsi FileSystemInfo structure
|
||||||
|
* @return eNode{Node, errno}
|
||||||
|
*/
|
||||||
eNode Mount(Node &Parent, Inode *inode, std::string Name, FileSystemInfo *fsi);
|
eNode Mount(Node &Parent, Inode *inode, std::string Name, FileSystemInfo *fsi);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Mount a filesystem
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param Parent Parent Node
|
||||||
|
* @param Name Name of the mount point
|
||||||
|
* @param fsi FileSystemInfo structure
|
||||||
|
* @param Device Device to mount
|
||||||
|
* @return eNode{Node, errno}
|
||||||
|
*/
|
||||||
|
eNode Mount(Node &Parent, std::string Name, FileSystemInfo *fsi, FileSystemDevice *Device);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for Mount(Node &Parent, std::string Name, FileSystemInfo *fsi, FileSystemDevice *Device)
|
||||||
|
*/
|
||||||
|
eNode Mount(Node &Parent, std::string Name, FileSystemInfo *fsi, Node Device)
|
||||||
|
{
|
||||||
|
FileSystemDevice dev;
|
||||||
|
dev.inode.node = Device->inode;
|
||||||
|
dev.inode.ops = &Device->fsi->Ops;
|
||||||
|
dev.Block = nullptr;
|
||||||
|
return this->Mount(Parent, Name, fsi, &dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for Mount(Node &Parent, std::string Name, FileSystemInfo *fsi, FileSystemDevice *Device)
|
||||||
|
*/
|
||||||
|
eNode Mount(Node &Parent, std::string Name, FileSystemInfo *fsi, BlockDevice *Device)
|
||||||
|
{
|
||||||
|
FileSystemDevice dev;
|
||||||
|
dev.inode.node = nullptr;
|
||||||
|
dev.inode.ops = nullptr;
|
||||||
|
dev.Block = Device;
|
||||||
|
return this->Mount(Parent, Name, fsi, &dev);
|
||||||
|
}
|
||||||
|
|
||||||
int Umount(Node &node);
|
int Umount(Node &node);
|
||||||
int Umount(Node &Parent, std::string Name);
|
int Umount(Node &Parent, std::string Name);
|
||||||
|
|
||||||
|
@ -323,6 +323,28 @@ struct InodeOperations
|
|||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct FileSystemInfo;
|
struct FileSystemInfo;
|
||||||
|
|
||||||
|
struct FileSystemDevice
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @brief Inode
|
||||||
|
*
|
||||||
|
* If the device is a block device, this will be NULL.
|
||||||
|
*/
|
||||||
|
struct Inode *node;
|
||||||
|
struct InodeOperations *ops;
|
||||||
|
} inode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Block Device
|
||||||
|
*
|
||||||
|
* If the device is a block device, this will be non-NULL.
|
||||||
|
*/
|
||||||
|
struct BlockDevice *Block;
|
||||||
|
};
|
||||||
|
|
||||||
struct SuperBlockOperations
|
struct SuperBlockOperations
|
||||||
{
|
{
|
||||||
int (*AllocateInode)(struct FileSystemInfo *Info, struct Inode **Result);
|
int (*AllocateInode)(struct FileSystemInfo *Info, struct Inode **Result);
|
||||||
@ -360,7 +382,7 @@ struct SuperBlockOperations
|
|||||||
*
|
*
|
||||||
* @return Zero on success, otherwise an error code.
|
* @return Zero on success, otherwise an error code.
|
||||||
*/
|
*/
|
||||||
int (*Probe)(void *Device);
|
int (*Probe)(struct FileSystemDevice *Device);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mount the filesystem.
|
* Mount the filesystem.
|
||||||
@ -369,11 +391,11 @@ struct SuperBlockOperations
|
|||||||
*
|
*
|
||||||
* @param FS Filesystem to mount.
|
* @param FS Filesystem to mount.
|
||||||
* @param Root Pointer to the root inode.
|
* @param Root Pointer to the root inode.
|
||||||
* @param Device Device to mount.
|
* @param Device Device to mount. This pointer will be undefined after the function returns!
|
||||||
*
|
*
|
||||||
* @return Zero on success, otherwise an error code.
|
* @return Zero on success, otherwise an error code.
|
||||||
*/
|
*/
|
||||||
int (*Mount)(struct FileSystemInfo *FS, struct Inode **Root, void *Device);
|
int (*Mount)(struct FileSystemInfo *FS, struct Inode **Root, struct FileSystemDevice *Device);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unmount the filesystem.
|
* Unmount the filesystem.
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include <fs/ramfs.hpp>
|
#include <fs/ramfs.hpp>
|
||||||
|
|
||||||
#include "../../kernel.h"
|
#include "../../kernel.h"
|
||||||
#include <fs/ustar.hpp>
|
|
||||||
#include <ini.h>
|
#include <ini.h>
|
||||||
|
|
||||||
namespace Subsystem::Linux
|
namespace Subsystem::Linux
|
||||||
@ -78,13 +77,21 @@ namespace Subsystem::Linux
|
|||||||
debug("path=%s", uPath);
|
debug("path=%s", uPath);
|
||||||
ini_destroy(ini);
|
ini_destroy(ini);
|
||||||
|
|
||||||
if (fs->Lookup(root, uPath) != false)
|
eNode ret = fs->Lookup(root, uPath);
|
||||||
|
if (ret != false)
|
||||||
{
|
{
|
||||||
root = fs->Lookup(root, uPath);
|
Node tar = ret;
|
||||||
|
FileSystemInfo *fsi = fs->Probe(tar);
|
||||||
// if (TestAndInitializeUSTAR(moduleAddress, moduleSize, 0))
|
if (fsi == nullptr)
|
||||||
// {
|
{
|
||||||
// }
|
warn("Couldn't probe rootfs %s", uPath);
|
||||||
|
__CreateStubRoot();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Node mnt = fs->Lookup(root, "/mnt");
|
||||||
|
auto node = fs->Mount(mnt, "linux", fsi, tar);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <fs/ramfs.hpp>
|
#include <fs/ramfs.hpp>
|
||||||
|
|
||||||
#include "../../kernel.h"
|
#include "../../kernel.h"
|
||||||
|
#include <ini.h>
|
||||||
|
|
||||||
namespace Subsystem::Windows
|
namespace Subsystem::Windows
|
||||||
{
|
{
|
||||||
@ -47,6 +48,50 @@ namespace Subsystem::Windows
|
|||||||
{
|
{
|
||||||
if (fs->RootExists(2) == false)
|
if (fs->RootExists(2) == false)
|
||||||
{
|
{
|
||||||
|
Node root = fs->GetRoot(0);
|
||||||
|
Node cfg = fs->Lookup(root, "/sys/cfg/subsystem/windows");
|
||||||
|
if (cfg)
|
||||||
|
{
|
||||||
|
struct kstat st;
|
||||||
|
fs->Stat(cfg, &st);
|
||||||
|
|
||||||
|
std::unique_ptr<char[]> buf(new char[st.Size]);
|
||||||
|
fs->Read(cfg, buf.get(), st.Size, 0);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
eNode ret = fs->Lookup(root, uPath);
|
||||||
|
if (ret != false)
|
||||||
|
{
|
||||||
|
Node tar = ret;
|
||||||
|
FileSystemInfo *fsi = fs->Probe(tar);
|
||||||
|
if (fsi == nullptr)
|
||||||
|
{
|
||||||
|
warn("Couldn't probe rootfs %s", uPath);
|
||||||
|
__CreateStubRoot();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Node mnt = fs->Lookup(root, "/mnt");
|
||||||
|
auto node = fs->Mount(mnt, "windows", fsi, tar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
warn("Couldn't find rootfs path %s", uPath);
|
||||||
|
__CreateStubRoot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
warn("Couldn't open /sys/cfg/subsystem/windows");
|
||||||
|
__CreateStubRoot();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user