summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/src/FS/HeFS.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dev/kernel/src/FS/HeFS.cc')
-rw-r--r--dev/kernel/src/FS/HeFS.cc139
1 files changed, 62 insertions, 77 deletions
diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc
index d7cce9d6..eb6e6fc1 100644
--- a/dev/kernel/src/FS/HeFS.cc
+++ b/dev/kernel/src/FS/HeFS.cc
@@ -79,8 +79,7 @@ namespace Detail {
NE_UNUSED(node);
if (!dir || !node) {
- ke_panic(RUNTIME_CHECK_FILESYSTEM,
- "Error: Invalid directory node/boot_node in RB-Tree traversal.");
+ return;
}
if (dir->fChild != 0) {
@@ -92,7 +91,7 @@ namespace Detail {
} else if (dir->fPrev != 0) {
start = dir->fPrev;
} else {
- start = node->fStartIND;
+ start = 0;
}
}
@@ -218,7 +217,7 @@ namespace Detail {
auto start = root->fStartIND;
auto end = root->fEndIND;
- auto hop_watch = 0;
+ auto hop_watch = 0UL;
while (YES) {
if (start > end) {
@@ -226,16 +225,11 @@ namespace Detail {
break;
}
- if (hop_watch > 100) {
+ if (hop_watch++ > (root->fEndIND / sizeof(HEFS_INDEX_NODE_DIRECTORY))) {
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;
@@ -316,11 +310,11 @@ namespace Detail {
return NO;
}
- if (tmpdir->fDeleted || !tmpdir->fCreated) {
- dir->fChild = tmpdir->fChild;
+ if (tmpdir->fDeleted) {
+ dir->fChild = tmpdir->fChild;
dir->fParent = tmpdir->fParent;
- dir->fNext = tmpdir->fNext;
- dir->fPrev = tmpdir->fPrev;
+ dir->fNext = tmpdir->fNext;
+ dir->fPrev = tmpdir->fPrev;
mnt->fPacket.fPacketLba = start;
mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
@@ -331,7 +325,9 @@ namespace Detail {
return YES;
}
+ auto old_start = start;
hefsi_traverse_tree(tmpdir, root, start);
+ if (start == 0 || start == old_start) break;
}
return YES;
@@ -349,7 +345,7 @@ namespace Detail {
auto start = root->fStartIND;
auto end = root->fEndIND;
- auto hop_watch = 0;
+ auto hop_watch = 0UL;
while (YES) {
if (start > end) {
@@ -357,16 +353,11 @@ namespace Detail {
break;
}
- if (hop_watch > 100) {
+ if (hop_watch++ > (root->fEndIND / sizeof(HEFS_INDEX_NODE_DIRECTORY))) {
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;
@@ -390,7 +381,9 @@ namespace Detail {
}
}
+ auto old_start = start;
hefsi_traverse_tree(dir, root, start);
+ if (start == 0 || start == old_start) break;
}
delete dir;
@@ -427,7 +420,7 @@ namespace Detail {
auto start_cnt = 0UL;
- auto hop_watch = 0;
+ auto hop_watch = 0UL;
while (YES) {
if (start > end) {
@@ -435,16 +428,11 @@ namespace Detail {
break;
}
- if (hop_watch > 100) {
+ if (hop_watch++ > (root->fEndIND / sizeof(HEFS_INDEX_NODE_DIRECTORY))) {
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;
@@ -507,7 +495,9 @@ namespace Detail {
}
}
+ auto old_start = start;
hefsi_traverse_tree(dir, root, start);
+ if (start == 0 || start == old_start) break;
}
delete dir;
@@ -539,19 +529,16 @@ namespace Detail {
auto start = root->fStartIND;
- auto hop_watch = 0;
+ auto hop_watch = 0UL;
while (YES) {
- if (hop_watch > 100) {
+ if (start > root->fEndIND) break;
+
+ if (hop_watch++ > (root->fEndIND / sizeof(HEFS_INDEX_NODE_DIRECTORY))) {
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;
@@ -590,7 +577,11 @@ namespace Detail {
}
}
+ auto old_start = start;
+
hefsi_traverse_tree(dir, root, start);
+
+ if (start == 0 || start == old_start) break;
}
delete dir;
@@ -614,9 +605,10 @@ namespace Detail {
auto start = root->fStartIND;
+ SizeT hop_watch = 0UL;
+
while (YES) {
- if (start > root->fEndIND)
- break;
+ if (start > root->fEndIND) break;
mnt->fPacket.fPacketLba = start;
mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
@@ -624,6 +616,11 @@ namespace Detail {
mnt->fInput(mnt->fPacket);
+ if (hop_watch++ > (root->fSectorCount)) { // <-- NEW (stall protection)
+ kout << "Warning: Traversal stalled during balancing.\r";
+ break; // Exit cleanly instead of hanging forever
+ }
+
if (!mnt->fPacket.fPacketGood) {
delete dir;
dir = nullptr;
@@ -700,14 +697,21 @@ namespace Detail {
return NO;
}
+ auto old_start = start;
hefsi_traverse_tree(dir, root, start);
+ if (start == 0 || start == old_start) break;
+
continue;
} else {
if (dir_parent->fNext == start) {
hefsi_rotate_left(dir, start, mnt);
+
+ auto old_start = start;
hefsi_traverse_tree(dir, root, start);
+ if (start == 0 || start == old_start) break;
+
continue;
}
@@ -729,12 +733,12 @@ namespace Detail {
}
hefsi_rotate_right(dir, start, mnt);
- hefsi_traverse_tree(dir, root, start);
-
- continue;
}
+ auto old_start = start;
hefsi_traverse_tree(dir, root, start);
+
+ if (start == 0 || start == old_start) break;
}
delete dir;
@@ -852,8 +856,6 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input
drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
drive->fPacket.fPacketContent = root;
- HEFS_BOOT_NODE root_cpy = *root;
-
drive->fOutput(drive->fPacket);
if (!drive->fPacket.fPacketGood) {
@@ -865,20 +867,20 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input
return NO;
}
- SizeT cnt = kHeFSBlockCount;
+ /// @note this allocates 4 ind at format.
+ SizeT cnt = 4UL;
- Lba next = root_cpy.fStartIND;
- Lba prev = next;
+ Lba next = drive->fLbaStart + sizeof(HEFS_BOOT_NODE) + sizeof(HEFS_BOOT_NODE);
HEFS_INDEX_NODE_DIRECTORY* index_node = new HEFS_INDEX_NODE_DIRECTORY();
-
+
// Pre-allocate index node directory tree
for (SizeT i = 0; i < cnt; ++i) {
rt_set_memory(index_node, 0, sizeof(HEFS_INDEX_NODE_DIRECTORY));
wrt_copy_memory((VoidPtr) u"/$", index_node->fName, wrt_string_len(u"/$"));
- index_node->fFlags = flags;
- index_node->fKind = kHeFSFileKindDirectory;
+ index_node->fFlags = flags;
+ index_node->fKind = kHeFSFileKindDirectory;
index_node->fDeleted = kHeFSTimeMax;
@@ -890,23 +892,25 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input
index_node->fUID = 0;
index_node->fGID = 0;
index_node->fMode = 0;
- index_node->fColor = kHeFSBlack;
- index_node->fParent = next;
+ index_node->fColor = kHeFSBlack;
index_node->fChild = 0;
- index_node->fNext = next + sizeof(HEFS_INDEX_NODE_DIRECTORY);
- index_node->fPrev = prev;
+ index_node->fParent = 0;
+ index_node->fNext = 0;
+ index_node->fPrev = 0;
- drive->fPacket.fPacketLba = next;
- drive->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ drive->fPacket.fPacketLba = next;
+ drive->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
drive->fPacket.fPacketContent = index_node;
- prev = next;
next += sizeof(HEFS_INDEX_NODE_DIRECTORY);
drive->fOutput(drive->fPacket);
}
+ delete index_node;
+ index_node = nullptr;
+
// Create the directories, something UNIX inspired but more explicit and forward looking.
this->CreateDirectory(drive, kHeFSEncodingUTF16, u"/boot");
@@ -921,7 +925,7 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input
this->CreateFile(drive, kHeFSEncodingBinary, u"/", u".hefs");
delete root;
- root = nullptr;
+ root = nullptr;
if (drive->fPacket.fPacketGood) return YES;
@@ -967,37 +971,18 @@ _Output Bool HeFileSystemParser::CreateDirectory(_Input DriveTrait* drive, _Inpu
Detail::hefsi_balance_filesystem(root, drive);
- 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();
+ auto 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; /// TODO: Add the current time.
+ dirent->fCreated = kHeFSTimeMax; /// TODO: Add the current time.
dirent->fDeleted = 0;
dirent->fModified = 0;
dirent->fEntryCount = 0;
- dirent->fParent = root->fStartIND; // No parent (it's the real root)
- dirent->fChild = root->fEndIND; // No children yet
- dirent->fNext = 0; // No next
- dirent->fPrev = 0; // No previous
-
dirent->fKind = kHeFSFileKindDirectory;
dirent->fFlags = flags;
dirent->fChecksum = 0;