Restructured and rewritten entire codebase

This commit is contained in:
Alex
2023-10-09 01:16:24 +03:00
parent 446a571018
commit 889e1522a3
484 changed files with 15683 additions and 14032 deletions

View File

@ -1,18 +1,18 @@
/*
This file is part of Fennix Kernel.
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 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.
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/>.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_KERNEL_FILESYSTEM_H__
@ -27,24 +27,34 @@
#include <atomic>
#include <string>
#define FILENAME_LENGTH 256
#define PATH_MAX 256
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
/** Other users have execute permission. */
#define S_IXOTH 0001
/** Other users have write permission. */
#define S_IWOTH 0002
/** Other users have read permission. */
#define S_IROTH 0004
/** Other users have read, write, and execute permissions. */
#define S_IRWXO 0007
/** Group members have execute permission. */
#define S_IXGRP 0010
/** Group members have write permission. */
#define S_IWGRP 0020
/** Group members have read permission. */
#define S_IRGRP 0040
/** Group members have read, write, and execute permissions. */
#define S_IRWXG 0070
/** The file owner has execute permission. */
#define S_IXUSR 0100
/** The file owner has write permission. */
#define S_IWUSR 0200
/** The file owner has read permission. */
#define S_IRUSR 0400
/** The file owner has read, write,
* and execute permissions. */
#define S_IRWXU 0700
#define O_RDONLY 00
@ -66,13 +76,13 @@
#define S_IFMT 0170000
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
#define S_ISCHR(mode) (((mode)&S_IFMT) == S_IFCHR)
#define S_ISBLK(mode) (((mode)&S_IFMT) == S_IFBLK)
#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG)
#define S_ISFIFO(mode) (((mode)&S_IFMT) == S_IFIFO)
#define S_ISLNK(mode) (((mode)&S_IFMT) == S_IFLNK)
#define S_ISSOCK(mode) (((mode)&S_IFMT) == S_IFSOCK)
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
struct stat
{
@ -140,30 +150,11 @@ static inline int ConvertFileFlags(const char *Mode)
return Flags;
}
namespace VirtualFileSystem
namespace vfs
{
struct Node;
typedef std::size_t (*OperationRead)(Node *node, std::size_t Size, uint8_t *Buffer, off_t &RefOffset);
typedef std::size_t (*OperationWrite)(Node *node, std::size_t Size, uint8_t *Buffer, off_t &RefOffset);
typedef void (*OperationCreate)(Node *node, char *Name, uint16_t NameLength, off_t &RefOffset);
typedef void (*OperationMkdir)(Node *node, char *Name, uint16_t NameLength, off_t &RefOffset);
typedef std::size_t (*OperationSeek)(Node *node, std::size_t Offset, int Whence, off_t &RefOffset);
#define ReadFSFunction(name) \
std::size_t name(VirtualFileSystem::Node *node, std::size_t Size, uint8_t *Buffer, off_t &RefOffset)
#define WriteFSFunction(name) \
std::size_t name(VirtualFileSystem::Node *node, std::size_t Size, uint8_t *Buffer, off_t &RefOffset)
#define CreateFSFunction(name) \
void name(VirtualFileSystem::Node *node, char *Name, uint16_t NameLength, off_t &RefOffset)
#define MkdirFSFunction(name) \
void name(VirtualFileSystem::Node *node, char *Name, uint16_t NameLength, off_t &RefOffset)
#define SeekFSFunction(name) \
off_t name(VirtualFileSystem::Node *node, off_t Offset, uint8_t Whence, off_t &RefOffset)
enum NodeFlags
enum NodeType : mode_t
{
NODE_FLAG_ERROR = 0x0,
NODE_TYPE_NONE = 0x0,
FILE = S_IFREG,
DIRECTORY = S_IFDIR,
CHARDEVICE = S_IFCHR,
@ -173,123 +164,105 @@ namespace VirtualFileSystem
MOUNTPOINT = S_IFDIR
};
struct FileSystemOperations
{
/**
* Name of the filesystem operations
*
* @note Mandatory
*/
char Name[FILENAME_LENGTH];
/**
* Pointer to the read function
*
* @note Mandatory
*/
OperationRead Read = nullptr;
/**
* Pointer to the write function
*
* @note Mandatory
*/
OperationWrite Write = nullptr;
/**
* Pointer to the create function
*
* @note Optional
*/
OperationCreate Create = nullptr;
/**
* Pointer to the mkdir function
*
* @note Optional
*/
OperationMkdir MakeDirectory = nullptr;
/**
* Pointer to the seek function
*
* @note Optional
*/
OperationSeek Seek = nullptr;
};
#define RefNode VirtualFileSystem::ReferenceNode
class ReferenceNode
{
private:
std::atomic_int64_t Offset = 0;
off_t FileSize = 0;
NewLock(RefNodeLock);
Node *node;
RefNode *SymlinkTo;
public:
decltype(FileSize) &Length = FileSize;
Node *GetNode() const { return node; }
std::string AbsolutePath;
size_t Read(uint8_t *Buffer, size_t Size);
size_t Write(uint8_t *Buffer, size_t Size);
off_t Seek(off_t Offset, int Whence);
ReferenceNode(Node *node);
~ReferenceNode();
friend class Virtual;
friend class FileDescriptorTable;
};
class RefNode;
class Node
{
private:
NewLock(NodeLock);
public:
class Virtual *FileSystem = nullptr;
ino_t IndexNode = 0;
const char *Name;
const char *Symlink;
Node *SymlinkTarget = nullptr;
mode_t Mode = 0;
NodeFlags Flags = NodeFlags::NODE_FLAG_ERROR;
uid_t UserIdentifier = 0;
gid_t GroupIdentifier = 0;
uintptr_t Address = 0;
off_t Length = 0;
virtual int open(int Flags, mode_t Mode);
virtual int close();
virtual size_t read(uint8_t *Buffer,
size_t Size,
off_t Offset);
virtual size_t write(uint8_t *Buffer,
size_t Size,
off_t Offset);
virtual int ioctl(unsigned long Request,
void *Argp);
virtual ~Node();
class Virtual *vFS = nullptr;
Node *Parent = nullptr;
FileSystemOperations *Operator = nullptr;
/* For root node:
0 - root "/"
1 - etc
...
*/
const char *Name;
const char *FullPath;
NodeType Type;
ino_t IndexNode;
const char *Symlink;
Node *SymlinkTarget;
mode_t Mode;
uid_t UserIdentifier;
gid_t GroupIdentifier;
dev_t DeviceMajor;
dev_t DeviceMinor;
time_t AccessTime;
time_t ModifyTime;
time_t ChangeTime;
off_t Size;
std::vector<Node *> Children;
/**
* References to this node (open files, etc..)
*/
std::vector<ReferenceNode *> References;
std::vector<RefNode *> References;
RefNode *CreateReference();
void RemoveReference(RefNode *Reference);
/**
* Create a new reference to this node
* @return Pointer to the new reference
* Delete all children of this node
*
* @note The function will self-delete
* if there are no errors.
*/
ReferenceNode *CreateReference();
int Delete(bool Recursive = false);
/**
* Remove a reference to this node
* @param Reference Pointer to the reference to remove
* Create a new node
*
* @param Parent The parent node
* @param Name The name of the node
* @param Type The type of the node
* @param NoParent If true, the @param Parent will
* be used as a hint for the parent node, but it
* won't be set as the parent node.
* @param fs The virtual filesystem (only if
* NoParent is set)
* @param Err If not nullptr, the function will
* write the error code to the given address.
*/
void RemoveReference(ReferenceNode *Reference);
Node(Node *Parent,
const char *Name,
NodeType Type,
bool NoParent = false,
Virtual *fs = nullptr,
int *Err = nullptr);
};
Node() {}
~Node() {}
class RefNode
{
private:
std::atomic_int64_t FileOffset = 0;
off_t FileSize = 0;
Node *n;
RefNode *SymlinkTo;
public:
decltype(FileSize) &Size = FileSize;
decltype(n) &node = n;
size_t read(uint8_t *Buffer, size_t Size);
size_t write(uint8_t *Buffer, size_t Size);
off_t seek(off_t Offset, int Whence);
int ioctl(unsigned long Request, void *Argp);
RefNode(Node *node);
~RefNode();
friend class Virtual;
friend class FileDescriptorTable;
};
class Virtual
@ -298,73 +271,43 @@ namespace VirtualFileSystem
Node *FileSystemRoot = nullptr;
NewLock(VirtualLock);
/**
* @note This function is NOT thread safe
*/
Node *AddNewChild(const char *Name, Node *Parent);
/**
* @note This function is NOT thread safe
*/
Node *GetChild(const char *Name, Node *Parent);
/**
* @note This function is NOT thread safe
*/
int RemoveChild(const char *Name, Node *Parent);
/**
* @note This function is NOT thread safe
*/
Node *GetParent(const char *Path, Node *Parent);
/**
* @note This function is NOT thread safe
*/
/** @note This function is NOT thread safe */
Node *GetNodeFromPath_Unsafe(const char *Path, Node *Parent = nullptr);
public:
std::string GetPathFromNode(Node *node);
Node *nRoot = nullptr;
Node *GetNodeFromPath(const char *Path, Node *Parent = nullptr);
bool PathIsRelative(const char *Path);
Node *GetRootNode() { return FileSystemRoot; }
std::string NormalizePath(const char *Path, Node *Parent = nullptr);
const char *NormalizePath(const char *Path, Node *Parent = nullptr);
bool PathExists(const char *Path, Node *Parent = nullptr);
Node *CreateRoot(const char *RootName, FileSystemOperations *Operator);
Node *Create(const char *Path, NodeFlags Flag, Node *Parent = nullptr);
Node *Create(const char *Path, NodeType Type, Node *Parent = nullptr);
int Delete(const char *Path, bool Recursive = false, Node *Parent = nullptr);
int Delete(Node *Path, bool Recursive = false, Node *Parent = nullptr);
Node *Mount(const char *Path, FileSystemOperations *Operator);
int Unmount(Node *File);
/**
* Open a file
* @param Path The path to the file, relative or absolute. The buffer shouldn't be modified while the function is running.
* @param Parent Pointer to the parent node, if nullptr, the root node will be used.
* @return A pointer to the VirtualFileSystem::ReferenceNode, or nullptr if the file doesn't exist.
* @return A pointer to the vfs::ReferenceNode, or nullptr if the file doesn't exist.
*/
RefNode *Open(const char *Path, Node *Parent = nullptr);
Virtual();
~Virtual();
friend class Node;
};
class FileDescriptorTable
{
public:
struct winsize
{
unsigned short ws_row;
unsigned short ws_col;
unsigned short ws_xpixel;
unsigned short ws_ypixel;
};
struct Fildes
{
RefNode *Handle{};
@ -384,7 +327,7 @@ namespace VirtualFileSystem
private:
std::vector<Fildes> FileDescriptors;
std::vector<DupFildes> FildesDuplicates;
VirtualFileSystem::Node *fdDir = nullptr;
vfs::Node *fdDir = nullptr;
Fildes GetFileDescriptor(int FileDescriptor);
FileDescriptorTable::DupFildes GetDupFildes(int FileDescriptor);
@ -395,7 +338,7 @@ namespace VirtualFileSystem
int GetFreeFileDescriptor();
public:
std::string GetAbsolutePath(int FileDescriptor);
const char *GetAbsolutePath(int FileDescriptor);
std::vector<Fildes> &GetFileDescriptors() { return FileDescriptors; }
int _open(const char *pathname, int flags, mode_t mode);