diff options
| author | Amlal <amlal@nekernel.org> | 2025-04-30 09:39:01 +0200 |
|---|---|---|
| committer | Amlal <amlal@nekernel.org> | 2025-04-30 09:39:01 +0200 |
| commit | 8c76c3c1e9723d6d63513fa5bb2550e940c43e00 (patch) | |
| tree | c4b843073ec95b8e7f554dd58fa905bfeec61d35 /dev/kernel/src/FS | |
| parent | 40980a0c8e32a3cb650d1e5821a8ae5daa4628f4 (diff) | |
kernel, FS/HeFS: saving changes on HeFS IFS.
Signed-off-by: Amlal <amlal@nekernel.org>
Diffstat (limited to 'dev/kernel/src/FS')
| -rw-r--r-- | dev/kernel/src/FS/HeFS.cc | 202 |
1 files changed, 130 insertions, 72 deletions
diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index e3dcb699..01df612e 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -30,7 +30,7 @@ namespace Detail { /// @note This function is used to traverse the RB-Tree of the filesystem. /// @internal Internal filesystem use only. STATIC ATTRIBUTE(unused) _Output Void - hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start, Bool hop_watch = NO); + hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start); /// @brief Get the index node of a file or directory. /// @param root The root node of the filesystem. @@ -76,22 +76,19 @@ namespace Detail { /// @note This function is used to traverse the RB-Tree of the filesystem. /// @internal Internal filesystem use only. STATIC ATTRIBUTE(unused) _Output Void - hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start, Bool hop_watch) { - if (dir->fChild != 0) { - start = dir->fChild; - } else if (dir->fNext != 0) { + hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start) { + if (dir->fNext != 0) { start = dir->fNext; - } else if (dir->fParent != 0) { - start = dir->fParent; } else if (dir->fPrev != 0) { start = dir->fPrev; } else { - if (hop_watch) { - err_global_get() = kErrorDisk; - return; + if (dir->fParent != 0) { + start = dir->fParent; + } else if (dir->fPrev != 0) { + start = dir->fPrev; + } else { + start += kHeFSINDStartOffset; } - - start += kHeFSINDStartOffset; } kout << "Traversing RB-Tree...\r"; @@ -133,9 +130,31 @@ namespace Detail { mnt->fInput(mnt->fPacket); + HEFS_INDEX_NODE_DIRECTORY* cousin_child = + (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY)); + + mnt->fPacket.fPacketLba = cousin->fChild; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = cousin; + + mnt->fInput(mnt->fPacket); + + grand_parent->fChild = cousin->fChild; + cousin_child->fParent = parent->fParent; + parent->fParent = cousin->fParent; cousin->fChild = start; + cousin_child->fChecksum = + ke_calculate_crc32((Char*) cousin_child, sizeof(HEFS_INDEX_NODE_DIRECTORY)); + + grand_parent->fChecksum = + ke_calculate_crc32((Char*) grand_parent, sizeof(HEFS_INDEX_NODE_DIRECTORY)); + + parent->fChecksum = ke_calculate_crc32((Char*) parent, sizeof(HEFS_INDEX_NODE_DIRECTORY)); + + cousin->fChecksum = ke_calculate_crc32((Char*) cousin, sizeof(HEFS_INDEX_NODE_DIRECTORY)); + mnt->fPacket.fPacketLba = parent->fParent; mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); mnt->fPacket.fPacketContent = grand_parent; @@ -214,7 +233,7 @@ namespace Detail { return 0; } - /// @brief Alllocate IND for boot node-> + /// @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 { @@ -225,12 +244,14 @@ namespace Detail { if (mnt) { HEFS_INDEX_NODE_DIRECTORY* tmpdir = - (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY)); + (HEFS_INDEX_NODE_DIRECTORY*) mm_new_heap(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No); auto start = root->fStartIND; + MUST_PASS(root->fStartIND > mnt->fLbaStart); + while (YES) { - if (start == 0) break; + auto tmp = start; mnt->fPacket.fPacketLba = start; mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); @@ -242,7 +263,7 @@ namespace Detail { break; } - if ((!tmpdir->fCreated && tmpdir->fDeleted) || *tmpdir->fName == 0) { + if ((!tmpdir->fCreated && tmpdir->fDeleted)) { HEFS_INDEX_NODE_DIRECTORY* dirent = (HEFS_INDEX_NODE_DIRECTORY*) mm_new_heap(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No); @@ -264,7 +285,7 @@ namespace Detail { dirent->fPrev = tmpdir->fPrev; dirent->fParent = tmpdir->fParent; dirent->fChild = tmpdir->fChild; - dirent->fColor = tmpdir->fColor; + dirent->fColor = tmpdir->fColor; if (dirent->fColor < kHeFSRed) { dirent->fColor = kHeFSBlack; @@ -295,7 +316,7 @@ namespace Detail { mnt->fInput(mnt->fPacket); - if ((!tmpend->fCreated && tmpend->fDeleted) || *tmpend->fName == 0) { + if ((!tmpend->fCreated && tmpend->fDeleted)) { break; } @@ -316,7 +337,7 @@ namespace Detail { dirent->fChecksum = ke_calculate_crc32((Char*) dirent, sizeof(HEFS_INDEX_NODE_DIRECTORY)); - mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketLba = tmp; mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); mnt->fPacket.fPacketContent = dirent; @@ -325,6 +346,15 @@ namespace Detail { err_global_get() = kErrorSuccess; mm_delete_heap(dirent); + mm_delete_heap(tmpdir); + + ++root->fINDCount; + + mnt->fPacket.fPacketLba = mnt->fLbaStart; + mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); + mnt->fPacket.fPacketContent = root; + + mnt->fOutput(mnt->fPacket); return YES; } @@ -334,6 +364,7 @@ namespace Detail { } err_global_get() = kErrorDisk; + mm_delete_heap(tmpdir); return NO; } @@ -365,7 +396,7 @@ namespace Detail { if (dir->fKind == kHeFSFileKindDirectory) { if (KStringBuilder::Equals(dir_name, dir->fName)) { - if (ke_calculate_crc32((Char*) &dir, sizeof(HEFS_INDEX_NODE_DIRECTORY)) != + if (ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY)) != dir->fChecksum) ke_panic(RUNTIME_CHECK_FILESYSTEM, "CRC32 failure on HeFS IND!"); @@ -425,7 +456,7 @@ namespace Detail { if (dir->fKind == kHeFSFileKindDirectory) { if (KStringBuilder::Equals(dir_name, dir->fName) || KStringBuilder::Equals(dir_name, kHeFSSearchAllStr)) { - if (ke_calculate_crc32((Char*) &dir, sizeof(HEFS_INDEX_NODE_DIRECTORY)) != + if (ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY)) != dir->fChecksum) ke_panic(RUNTIME_CHECK_FILESYSTEM, "CRC32 failure on HeFS IND!"); @@ -438,7 +469,7 @@ namespace Detail { mnt->fInput(mnt->fPacket); if (mnt->fPacket.fPacketGood) { - if (ke_calculate_crc32((Char*) &node, sizeof(HEFS_INDEX_NODE)) != node->fChecksum) + if (ke_calculate_crc32((Char*) node, sizeof(HEFS_INDEX_NODE)) != node->fChecksum) ke_panic(RUNTIME_CHECK_FILESYSTEM, "CRC32 failure on HeFS IND!"); if (KStringBuilder::Equals(file_name, node->fName) && node->fKind == kind) { @@ -553,6 +584,16 @@ namespace Detail { return NO; } + if (ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY)) != dir->fChecksum) { + dir->fChecksum = ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY)); + + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir; + + mnt->fOutput(mnt->fPacket); + } + if (start == root->fStartIND) { dir->fColor = kHeFSBlack; @@ -590,61 +631,35 @@ namespace Detail { return NO; } - if (dir_uncle->fColor == kHeFSRed) { - dir_parent->fColor = kHeFSBlack; - dir_uncle->fColor = kHeFSBlack; - - mnt->fPacket.fPacketLba = dir->fParent; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir_parent; - - mnt->fOutput(mnt->fPacket); - - mnt->fPacket.fPacketLba = dir_uncle->fParent; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir_uncle; - - mnt->fOutput(mnt->fPacket); - - if (!mnt->fPacket.fPacketGood) { - err_global_get() = kErrorDiskIsCorrupted; - - return NO; - } - - hefsi_traverse_tree(dir, start, YES); + if (dir_parent->fNext == start) { + hefsi_rotate_tree(start, mnt, YES); + hefsi_traverse_tree(dir_parent, start); if (start > root->fEndIND || start == 0) break; continue; - } else { - if (dir_parent->fNext == start) { - hefsi_rotate_tree(start, mnt, YES); - hefsi_traverse_tree(dir_parent, start, YES); - - if (start > root->fEndIND || start == 0) break; - - continue; - } + } - dir_parent->fColor = kHeFSBlack; + dir_parent->fColor = kHeFSBlack; - mnt->fPacket.fPacketLba = dir->fParent; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir_parent; + dir_parent->fChecksum = + ke_calculate_crc32((Char*) dir_parent, sizeof(HEFS_INDEX_NODE_DIRECTORY)); - mnt->fOutput(mnt->fPacket); + mnt->fPacket.fPacketLba = dir->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir_parent; - if (!mnt->fPacket.fPacketGood) { - err_global_get() = kErrorDiskIsCorrupted; + mnt->fOutput(mnt->fPacket); - return NO; - } + if (!mnt->fPacket.fPacketGood) { + err_global_get() = kErrorDiskIsCorrupted; - hefsi_rotate_tree(start, mnt, NO); + return NO; } - hefsi_traverse_tree(dir, start, YES); + hefsi_rotate_tree(start, mnt, NO); + + hefsi_traverse_tree(dir, start); if (start > root->fEndIND || start == 0) break; } @@ -703,10 +718,15 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input if (KStringBuilder::Equals(root->fMagic, kHeFSMagic) && root->fVersion == kHeFSVersion) { err_global_get() = kErrorSuccess; - return YES; } + if (ke_calculate_crc32((Char*) root, sizeof(HEFS_BOOT_NODE)) != root->fChecksum && + root->fChecksum > 0) { + err_global_get() = kErrorDiskIsCorrupted; + return NO; + } + rt_copy_memory((VoidPtr) "fs/hefs-packet", drive->fPacket.fPacketMime, rt_string_len("fs/hefs-packet")); @@ -724,9 +744,11 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input root->fSectorCount = drv_std_get_sector_count(); root->fSectorSize = drive->fSectorSz; + MUST_PASS(root->fSectorSize); + const SizeT max_lba = drive->fLbaEnd / root->fSectorSize; - const SizeT dir_max = max_lba / 20; // 5% for directory metadata + const SizeT dir_max = max_lba / 20; // 20% for directory metadata const SizeT inode_max = max_lba / 10; // 10% for inodes root->fStartIND = drive->fLbaStart + kHeFSINDStartOffset; @@ -737,7 +759,7 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input constexpr SizeT kHeFSPreallocateCount = 0x7UL; - root->fINDCount = kHeFSPreallocateCount; + root->fINDCount = 0; root->fDiskSize = drv_std_get_size(); root->fDiskStatus = kHeFSStatusUnlocked; @@ -758,7 +780,7 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input root->fVID = kHeFSInvalidVID; - root->fChecksum = ke_calculate_crc32((Char*) &root, sizeof(HEFS_BOOT_NODE)); + root->fChecksum = ke_calculate_crc32((Char*) root, sizeof(HEFS_BOOT_NODE)); drive->fPacket.fPacketLba = drive->fLbaStart; drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); @@ -766,6 +788,43 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input drive->fOutput(drive->fPacket); + HEFS_INDEX_NODE_DIRECTORY* dir = + (HEFS_INDEX_NODE_DIRECTORY*) mm_new_heap(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No); + + MUST_PASS(dir); + + urt_copy_memory((VoidPtr) u8"\0", dir->fName, urt_string_len(u8"\0")); + + dir->fFlags = flags; + dir->fKind = kHeFSFileKindDirectory; + + dir->fCreated = 0; + dir->fDeleted = 1; + dir->fEntryCount = 0; + + dir->fIndexNodeChecksum = 0; + + dir->fUID = 0; + dir->fGID = 0; + dir->fMode = 0; + + dir->fColor = kHeFSBlack; + + dir->fChild = 0; + dir->fParent = 0; + dir->fNext = 0; + dir->fPrev = 0; + + dir->fChecksum = ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY)); + + drive->fPacket.fPacketLba = root->fStartIND; + drive->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + drive->fPacket.fPacketContent = dir; + + drive->fOutput(drive->fPacket); + + mm_delete_heap(dir); + (Void)(kout << "Drive kind: " << drive->fProtocol() << kendl); (Void)(kout8 << u8"Partition name: " << root->fVolName << kendl8); (Void)(kout << "Start IND: " << hex_number(root->fStartIND) << kendl); @@ -786,8 +845,6 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input this->CreateDirectory(drive, kHeFSEncodingUTF8, kFileMap[i]); } - Detail::hefsi_balance_filesystem(root, drive); - err_global_get() = kErrorSuccess; if (drive->fPacket.fPacketGood) return YES; @@ -830,6 +887,7 @@ _Output Bool HeFileSystemParser::CreateDirectory(_Input DriveTrait* drive, _Inpu urt_copy_memory((VoidPtr) dir, name, urt_string_len(dir) + 1); if (Detail::hefsi_allocate_index_node_directory(root, drive, name, flags)) { + Detail::hefsi_balance_filesystem(root, drive); mm_delete_heap((VoidPtr) root); delete[] name; return YES; @@ -885,7 +943,7 @@ _Output Bool HeFileSystemParser::CreateFile(_Input DriveTrait* drive, _Input con node->fKind = kHeFSFileKindRegular; node->fFlags = flags; node->fChecksum = 0; - node->fChecksum = ke_calculate_crc32((Char*) &node, sizeof(HEFS_INDEX_NODE)); + node->fChecksum = ke_calculate_crc32((Char*) node, sizeof(HEFS_INDEX_NODE)); node->fGID = 0; node->fUID = 0; |
