diff options
Diffstat (limited to 'dev')
| -rw-r--r-- | dev/kernel/FSKit/HeFS.h | 7 | ||||
| -rw-r--r-- | dev/kernel/KernelKit/CoreProcessScheduler.h | 10 | ||||
| -rw-r--r-- | dev/kernel/src/FS/HeFS.cc | 280 | ||||
| -rw-r--r-- | dev/kernel/src/IPEFDylibObject.cc | 2 | ||||
| -rw-r--r-- | dev/kernel/src/UserProcessScheduler.cc | 4 | ||||
| -rw-r--r-- | dev/kernel/src/UserProcessTeam.cc (renamed from dev/kernel/src/ProcessTeam.cc) | 0 |
6 files changed, 295 insertions, 8 deletions
diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index 63725f04..895422a6 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -168,7 +168,7 @@ struct PACKED ALIGN(8) HEFS_INDEX_NODE_DIRECTORY final { Kernel::UInt32 fChecksum,
fIndexNodeChecksum; /// @brief Checksum of the file, index node checksum.
- Kernel::ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps.
+ Kernel::ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps and allocation status.
Kernel::UInt32 fUID, fGID; /// @brief User ID and Group ID of the file.
Kernel::UInt32 fMode; /// @brief File mode. (read, write, execute, etc).
@@ -354,6 +354,11 @@ class HeFileSystemParser final { _Output Bool Format(_Input _Output DriveTrait* drive, _Input const Int32 flags,
const Utf16Char* part_name);
+ _Output Bool CreateDirectory(_Input DriveTrait* drive, _Input const Int32 flags, const Utf16Char* dir);
+
+ _Output Bool CreateFile(_Input DriveTrait* drive, _Input const Int32 flags, const Utf16Char* dir,
+ const Utf16Char* name);
+
public:
UInt32 mDriveIndex{MountpointInterface::kDriveIndexA}; /// @brief The drive index which this
/// filesystem is mounted on.
diff --git a/dev/kernel/KernelKit/CoreProcessScheduler.h b/dev/kernel/KernelKit/CoreProcessScheduler.h index 3b581ffe..42def9fc 100644 --- a/dev/kernel/KernelKit/CoreProcessScheduler.h +++ b/dev/kernel/KernelKit/CoreProcessScheduler.h @@ -115,12 +115,18 @@ using ImagePtr = VoidPtr; struct PROCESS_IMAGE final { explicit PROCESS_IMAGE() = default; +private: + friend USER_PROCESS; + friend KERNEL_PROCESS; + friend class UserProcessScheduler; + ImagePtr fCode; ImagePtr fBlob; - Bool HasCode() { return this->fCode != nullptr; } +public: + Bool HasCode() const { return this->fCode != nullptr; } - Bool HasImage() { return this->fBlob != nullptr; } + Bool HasImage() const { return this->fBlob != nullptr; } ErrorOr<ImagePtr> Leak() { if (this->fCode) { diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index 9037a1e2..71d1d1d4 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -4,7 +4,6 @@ ------------------------------------------- */ -#include "NewKit/Defines.h" #ifdef __FSKIT_INCLUDES_HEFS__ #include <FSKit/HeFS.h> @@ -289,6 +288,109 @@ namespace Detail { return 0; } + STATIC _Output BOOL hefs_allocate_index_directory_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, + HEFS_INDEX_NODE_DIRECTORY* dir) noexcept { + if (root && mnt) { + HEFS_INDEX_NODE_DIRECTORY* parent = new HEFS_INDEX_NODE_DIRECTORY(); + + if (!parent) { + kout << "Error: Failed to allocate memory for index node.\r"; + return NO; + } + + auto start = root->fStartIND; + + while (YES) { + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = parent; + + mnt->fInput(mnt->fPacket); + + if (!mnt->fPacket.fPacketGood) { + delete parent; + return NO; + } + + if (parent->fDeleted) { + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir; + + mnt->fOutput(mnt->fPacket); + + return YES; + } + + hefsi_traverse_tree(parent, start); + } + + return YES; + } + + err_global_get() = kErrorFileNotFound; + return NO; + } + + STATIC _Output HEFS_INDEX_NODE_DIRECTORY* hefs_fetch_index_node_directory( + HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name) { + if (root && mnt) { + HEFS_INDEX_NODE_DIRECTORY* dir = new HEFS_INDEX_NODE_DIRECTORY(); + + auto start = root->fStartIND; + auto end = root->fEndIND; + + auto hop_watch = 0; + + while (YES) { + if (start > end) { + kout << "Error: Invalid start/end values.\r"; + break; + } + + if (hop_watch > 100) { + kout << "Error: Hop watch exceeded, filesystem is stalling.\r"; + break; + } + + if (start == 0) { + ++hop_watch; + start = root->fStartIND; + } + + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir; + + mnt->fInput(mnt->fPacket); + + if (!mnt->fPacket.fPacketGood) { + delete dir; + + dir = nullptr; + + err_global_get() = kErrorFileNotFound; + + return nullptr; + } + + if (dir->fKind == kHeFSFileKindDirectory) { + if (KStringBuilder::Equals(dir_name, dir->fName)) { + return dir; + } + } + + hefsi_traverse_tree(dir, start); + } + + err_global_get() = kErrorSuccess; + return dir; + } + + err_global_get() = kErrorFileNotFound; + return nullptr; + } + /// @brief Get the index node of a file or directory. /// @param root The root node of the filesystem. /// @param mnt The drive to read from. @@ -709,7 +811,178 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input drive->fOutput(drive->fPacket); - return YES; + delete root; + root = nullptr; + + if (drive->fPacket.fPacketGood) return YES; + + err_global_get() = kErrorDiskIsCorrupted; + + return NO; +} + +/// @brief Create a new directory on the disk. +/// @param drive The drive to write on. +/// @param flags The flags to use. +/// @param dir The directory to create the file in. +/// @return If it was sucessful, see err_local_get(). +_Output Bool HeFileSystemParser::CreateDirectory(_Input DriveTrait* drive, _Input const Int32 flags, + const Utf16Char* dir) { + NE_UNUSED(drive); + NE_UNUSED(flags); + NE_UNUSED(dir); + + HEFS_BOOT_NODE* root = new HEFS_BOOT_NODE(); + HEFS_INDEX_NODE* node = new HEFS_INDEX_NODE(); + + if (!root || !node) { + kout << "Error: Failed to allocate memory for boot node.\r"; + + if (node) delete node; + if (root) delete root; + + return NO; + } + + rt_set_memory(root, 0, sizeof(HEFS_BOOT_NODE)); + rt_set_memory(node, 0, sizeof(HEFS_INDEX_NODE)); + + rt_copy_memory((VoidPtr) "fs/hefs-packet", drive->fPacket.fPacketMime, + rt_string_len("fs/hefs-packet")); + + drive->fPacket.fPacketLba = drive->fLbaStart; + drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); + drive->fPacket.fPacketContent = root; + + drive->fInput(drive->fPacket); + + auto dirent = Detail::hefs_fetch_index_node_directory(root, drive, dir); + + if (dirent) { + kout << "Error: Directory already exists.\r"; + + delete dirent; + dirent = nullptr; + + delete node; + delete root; + + return NO; + } + + dirent = new HEFS_INDEX_NODE_DIRECTORY(); + + rt_set_memory(dirent, 0, sizeof(HEFS_INDEX_NODE_DIRECTORY)); + + wrt_copy_memory((VoidPtr) dir, dirent->fName, wrt_string_len(dir)); + + dirent->fAccessed = 0; + dirent->fCreated = 0; + dirent->fDeleted = 0; + dirent->fModified = 0; + dirent->fEntryCount = 0; + dirent->fKind = kHeFSFileKindDirectory; + dirent->fFlags = flags; + dirent->fChecksum = 0; + + if (Detail::hefs_allocate_index_directory_node(root, drive, dirent)) { + delete dirent; + dirent = nullptr; + + delete node; + delete root; + + return YES; + } + + delete dirent; + dirent = nullptr; + + delete node; + delete root; + + return NO; +} + +/// @brief Create a new file on the disk. +/// @param drive The drive to write on. +/// @param flags The flags to use. +/// @param dir The directory to create the file in. +/// @param name The name of the file. +/// @return If it was sucessful, see err_local_get(). +_Output Bool HeFileSystemParser::CreateFile(_Input DriveTrait* drive, _Input const Int32 flags, + const Utf16Char* dir, const Utf16Char* name) { + NE_UNUSED(drive); + NE_UNUSED(flags); + NE_UNUSED(dir); + NE_UNUSED(name); + + HEFS_BOOT_NODE* root = new HEFS_BOOT_NODE(); + HEFS_INDEX_NODE* node = new HEFS_INDEX_NODE(); + + if (!root || !node) { + kout << "Error: Failed to allocate memory for boot node.\r"; + + if (node) delete node; + if (root) delete root; + + return NO; + } + + rt_set_memory(root, 0, sizeof(HEFS_BOOT_NODE)); + rt_set_memory(node, 0, sizeof(HEFS_INDEX_NODE)); + + rt_copy_memory((VoidPtr) "fs/hefs-packet", drive->fPacket.fPacketMime, + rt_string_len("fs/hefs-packet")); + + drive->fPacket.fPacketLba = drive->fLbaStart; + drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); + drive->fPacket.fPacketContent = root; + + drive->fInput(drive->fPacket); + + auto dirent = Detail::hefs_fetch_index_node_directory(root, drive, dir); + + if (!dirent) { + kout << "Error: Directory not found.\r"; + + delete node; + delete root; + + return NO; + } + + delete dirent; + dirent = nullptr; + + if (KStringBuilder::Equals(name, kHeFSSearchAllStr)) { + kout << "Error: Invalid file name.\r"; + + delete node; + delete root; + + return NO; + } + + node->fAccessed = 0; + node->fCreated = 0; + node->fDeleted = 0; + node->fModified = 0; + node->fSize = 0; + node->fKind = kHeFSFileKindRegular; + node->fFlags = flags; + node->fChecksum = 0; + + wrt_copy_memory((VoidPtr) name, node->fName, wrt_string_len(name)); + + if (Detail::hefs_allocate_index_node(root, drive, dir, node)) { + delete node; + delete root; + + return YES; + } + + return NO; } Boolean fs_init_hefs(Void) noexcept { @@ -723,6 +996,9 @@ Boolean fs_init_hefs(Void) noexcept { HeFileSystemParser parser; parser.Format(&drv, kHeFSEncodingUTF16, kHeFSDefaultVoluneName); + parser.CreateDirectory(&drv, kHeFSEncodingUTF16, u"/"); + parser.CreateFile(&drv, kHeFSEncodingUTF16, u"/", u"boot.log"); + return YES; } } // namespace Kernel::HeFS diff --git a/dev/kernel/src/IPEFDylibObject.cc b/dev/kernel/src/IPEFDylibObject.cc index f064dbac..f9cd758c 100644 --- a/dev/kernel/src/IPEFDylibObject.cc +++ b/dev/kernel/src/IPEFDylibObject.cc @@ -60,7 +60,7 @@ EXTERN_C IDylibRef rtl_init_dylib_pef(USER_PROCESS& process) { return nullptr; } - dll_obj->Get()->ImageObject = process.Image.fBlob; + dll_obj->Get()->ImageObject = process.Image.LeakBlob().Leak().Leak(); if (!dll_obj->Get()->ImageObject) { delete dll_obj->Get(); diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index ae7bbfb8..bc2cc8e2 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -498,7 +498,7 @@ SizeT UserProcessScheduler::Run() noexcept { process.PTime = static_cast<Int32>(process.Affinity); // tell helper to find a core to schedule on. - BOOL ret = UserProcessHelper::Switch(process.Image.fCode, + BOOL ret = UserProcessHelper::Switch(process.Image.Leak().Leak().Leak(), &process.StackReserve[process.StackSize - 1], process.StackFrame, process.ProcessId); @@ -570,7 +570,7 @@ Bool UserProcessHelper::CanBeScheduled(const USER_PROCESS& process) { if (process.Status == ProcessStatusKind::kInvalid) return No; - if (!process.Image.fCode) return No; + if (!process.Image.HasCode()) return No; if (!process.Name[0]) return No; diff --git a/dev/kernel/src/ProcessTeam.cc b/dev/kernel/src/UserProcessTeam.cc index 7acbcf8d..7acbcf8d 100644 --- a/dev/kernel/src/ProcessTeam.cc +++ b/dev/kernel/src/UserProcessTeam.cc |
