summaryrefslogtreecommitdiffhomepage
path: root/dev
diff options
context:
space:
mode:
authorAmlal <amlal@nekernel.org>2025-05-10 09:45:32 +0200
committerAmlal <amlal@nekernel.org>2025-05-10 09:45:32 +0200
commitb816e857b2d3b602473bf28703ad2cff722535e5 (patch)
treef615cc7643c4b1f573f0e4972e04e59ecab88efd /dev
parent1391fa1bdc1cfe864596d3120bda12590131bc62 (diff)
dev(kernel): feat: AHCI driver improvements against 'disk hangs', and HeFS has been improved with better traversal, and inode/ind allocation.
Signed-off-by: Amlal <amlal@nekernel.org>
Diffstat (limited to 'dev')
-rw-r--r--dev/boot/src/HEL/AMD64/BootEFI.cc9
-rw-r--r--dev/kernel/FSKit/HeFS.h5
-rw-r--r--dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc23
-rw-r--r--dev/kernel/src/FS/HeFS+FileSystemParser.cc97
4 files changed, 57 insertions, 77 deletions
diff --git a/dev/boot/src/HEL/AMD64/BootEFI.cc b/dev/boot/src/HEL/AMD64/BootEFI.cc
index 260d7c00..dbc12265 100644
--- a/dev/boot/src/HEL/AMD64/BootEFI.cc
+++ b/dev/boot/src/HEL/AMD64/BootEFI.cc
@@ -17,11 +17,6 @@
#include <modules/CoreGfx/CoreGfx.h>
#include <modules/CoreGfx/TextGfx.h>
-// Makes the compiler shut up.
-#ifndef kMachineModel
-#define kMachineModel "OS"
-#endif // !kMachineModel
-
/** Graphics related. */
STATIC EfiGraphicsOutputProtocol* kGop = nullptr;
@@ -136,14 +131,14 @@ EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, EfiSystemTa
Int32 trials = 5 * 10000000;
writer.Write("BootZ: Welcome to BootZ.\r");
- writer.Write("BootZ: Allocating sufficent memory, trying 4GB...\r");
+ writer.Write("BootZ: Allocating sufficient memory, trying 4GB...\r");
while (BS->AllocatePool(EfiLoaderData, handover_hdr->f_BitMapSize,
&handover_hdr->f_BitMapStart) != kEfiOk) {
--trials;
if (!trials) {
- writer.Write("BootZ: Unable to allocate sufficent memory, trying again with 2GB...\r");
+ writer.Write("BootZ: Unable to allocate sufficient memory, trying again with 2GB...\r");
trials = 3 * 10000000;
diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h
index f6f2d1dd..309a4338 100644
--- a/dev/kernel/FSKit/HeFS.h
+++ b/dev/kernel/FSKit/HeFS.h
@@ -29,7 +29,8 @@
#define kHeFSDefaultVolumeName u8"HeFS Volume"
-#define kHeFSINDStartOffset (sizeof(HEFS_INDEX_NODE_DIRECTORY) + sizeof(HEFS_BOOT_NODE))
+#define kHeFSINDStartOffset (sizeof(HEFS_BOOT_NODE))
+#define kHeFSINStartOffset (sizeof(HEFS_INDEX_NODE_DIRECTORY))
#define kHeFSSearchAllStr u8"*"
@@ -176,7 +177,7 @@ struct PACKED HEFS_INDEX_NODE final {
/// @details Using an offset to ask fBase, and fLength to compute each slice's length.
UInt64 fOffsetSlices;
- HEFS_SLICE_NODE fSlices[kHeFSSliceCount]; /// @brief block slice
+ HEFS_SLICE_NODE fSlices[kHeFSSliceCount]; /// @brief block slice, unused as of current HeFS.
Char fPad[309];
};
diff --git a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
index ad4f9eeb..80053ea8 100644
--- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
+++ b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
@@ -144,12 +144,6 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz
lba /= sector_sz;
- if (lba > kSATASectorCount) {
- kout << "Out of range LBA.\r";
- err_global_get() = kErrorDisk;
- return;
- }
-
if (!buffer || size_buffer == 0) {
kout << "Invalid buffer for AHCI I/O.\r";
err_global_get() = kErrorDisk;
@@ -160,12 +154,12 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz
UInt16 timeout = 0;
- constexpr static UInt16 kTimeout = 0x7000;
+ constexpr static UInt16 kTimeout = 0x8000;
while (slot == ~0UL) {
- kout << "No free command slot found, AHCI disk is busy!\r";
-
if (timeout > kTimeout) {
+ kout << "No free command slot found, AHCI disk is busy!\r";
+
err_global_get() = kErrorDisk;
return;
}
@@ -265,7 +259,18 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz
// Issue command
kSATAHba->Ports[kSATAIndex].Ci = (1 << slot);
+ timeout = 0UL;
+
while (YES) {
+ if (timeout > kTimeout) {
+ kout << "Disk hangup!\r";
+
+ err_global_get() = kErrorDisk;
+ return;
+ }
+
+ ++timeout;
+
if (!(kSATAHba->Ports[kSATAIndex].Ci & (1 << slot))) break;
}
diff --git a/dev/kernel/src/FS/HeFS+FileSystemParser.cc b/dev/kernel/src/FS/HeFS+FileSystemParser.cc
index da55432a..010dbc5d 100644
--- a/dev/kernel/src/FS/HeFS+FileSystemParser.cc
+++ b/dev/kernel/src/FS/HeFS+FileSystemParser.cc
@@ -32,7 +32,7 @@ namespace Detail {
/***********************************************************************************/
STATIC ATTRIBUTE(unused) _Output Void
hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, DriveTrait* mnt, const Lba& start_ind,
- Lba& start, const BOOL try_new = NO);
+ Lba& start);
/***********************************************************************************/
/// @brief Get the index node of a file or directory.
@@ -107,9 +107,8 @@ namespace Detail {
/// @param start The starting point of the traversal.
/// @note This function is used to traverse the RB-Tree of the filesystem.
/// @internal Internal filesystem use only.
- STATIC ATTRIBUTE(unused) Void
- hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, DriveTrait* mnt, const Lba& ind_start,
- Lba& start, const BOOL try_new) {
+ STATIC ATTRIBUTE(unused) Void hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, DriveTrait* mnt,
+ const Lba& ind_start, Lba& start) {
if (!mnt || !dir) return;
BOOL check_is_good = NO;
@@ -149,8 +148,6 @@ namespace Detail {
check_is_good = YES;
continue;
} else {
- if (!try_new) break;
-
if (start == 0) {
start = ind_start;
continue;
@@ -162,10 +159,8 @@ namespace Detail {
}
}
- if (try_new) start += sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ start += sizeof(HEFS_INDEX_NODE_DIRECTORY);
if (start == 0) start = ind_start;
-
- (Void)(kout << "LBA_" << hex_number(start) << kendl);
}
/***********************************************************************************/
@@ -351,7 +346,7 @@ namespace Detail {
break;
}
- hefsi_traverse_tree(tmpend, mnt, root->fStartIND, child_first, YES);
+ hefsi_traverse_tree(tmpend, mnt, root->fStartIND, child_first);
}
}
@@ -435,8 +430,8 @@ namespace Detail {
prev_location = start;
- hefsi_traverse_tree(tmpdir, mnt, root->fStartIND, start, YES);
- if (start > root->fEndIND) break;
+ hefsi_traverse_tree(tmpdir, mnt, root->fStartIND, start);
+ if (start > root->fEndIND || start == 0) break;
}
err_global_get() = kErrorDisk;
@@ -504,6 +499,7 @@ namespace Detail {
err_global_get() = kErrorSuccess;
delete dir;
+ dir = nullptr;
return node_arr;
}
@@ -512,8 +508,8 @@ namespace Detail {
}
}
- hefsi_traverse_tree(dir, mnt, root->fStartIND, start, YES);
- if (start > root->fEndIND) break;
+ hefsi_traverse_tree(dir, mnt, root->fStartIND, start);
+ if (start > root->fEndIND || start == 0) break;
}
err_global_get() = kErrorSuccess;
@@ -586,9 +582,8 @@ namespace Detail {
SizeT cnt = 0ULL;
while (cnt < kHeFSSliceCount) {
- HEFS_SLICE_NODE& slice = node->fSlices[cnt];
- slice.fBase = offset;
- slice.fLength = kHeFSBlockLen;
+ node->fSlices[cnt].fBase = offset;
+ node->fSlices[cnt].fLength = kHeFSBlockLen;
offset += kHeFSBlockLen;
++cnt;
@@ -601,7 +596,7 @@ namespace Detail {
mnt->fOutput(mnt->fPacket);
root->fStartIN += sizeof(HEFS_INDEX_NODE);
- root->fStartBlock += (kHeFSSliceCount * kHeFSBlockLen);
+ root->fStartBlock += kHeFSBlockLen;
root->fChecksum = ke_calculate_crc32((Char*) root, sizeof(HEFS_BOOT_NODE));
@@ -665,7 +660,7 @@ namespace Detail {
}
}
- hefsi_traverse_tree(dir, mnt, root->fStartIND, start, YES);
+ hefsi_traverse_tree(dir, mnt, root->fStartIND, start);
if (start > root->fEndIND || start == 0) break;
}
@@ -737,7 +732,7 @@ namespace Detail {
mnt->fOutput(mnt->fPacket);
}
- hefsi_traverse_tree(dir, mnt, root->fStartIND, start, NO);
+ hefsi_traverse_tree(dir, mnt, root->fStartIND, start);
}
err_global_get() = kErrorSuccess;
@@ -827,23 +822,26 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* mnt, _Input c
MUST_PASS(root->fSectorSize);
- const SizeT max_lba = mnt->fLbaEnd / root->fSectorSize;
+ /// @note all HeFS strucutres are equal to 512, so here it's fine, unless fSectoSize is 2048.
+ const SizeT max_lba = (mnt->fLbaEnd / 4) / root->fSectorSize;
- const SizeT dir_max = max_lba / 20; // 20% for directory metadata
- const SizeT inode_max = max_lba / 20; // 10% for inodes
+ const SizeT dir_max = max_lba / 30; // 20% for directory inodes
+ const SizeT inode_max = max_lba / 60; // 30% for inodes
root->fStartIND = mnt->fLbaStart + kHeFSINDStartOffset;
root->fEndIND = root->fStartIND + dir_max;
- root->fStartIN = root->fEndIND + sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ root->fStartIN = root->fEndIND;
root->fEndIN = root->fStartIN + inode_max;
- constexpr SizeT kHeFSPreallocateCount = 0x6UL;
+ root->fStartBlock = root->fEndIN;
+ root->fEndBlock = mnt->fLbaEnd;
+
+ constexpr const SizeT kHeFSPreallocateCount = 0x6UL;
root->fINDCount = 0;
- // let's lie here.
- root->fDiskSize = mnt->fLbaEnd;
+ root->fDiskSize = drv_std_get_size();
root->fDiskStatus = kHeFSStatusUnlocked;
root->fDiskFlags = flags;
@@ -856,9 +854,6 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* mnt, _Input c
root->fDiskKind = kHeFSUnknown;
}
- root->fStartBlock = root->fEndIN + sizeof(HEFS_INDEX_NODE);
- root->fEndBlock = mnt->fLbaEnd;
-
root->fVersion = kHeFSVersion;
root->fVID = kHeFSInvalidVID;
@@ -1015,48 +1010,32 @@ _Output Bool HeFileSystemParser::INodeManip(_Input DriveTrait* mnt, VoidPtr bloc
return NO;
}
- SizeT cnt = block_sz / sizeof(HEFS_INDEX_NODE);
+ SizeT cnt = block_sz / sizeof(HEFS_INDEX_NODE) + 1;
auto nodes = Detail::hefsi_fetch_in(root, mnt, dir, name, kind, &cnt);
if (!nodes) return NO;
- SizeT sz_out = 0;
-
for (SizeT i = 0UL; i < cnt; ++i) {
auto& start = nodes[i];
SizeT cnt_slice = 0;
- while (cnt_slice < kHeFSSliceCount) {
- HEFS_SLICE_NODE& slice = start.fSlices[cnt_slice];
-
- mnt->fPacket.fPacketLba = slice.fBase + start.fOffsetSlices;
- mnt->fPacket.fPacketSize = kHeFSBlockLen;
- mnt->fPacket.fPacketContent = block;
-
- if (mnt->fPacket.fPacketLba > root->fEndBlock) {
- goto inode_manip_fail;
- }
-
- if (!in) {
- mnt->fOutput(mnt->fPacket);
- delete[] nodes;
- return YES;
- } else {
- mnt->fInput(mnt->fPacket);
- sz_out += kHeFSBlockLen;
+ mnt->fPacket.fPacketLba = start.fOffsetSlices;
+ mnt->fPacket.fPacketSize = kHeFSBlockLen;
+ mnt->fPacket.fPacketContent = block;
- if (sz_out >= block_sz) {
- delete[] nodes;
- return YES;
- }
- }
-
- ++cnt_slice;
+ if (in) {
+ mnt->fInput(mnt->fPacket);
+ } else {
+ mnt->fOutput(mnt->fPacket);
}
+
+ delete[] nodes;
+ return mnt->fPacket.fPacketGood == YES;
}
-inode_manip_fail:
delete[] nodes;
+ nodes = nullptr;
+
return NO;
}