summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'dev/kernel')
-rw-r--r--dev/kernel/FSKit/HeFS.h16
-rw-r--r--dev/kernel/src/FS/HeFS.cc192
-rw-r--r--dev/kernel/src/PEFCodeMgr.cc1
3 files changed, 150 insertions, 59 deletions
diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h
index da5da3c1..50b8e259 100644
--- a/dev/kernel/FSKit/HeFS.h
+++ b/dev/kernel/FSKit/HeFS.h
@@ -358,14 +358,22 @@ class HeFileSystemParser final {
/// @return If it was sucessful, see err_local_get().
_Output Bool Format(_Input _Output DriveTrait* drive, _Input const Int32 flags,
const Utf8Char* part_name);
-
+
_Output Bool CreateDirectory(_Input DriveTrait* drive, _Input const Int32 flags,
- const Utf8Char* dir);
+ const Utf8Char* dir, const Utf8Char* parent_dir);
+
+
+ _Output Bool RemoveDirectory(_Input DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* dir, const Utf8Char* parent_dir);
- _Output Bool CreateFile(_Input DriveTrait* drive, _Input const Int32 flags, const Utf8Char* dir,
+ _Output Bool CreateFile(_Input DriveTrait* drive, _Input const Int32 flags, const Utf8Char* dir, const Utf8Char* namespase,
const Utf8Char* name);
- public:
+ private:
+
+ _Output Bool DirectoryCtl_(_Input DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* dir, const Utf8Char* parent, const BOOL delete_or_create);
+
UInt32 mDriveIndex{MountpointInterface::kDriveIndexA}; /// @brief The drive index which this
/// filesystem is mounted on.
};
diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc
index 695752af..4cea6f58 100644
--- a/dev/kernel/src/FS/HeFS.cc
+++ b/dev/kernel/src/FS/HeFS.cc
@@ -67,8 +67,7 @@ namespace Detail {
/// @param root The root node of the filesystem.
/// @param mnt The drive to read/write from.
/// @return Status, see err_global_get().
- STATIC ATTRIBUTE(unused) _Output BOOL
- hefsi_balance_filesystem(HEFS_BOOT_NODE* root, DriveTrait* mnt);
+ STATIC ATTRIBUTE(unused) _Output BOOL hefsi_balance_ind(HEFS_BOOT_NODE* root, DriveTrait* mnt);
/// @brief Traverse the RB-Tree of the filesystem.
/// @param dir The directory to traverse.
@@ -88,11 +87,9 @@ namespace Detail {
mnt->fPacket.fPacketContent = dir;
mnt->fInput(mnt->fPacket);
- if (!mnt->fPacket.fPacketGood)
- break;
+ if (!mnt->fPacket.fPacketGood) break;
- if (*dir->fName != 0 && alloc_in_mind)
- break;
+ if (*dir->fName != 0 && alloc_in_mind) break;
if (dir->fNext != 0) {
if (check_is_good) break;
@@ -134,10 +131,9 @@ namespace Detail {
}
}
- if (*dir->fName != 0 && alloc_in_mind)
- start += sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ if (*dir->fName != 0 && alloc_in_mind) start += sizeof(HEFS_INDEX_NODE_DIRECTORY);
- kout << "LBA_" << number(start) << kendl;
+ (Void)(kout << "LBA_" << number(start) << kendl);
}
/***********************************************************************************/
@@ -279,10 +275,17 @@ namespace Detail {
return 0;
}
- /// @brief Alllocate IND for boot node.
- STATIC _Output BOOL hefsi_allocate_index_node_directory(HEFS_BOOT_NODE* root, DriveTrait* mnt,
- const Utf8Char* dir_name,
- UInt16 flags) noexcept {
+ /// @brief Alllocate IND from boot node.
+ /// @param root The root node of the filesystem.
+ /// @param mnt The drive to read from.
+ /// @param dir_name The name of the directory.
+ /// @param dir_name The parent of the directory.
+ /// @param flags Directory flags.
+ /// @param delete_or_create Delete or create directory.
+ STATIC _Output BOOL hefsi_update_ind_status(HEFS_BOOT_NODE* root, DriveTrait* mnt,
+ const Utf8Char* dir_name,
+ const Utf8Char* parent_dir_fmt, UInt16 flags,
+ const BOOL delete_or_create) noexcept {
if (urt_string_len(dir_name) >= kHeFSFileNameLen) {
err_global_get() = kErrorDisk;
return NO;
@@ -292,13 +295,14 @@ namespace Detail {
HEFS_INDEX_NODE_DIRECTORY* tmpdir =
(HEFS_INDEX_NODE_DIRECTORY*) mm_new_heap(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No);
- auto start = root->fStartIND;
- auto prev_location = start;
+ auto start = root->fStartIND;
+ auto prev_location = start;
+ auto parent_location = 0UL;
MUST_PASS(root->fStartIND > mnt->fLbaStart);
while (YES) {
- auto tmp = start;
+ auto prev_start = start;
if (start)
mnt->fPacket.fPacketLba = start;
@@ -310,17 +314,41 @@ namespace Detail {
mnt->fInput(mnt->fPacket);
- if ((!tmpdir->fCreated && tmpdir->fDeleted) || *tmpdir->fName == 0) {
+ BOOL expr = NO;
+
+ if (!delete_or_create) {
+ expr = (!tmpdir->fCreated && tmpdir->fDeleted) || *tmpdir->fName == 0;
+ } else {
+ expr = tmpdir->fCreated && !tmpdir->fDeleted &&
+ KStringBuilder::Equals(tmpdir->fName, dir_name);
+
+ if (parent_dir_fmt && !delete_or_create && !parent_location) {
+ if (KStringBuilder::Equals(tmpdir->fName, parent_dir_fmt)) {
+ if (tmpdir->fChild == 0) {
+ ke_panic(RUNTIME_CHECK_FILESYSTEM,
+ "Filesystem has a corrupted child entry on RB-Tree IND.");
+ } else {
+ parent_location = start;
+ continue;
+ }
+ }
+ }
+ }
+
+ if (expr) {
HEFS_INDEX_NODE_DIRECTORY* dirent =
(HEFS_INDEX_NODE_DIRECTORY*) mm_new_heap(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No);
- urt_copy_memory((VoidPtr) dir_name, dirent->fName, urt_string_len(dir_name) + 1);
+ rt_set_memory(dirent, 0, sizeof(HEFS_INDEX_NODE_DIRECTORY));
- dirent->fAccessed = 0;
- dirent->fCreated = 1UL;
- dirent->fDeleted = 0;
- dirent->fModified = 0;
- dirent->fEntryCount = 0;
+ if (!delete_or_create)
+ urt_copy_memory((VoidPtr) dir_name, dirent->fName, urt_string_len(dir_name) + 1);
+
+ dirent->fAccessed = 0UL;
+ dirent->fCreated = delete_or_create ? 0UL : 1UL;
+ dirent->fDeleted = delete_or_create ? 1UL : 0UL;
+ dirent->fModified = 0UL;
+ dirent->fEntryCount = 0UL;
dirent->fKind = kHeFSFileKindDirectory;
dirent->fFlags = flags;
@@ -328,6 +356,48 @@ namespace Detail {
dirent->fEntryCount = 0;
+ if (parent_location) {
+ HEFS_INDEX_NODE_DIRECTORY* tmpend =
+ (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fPacket.fPacketLba = parent_location;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = tmpend;
+
+ mnt->fInput(mnt->fPacket);
+
+ if (tmpend->fChecksum !=
+ ke_calculate_crc32((Char*) tmpend, sizeof(HEFS_INDEX_NODE_DIRECTORY)))
+ ke_panic(RUNTIME_CHECK_FILESYSTEM, "Bad CRC32");
+
+ if (delete_or_create)
+ --tmpend->fEntryCount;
+ else
+ ++tmpend->fEntryCount;
+
+ tmpend->fChecksum =
+ ke_calculate_crc32((Char*) tmpend, sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fOutput(mnt->fPacket);
+
+ auto child_first = tmpend->fChild;
+
+ while (YES) {
+ mnt->fPacket.fPacketLba = child_first;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = tmpend;
+
+ mnt->fInput(mnt->fPacket);
+
+ if ((!tmpend->fCreated && tmpend->fDeleted) || *tmpend->fName == 0) {
+ start = child_first;
+ break;
+ }
+
+ hefsi_traverse_tree(tmpend, mnt, root->fStartIND, child_first, YES);
+ }
+ }
+
dirent->fNext = tmpdir->fNext;
dirent->fPrev = tmpdir->fPrev;
dirent->fParent = tmpdir->fParent;
@@ -343,7 +413,7 @@ namespace Detail {
}
if (dirent->fNext == 0) {
- dirent->fNext = tmp + sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ dirent->fNext = prev_start + sizeof(HEFS_INDEX_NODE_DIRECTORY);
}
if (dirent->fParent == 0) {
@@ -384,7 +454,7 @@ namespace Detail {
dirent->fChecksum = ke_calculate_crc32((Char*) dirent, sizeof(HEFS_INDEX_NODE_DIRECTORY));
- mnt->fPacket.fPacketLba = tmp;
+ mnt->fPacket.fPacketLba = prev_start;
mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
mnt->fPacket.fPacketContent = dirent;
@@ -395,7 +465,10 @@ namespace Detail {
mm_delete_heap(dirent);
mm_delete_heap(tmpdir);
- ++root->fINDCount;
+ if (!delete_or_create)
+ ++root->fINDCount;
+ else
+ --root->fINDCount;
mnt->fPacket.fPacketLba = mnt->fLbaStart;
mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
@@ -422,8 +495,12 @@ namespace Detail {
return NO;
}
- STATIC _Output HEFS_INDEX_NODE_DIRECTORY* hefsi_fetch_index_node_directory(
- HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf8Char* dir_name) {
+ /// @brief Fetch IND from boot node.
+ /// @param root The root node of the filesystem.
+ /// @param mnt The drive to read from.
+ /// @param dir_name The name of the directory.
+ STATIC _Output HEFS_INDEX_NODE_DIRECTORY* hefsi_fetch_ind(HEFS_BOOT_NODE* root, DriveTrait* mnt,
+ const Utf8Char* dir_name) {
if (mnt) {
HEFS_INDEX_NODE_DIRECTORY* dir =
(HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
@@ -608,12 +685,11 @@ namespace Detail {
/// @param root The root node of the filesystem.
/// @param mnt The drive to read/write from.
/// @return Status, see err_global_get().
- STATIC ATTRIBUTE(unused) _Output BOOL
- hefsi_balance_filesystem(HEFS_BOOT_NODE* root, DriveTrait* mnt) {
+ STATIC ATTRIBUTE(unused) _Output BOOL hefsi_balance_ind(HEFS_BOOT_NODE* root, DriveTrait* mnt) {
if (mnt) {
HEFS_INDEX_NODE_DIRECTORY* dir =
(HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
- HEFS_INDEX_NODE_DIRECTORY* dir_parent =
+ HEFS_INDEX_NODE_DIRECTORY* parent_dir_fmt =
(HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
auto start = root->fStartIND;
@@ -655,7 +731,7 @@ namespace Detail {
mnt->fPacket.fPacketLba = dir->fParent;
mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = dir_parent;
+ mnt->fPacket.fPacketContent = parent_dir_fmt;
mnt->fInput(mnt->fPacket);
@@ -668,7 +744,7 @@ namespace Detail {
HEFS_INDEX_NODE_DIRECTORY* dir_uncle =
(HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
- mnt->fPacket.fPacketLba = dir_parent->fNext;
+ mnt->fPacket.fPacketLba = parent_dir_fmt->fNext;
mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
mnt->fPacket.fPacketContent = dir_uncle;
@@ -680,23 +756,23 @@ namespace Detail {
return NO;
}
- if (dir_parent->fNext == start) {
+ if (parent_dir_fmt->fNext == start) {
hefsi_rotate_tree(start, mnt, YES);
- hefsi_traverse_tree(dir_parent, mnt, root->fStartIND, start);
+ hefsi_traverse_tree(parent_dir_fmt, mnt, root->fStartIND, start);
if (start > root->fEndIND || start == 0) break;
continue;
}
- dir_parent->fColor = kHeFSBlack;
+ parent_dir_fmt->fColor = kHeFSBlack;
- dir_parent->fChecksum =
- ke_calculate_crc32((Char*) dir_parent, sizeof(HEFS_INDEX_NODE_DIRECTORY));
+ parent_dir_fmt->fChecksum =
+ ke_calculate_crc32((Char*) parent_dir_fmt, sizeof(HEFS_INDEX_NODE_DIRECTORY));
mnt->fPacket.fPacketLba = dir->fParent;
mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = dir_parent;
+ mnt->fPacket.fPacketContent = parent_dir_fmt;
mnt->fOutput(mnt->fPacket);
@@ -851,11 +927,11 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input
}
const Utf8Char* kFileMap[kHeFSPreallocateCount] = {
- u8"/", u8"/boot", u8"/system", u8"/network", u8"/devices", u8"/media", u8"/vm",
+ u8"/", u8"boot", u8"system", u8"network", u8"devices", u8"media", u8"vm",
};
for (SizeT i = 0; i < kHeFSPreallocateCount; ++i) {
- this->CreateDirectory(drive, kHeFSEncodingUTF8, kFileMap[i]);
+ this->CreateDirectory(drive, kHeFSEncodingUTF8, kFileMap[i], (i == 0) ? nullptr : u8"/");
}
err_global_get() = kErrorSuccess;
@@ -872,8 +948,9 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input
/// @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 Utf8Char* dir) {
+_Output Bool HeFileSystemParser::DirectoryCtl_(_Input DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* dir, const Utf8Char* parent_dir,
+ const BOOL delete_or_create) {
HEFS_BOOT_NODE* root = (HEFS_BOOT_NODE*) mm_new_heap(sizeof(HEFS_BOOT_NODE), Yes, No);
rt_copy_memory((VoidPtr) "fs/hefs-packet", drive->fPacket.fPacketMime,
@@ -893,24 +970,28 @@ _Output Bool HeFileSystemParser::CreateDirectory(_Input DriveTrait* drive, _Inpu
return NO;
}
- auto name = new Utf8Char[urt_string_len(dir) + 1];
-
- urt_copy_memory((VoidPtr) dir, name, urt_string_len(dir) + 1);
-
- if (Detail::hefsi_allocate_index_node_directory(root, drive, name, flags)) {
+ if (Detail::hefsi_update_ind_status(root, drive, dir, parent_dir, flags, delete_or_create)) {
// todo: make it smarter for high-throughput.
- Detail::hefsi_balance_filesystem(root, drive);
+ Detail::hefsi_balance_ind(root, drive);
mm_delete_heap((VoidPtr) root);
- delete[] name;
return YES;
}
mm_delete_heap((VoidPtr) root);
+ return NO;
+}
- delete[] name;
+_Output Bool HeFileSystemParser::RemoveDirectory(_Input DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* dir,
+ const Utf8Char* parent_dir_fmt) {
+ return this->DirectoryCtl_(drive, flags, dir, parent_dir_fmt, YES);
+}
- return NO;
+_Output Bool HeFileSystemParser::CreateDirectory(_Input DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* dir,
+ const Utf8Char* parent_dir_fmt) {
+ return this->DirectoryCtl_(drive, flags, dir, parent_dir_fmt, NO);
}
/// @brief Create a new file on the disk.
@@ -920,7 +1001,10 @@ _Output Bool HeFileSystemParser::CreateDirectory(_Input DriveTrait* drive, _Inpu
/// @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 Utf8Char* dir, const Utf8Char* name) {
+ const Utf8Char* dir, const Utf8Char* parent_dir_fmt,
+ const Utf8Char* name) {
+ NE_UNUSED(parent_dir_fmt);
+
HEFS_INDEX_NODE* node = (HEFS_INDEX_NODE*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE));
HEFS_BOOT_NODE* root = (HEFS_BOOT_NODE*) RTL_ALLOCA(sizeof(HEFS_BOOT_NODE));
@@ -933,7 +1017,7 @@ _Output Bool HeFileSystemParser::CreateFile(_Input DriveTrait* drive, _Input con
drive->fInput(drive->fPacket);
- if (!Detail::hefsi_fetch_index_node_directory(root, drive, dir)->fCreated) return NO;
+ if (!Detail::hefsi_fetch_ind(root, drive, dir)->fCreated) return NO;
if (KStringBuilder::Equals(name, kHeFSSearchAllStr)) {
kout << "Error: Invalid file name.\r";
diff --git a/dev/kernel/src/PEFCodeMgr.cc b/dev/kernel/src/PEFCodeMgr.cc
index 5da3a499..09a262d4 100644
--- a/dev/kernel/src/PEFCodeMgr.cc
+++ b/dev/kernel/src/PEFCodeMgr.cc
@@ -12,7 +12,6 @@
#include <NewKit/KString.h>
#include <NewKit/KernelPanic.h>
#include <NewKit/OwnPtr.h>
-#include "KernelKit/UserProcessScheduler.h"
/// @brief PEF stack size symbol.
#define kPefStackSizeSymbol "__PEFSizeOfReserveStack"