summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/src/FS/HeFS+FileSystemParser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dev/kernel/src/FS/HeFS+FileSystemParser.cc')
-rw-r--r--dev/kernel/src/FS/HeFS+FileSystemParser.cc443
1 files changed, 264 insertions, 179 deletions
diff --git a/dev/kernel/src/FS/HeFS+FileSystemParser.cc b/dev/kernel/src/FS/HeFS+FileSystemParser.cc
index b3e1d4d0..e91040b2 100644
--- a/dev/kernel/src/FS/HeFS+FileSystemParser.cc
+++ b/dev/kernel/src/FS/HeFS+FileSystemParser.cc
@@ -32,12 +32,12 @@ 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.
/// @param root The root node of the filesystem.
- /// @param mnt The drive to read from.
+ /// @param mnt The mnt to read from.
/// @param dir_name The name of the directory.
/// @param file_name The name of the file.
/// @param kind The kind of the file (regular, directory, block, character, FIFO, socket, symbolic
@@ -47,12 +47,12 @@ namespace Detail {
DriveTrait* mnt,
const Utf8Char* dir_name,
const Utf8Char* file_name,
- UInt8 kind, SizeT* cnt);
+ UInt8 kind);
/***********************************************************************************/
/// @brief Allocate a new index node->
/// @param root The root node of the filesystem.
- /// @param mnt The drive to read/write from.
+ /// @param mnt The mnt to read/write from.
/// @param dir_name The name of the parent directory.
/// @return Status, see err_global_get().
/***********************************************************************************/
@@ -63,14 +63,14 @@ namespace Detail {
/***********************************************************************************/
/// @brief Balance RB-Tree of the filesystem.
/// @param root The root node of the filesystem.
- /// @param mnt The drive to read/write from.
+ /// @param mnt The mnt to read/write from.
/// @return Status, see err_global_get().
/***********************************************************************************/
STATIC ATTRIBUTE(unused) _Output BOOL hefsi_balance_ind(HEFS_BOOT_NODE* root, DriveTrait* mnt);
/// @brief Alllocate IND from boot node.
/// @param root The root node of the filesystem.
- /// @param mnt The drive to read from.
+ /// @param mnt The mnt to read from.
/// @param dir_name The name of the directory.
/// @param dir_name The parent of the directory.
/// @param flags Directory flags.
@@ -107,65 +107,63 @@ 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;
+ BOOL check_is_good = NO;
+ HEFS_INDEX_NODE_DIRECTORY* dir_tmp = new HEFS_INDEX_NODE_DIRECTORY();
while (YES) {
mnt->fPacket.fPacketLba = start;
mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = dir;
+ mnt->fPacket.fPacketContent = dir_tmp;
mnt->fInput(mnt->fPacket);
if (!mnt->fPacket.fPacketGood) break;
- if (dir->fNext != 0) {
+ if (dir_tmp->fNext != 0) {
if (check_is_good) break;
- start = dir->fNext;
+ start = dir_tmp->fNext;
check_is_good = YES;
continue;
- } else if (dir->fPrev != 0) {
+ } else if (dir_tmp->fPrev != 0) {
if (check_is_good) break;
- start = dir->fPrev;
+ start = dir_tmp->fPrev;
check_is_good = YES;
continue;
} else {
- if (dir->fParent != 0) {
+ if (dir_tmp->fParent != 0) {
if (check_is_good) break;
- start = dir->fParent;
+ start = dir_tmp->fParent;
check_is_good = YES;
continue;
- } else if (dir->fPrev != 0) {
+ } else if (dir_tmp->fPrev != 0) {
if (check_is_good) break;
- start = dir->fPrev;
+ start = dir_tmp->fPrev;
check_is_good = YES;
continue;
} else {
- if (!try_new) break;
-
if (start == 0) {
start = ind_start;
continue;
}
- start += kHeFSINDStartOffset;
+ start += sizeof(HEFS_INDEX_NODE_DIRECTORY);
break;
}
}
}
- if (try_new) start += sizeof(HEFS_INDEX_NODE_DIRECTORY);
- if (start == 0) start = ind_start;
+ delete dir_tmp;
- (Void)(kout << "LBA_" << number(start) << kendl);
+ start += sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ if (start == 0) start = ind_start;
}
/***********************************************************************************/
@@ -254,7 +252,7 @@ namespace Detail {
/// @brief Alllocate IND from boot node.
/// @param root The root node of the filesystem.
- /// @param mnt The drive to read from.
+ /// @param mnt The mnt to read from.
/// @param dir_name The name of the directory.
/// @param dir_name The parent of the directory.
/// @param flags Directory flags.
@@ -307,7 +305,7 @@ namespace Detail {
dirent->fModified = 0UL;
dirent->fEntryCount = 0UL;
- dirent->fKind = kHeFSFileKindDirectory;
+ dirent->fReserved = 0;
dirent->fFlags = flags;
dirent->fChecksum = 0;
@@ -351,7 +349,7 @@ namespace Detail {
break;
}
- hefsi_traverse_tree(tmpend, mnt, root->fStartIND, child_first, YES);
+ hefsi_traverse_tree(tmpend, mnt, root->fStartIND, child_first);
}
}
@@ -422,6 +420,8 @@ namespace Detail {
else
--root->fINDCount;
+ root->fChecksum = ke_calculate_crc32((Char*) root, sizeof(HEFS_BOOT_NODE));
+
mnt->fPacket.fPacketLba = mnt->fLbaStart;
mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
mnt->fPacket.fPacketContent = root;
@@ -433,8 +433,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;
@@ -449,7 +449,7 @@ namespace Detail {
/// @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.
+ /// @param mnt The mnt to read from.
/// @param dir_name The name of the directory.
/// @param file_name The name of the file.
/// @param kind The kind of the file (regular, directory, block, character, FIFO, socket, symbolic
@@ -458,24 +458,16 @@ namespace Detail {
DriveTrait* mnt,
const Utf8Char* dir_name,
const Utf8Char* file_name,
- UInt8 kind, SizeT* cnt) {
+ UInt8 kind) {
if (mnt) {
- HEFS_INDEX_NODE* node_arr = new HEFS_INDEX_NODE[*cnt];
+ if (root->fStartIND > root->fEndIND) return nullptr;
+ if (root->fStartIN > root->fEndIN) return nullptr;
- if (!node_arr) {
- return nullptr;
- }
+ auto start = root->fStartIND;
+ HEFS_INDEX_NODE* node = new HEFS_INDEX_NODE();
- HEFS_INDEX_NODE* node = (HEFS_INDEX_NODE*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE));
HEFS_INDEX_NODE_DIRECTORY* dir =
- (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
-
- auto start = root->fStartIND;
-
- if (start > root->fEndIND) return nullptr;
- if (root->fStartIN > root->fEndIN) return nullptr;
-
- auto start_cnt = 0UL;
+ (HEFS_INDEX_NODE_DIRECTORY*) mm_new_heap(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No);
while (YES) {
mnt->fPacket.fPacketLba = start;
@@ -484,50 +476,37 @@ namespace Detail {
mnt->fInput(mnt->fPacket);
- if (!mnt->fPacket.fPacketGood) {
- err_global_get() = kErrorFileNotFound;
+ (Void)(kout << hex_number(hefsi_hash_64(dir_name)) << kendl);
+ (Void)(kout << hex_number(dir->fHashPath) << kendl);
- delete[] node_arr;
- return nullptr;
- }
+ if (hefsi_hash_64(dir_name) == dir->fHashPath) {
+ for (SizeT inode_index = 0UL; inode_index < kHeFSSliceCount; ++inode_index) {
+ mnt->fPacket.fPacketLba = dir->fINSlices[inode_index];
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE);
+ mnt->fPacket.fPacketContent = node;
- if (dir->fKind == kHeFSFileKindDirectory) {
- if (hefsi_hash_64(dir_name) == dir->fHashPath ||
- KStringBuilder::Equals(dir_name, kHeFSSearchAllStr)) {
- if (ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY)) !=
- dir->fChecksum)
- ke_panic(RUNTIME_CHECK_FILESYSTEM, "CRC32 checksum failed on HeFS IND!");
-
- for (SizeT inode_index = 0UL; inode_index < kHeFSSliceCount; ++inode_index) {
- if (dir->fINSlices[inode_index] != 0) {
- if (ke_calculate_crc32((Char*) node, sizeof(HEFS_INDEX_NODE)) != node->fChecksum)
- ke_panic(RUNTIME_CHECK_FILESYSTEM, "CRC32 failure on HeFS IND!");
-
- if (hefsi_hash_64(file_name) == node->fHashPath && node->fKind == kind) {
- node_arr[start_cnt] = *node;
- ++start_cnt;
-
- if (start_cnt > *cnt) {
- err_global_get() = kErrorSuccess;
- return node_arr;
- }
- }
- }
+ mnt->fInput(mnt->fPacket);
+
+ (Void)(kout << hex_number(hefsi_hash_64(file_name)) << kendl);
+ (Void)(kout << hex_number(node->fHashPath) << kendl);
+
+ if (hefsi_hash_64(file_name) == node->fHashPath && node->fKind == kind) {
+ return node;
}
- } else if (dir->fHashPath == 0) {
- break;
}
}
- hefsi_traverse_tree(dir, mnt, root->fStartIND, start, YES);
- if (start > root->fEndIND || start == 0) break;
+ hefsi_traverse_tree(dir, mnt, root->fStartIND, start);
}
- err_global_get() = kErrorSuccess;
- return node_arr;
+ delete node;
+ node = nullptr;
+
+ delete dir;
+ dir = nullptr;
}
- kout << "Error: Failed to find index node->\r";
+ kout << "Error: Failed to find IN.\r";
err_global_get() = kErrorFileNotFound;
@@ -537,7 +516,7 @@ namespace Detail {
STATIC ATTRIBUTE(unused) _Output BOOL
hefsi_update_in_status(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf8Char* dir_name,
HEFS_INDEX_NODE* node, BOOL delete_or_create) {
- if (!root) return NO;
+ if (!root || !mnt) return NO;
auto start = root->fStartIND;
@@ -557,8 +536,6 @@ namespace Detail {
mnt->fInput(mnt->fPacket);
- kout8 << dir_name << u8"\r";
-
(Void)(kout << hex_number(hefsi_hash_64(dir_name)) << kendl);
(Void)(kout << hex_number(dir->fHashPath) << kendl);
@@ -567,15 +544,8 @@ namespace Detail {
if (dir->fINSlices[inode_index] == 0 && !delete_or_create) {
dir->fINSlices[inode_index] = root->fStartIN;
- root->fStartIN += sizeof(HEFS_INDEX_NODE);
-
- mnt->fPacket.fPacketLba = mnt->fLbaStart;
- mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
- mnt->fPacket.fPacketContent = root;
-
- mnt->fOutput(mnt->fPacket);
-
++dir->fEntryCount;
+
dir->fChecksum = ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY));
mnt->fPacket.fPacketLba = start;
@@ -586,12 +556,28 @@ namespace Detail {
auto lba = dir->fINSlices[inode_index];
+ node->fOffsetSliceLow = (UInt32) (root->fStartBlock);
+ node->fOffsetSliceHigh = (UInt32) (root->fStartBlock >> 32);
+
+ node->fChecksum = ke_calculate_crc32((Char*) node, sizeof(HEFS_INDEX_NODE));
+
mnt->fPacket.fPacketLba = lba;
mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE);
mnt->fPacket.fPacketContent = node;
mnt->fOutput(mnt->fPacket);
+ root->fStartIN += sizeof(HEFS_INDEX_NODE);
+ root->fStartBlock += kHeFSBlockLen;
+
+ root->fChecksum = ke_calculate_crc32((Char*) root, sizeof(HEFS_BOOT_NODE));
+
+ mnt->fPacket.fPacketLba = mnt->fLbaStart;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ mnt->fPacket.fPacketContent = root;
+
+ mnt->fOutput(mnt->fPacket);
+
mm_delete_heap(dir);
return YES;
@@ -606,17 +592,17 @@ namespace Detail {
mnt->fInput(mnt->fPacket);
- kout8 << u8"HashPath: ";
- (Void)(kout << hex_number(tmp_node.fHashPath) << kendl);
-
- kout8 << u8"HashPath: ";
- (Void)(kout << hex_number(hash_file) << kendl);
-
if (tmp_node.fHashPath != hash_file) {
continue;
}
+ node->fOffsetSliceLow = 0;
+ node->fOffsetSliceHigh = 0;
+
root->fStartIN -= sizeof(HEFS_INDEX_NODE);
+ root->fStartBlock -= kHeFSBlockLen;
+
+ root->fChecksum = ke_calculate_crc32((Char*) root, sizeof(HEFS_BOOT_NODE));
mnt->fPacket.fPacketLba = mnt->fLbaStart;
mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
@@ -649,7 +635,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;
}
@@ -664,7 +650,7 @@ namespace Detail {
/// @brief Balance RB-Tree of the filesystem.
/// @param root The root node of the filesystem.
- /// @param mnt The drive to read/write from.
+ /// @param mnt The mnt to read/write from.
/// @return Status, see err_global_get().
STATIC ATTRIBUTE(unused) _Output BOOL hefsi_balance_ind(HEFS_BOOT_NODE* root, DriveTrait* mnt) {
if (mnt) {
@@ -674,7 +660,7 @@ namespace Detail {
auto start = root->fStartIND;
while (YES) {
- if (start == 0 || start > root->fEndIND) break;
+ if (start == 0UL || start > root->fEndIND) break;
mnt->fPacket.fPacketLba = start;
mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
@@ -698,10 +684,10 @@ namespace Detail {
mnt->fOutput(mnt->fPacket);
}
- if (dir->fColor == kHeFSBlack && dir->fChild != 0) {
+ if (dir->fColor == kHeFSBlack && dir->fChild != 0UL) {
dir->fColor = kHeFSRed;
hefsi_rotate_tree(start, mnt);
- } else if (dir->fColor == kHeFSBlack && dir->fChild == 0) {
+ } else if (dir->fColor == kHeFSBlack && dir->fChild == 0UL) {
dir->fColor = kHeFSBlack;
mnt->fPacket.fPacketLba = start;
@@ -721,7 +707,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;
@@ -739,16 +725,16 @@ namespace Detail {
/// @note This is certainly take longer to format a disk with it, but worth-it in the long run.
namespace Kernel::HeFS {
-/// @brief Make a EPM+HeFS drive out of the disk.
-/// @param drive The drive to write on.
+/// @brief Make a EPM+HeFS mnt out of the disk.
+/// @param mnt The mnt to write on.
/// @return If it was sucessful, see err_local_get().
-_Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input const Int32 flags,
+_Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* mnt, _Input const Int32 flags,
_Input const Utf8Char* vol_name) {
// Verify Disk.
- drive->fVerify(drive->fPacket);
+ mnt->fVerify(mnt->fPacket);
// if disk isn't good, then error out.
- if (false == drive->fPacket.fPacketGood) {
+ if (false == mnt->fPacket.fPacketGood) {
err_global_get() = kErrorDiskIsCorrupted;
return false;
}
@@ -761,13 +747,13 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input
HEFS_BOOT_NODE* root = (HEFS_BOOT_NODE*) RTL_ALLOCA(sizeof(HEFS_BOOT_NODE));
- drive->fPacket.fPacketLba = drive->fLbaStart;
- drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
- drive->fPacket.fPacketContent = root;
+ mnt->fPacket.fPacketLba = mnt->fLbaStart;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ mnt->fPacket.fPacketContent = root;
- drive->fInput(drive->fPacket);
+ mnt->fInput(mnt->fPacket);
- if (!drive->fPacket.fPacketGood) {
+ if (!mnt->fPacket.fPacketGood) {
err_global_get() = kErrorDiskIsCorrupted;
return NO;
@@ -792,13 +778,13 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input
return NO;
}
- rt_copy_memory((VoidPtr) "fs/hefs-packet", drive->fPacket.fPacketMime,
+ rt_copy_memory((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime,
rt_string_len("fs/hefs-packet"));
urt_copy_memory((VoidPtr) vol_name, root->fVolName, urt_string_len(vol_name) + 1);
rt_copy_memory((VoidPtr) kHeFSMagic, root->fMagic, kHeFSMagicLen - 1);
- if (drive->fLbaStart > drive->fLbaEnd) {
+ if (mnt->fLbaStart > mnt->fLbaEnd) {
err_global_get() = kErrorDiskIsCorrupted;
return NO;
@@ -807,71 +793,76 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input
root->fBadSectors = 0;
root->fSectorCount = drv_std_get_sector_count();
- root->fSectorSize = drive->fSectorSz;
+ root->fSectorSize = mnt->fSectorSz;
MUST_PASS(root->fSectorSize);
- const SizeT max_lba = drive->fLbaEnd / root->fSectorSize;
+ /// @note all HeFS strucutres are equal to 512, so here it's fine, unless fSectoSize is 2048.
+ const SizeT max_lba = drv_std_get_size() / 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 / 20; // 20% for directory inodes
+ const SizeT inode_max = max_lba / 30; // 30% for inodes
- root->fStartIND = drive->fLbaStart + kHeFSINDStartOffset;
+ 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 = drv_std_get_size();
root->fINDCount = 0;
- // let's lie here.
- root->fDiskSize = drive->fLbaEnd;
+ root->fDiskSize = drv_std_get_size();
root->fDiskStatus = kHeFSStatusUnlocked;
root->fDiskFlags = flags;
- if (drive->fKind & kMassStorageDrive) {
- } else if (drive->fKind & kHeFSOpticalDrive) {
+ if (mnt->fKind & kMassStorageDrive) {
+ root->fDiskKind = kHeFSMassStorageDevice;
+ } else if (mnt->fKind & kHeFSOpticalDrive) {
root->fDiskKind = kHeFSOpticalDrive;
} else {
root->fDiskKind = kHeFSUnknown;
}
- root->fReserved = 0;
- root->fReserved1 = 0;
-
root->fVersion = kHeFSVersion;
root->fVID = kHeFSInvalidVID;
root->fChecksum = ke_calculate_crc32((Char*) root, sizeof(HEFS_BOOT_NODE));
- drive->fPacket.fPacketLba = drive->fLbaStart;
- drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
- drive->fPacket.fPacketContent = root;
+ mnt->fPacket.fPacketLba = mnt->fLbaStart;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ mnt->fPacket.fPacketContent = root;
- drive->fOutput(drive->fPacket);
+ mnt->fOutput(mnt->fPacket);
- (Void)(kout << "Protocol: " << drive->fProtocol() << kendl);
+ (Void)(kout << "Protocol: " << mnt->fProtocol() << kendl);
(Void)(kout8 << u8"Volume Name: " << root->fVolName << kendl8);
(Void)(kout << "Start IND: " << hex_number(root->fStartIND) << kendl);
+ (Void)(kout << "End IND: " << hex_number(root->fEndIND) << kendl);
+ (Void)(kout << "Start IN: " << hex_number(root->fStartIN) << kendl);
+ (Void)(kout << "End IN: " << hex_number(root->fEndIN) << kendl);
+ (Void)(kout << "Start Block: " << hex_number(root->fStartBlock) << kendl);
+ (Void)(kout << "End Block: " << hex_number(root->fEndBlock) << kendl);
(Void)(kout << "Number of IND: " << hex_number(root->fINDCount) << kendl);
(Void)(kout << "Sector Size: " << hex_number(root->fSectorSize) << kendl);
- (Void)(kout << "Drive Kind:" << Detail::hefs_drive_kind_to_string(root->fDiskKind) << kendl);
+ (Void)(kout << "Drive Kind: " << Detail::hefs_drive_kind_to_string(root->fDiskKind) << kendl);
- if (!drive->fPacket.fPacketGood) {
+ if (!mnt->fPacket.fPacketGood) {
err_global_get() = kErrorDiskIsCorrupted;
-
return NO;
}
+ constexpr const SizeT kHeFSPreallocateCount = 0x6UL;
+
const Utf8Char* kFileMap[kHeFSPreallocateCount] = {u8"/", u8"/boot", u8"/system",
u8"/network", u8"/devices", u8"/media"};
for (SizeT i = 0; i < kHeFSPreallocateCount; ++i) {
- this->CreateINodeDirectory(drive, kHeFSEncodingFlagsUTF8, kFileMap[i]);
+ this->CreateINodeDirectory(mnt, kHeFSEncodingFlagsUTF8, kFileMap[i]);
}
err_global_get() = kErrorSuccess;
@@ -880,13 +871,14 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input
}
/// @brief Create a new directory on the disk.
-/// @param drive The drive to write on.
+/// @param mnt The mnt 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::INodeDirectoryCtl_(_Input DriveTrait* drive,
- _Input const Int32 flags, const Utf8Char* dir,
- const BOOL delete_or_create) {
+_Output Bool HeFileSystemParser::INodeDirectoryCtlManip(_Input DriveTrait* mnt,
+ _Input const Int32 flags,
+ const Utf8Char* dir,
+ const BOOL delete_or_create) {
if (urt_string_len(dir) > kHeFSFileNameLen) {
err_global_get() = kErrorDisk;
return NO;
@@ -894,14 +886,19 @@ _Output Bool HeFileSystemParser::INodeDirectoryCtl_(_Input DriveTrait* drive,
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,
+ rt_copy_memory((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime,
rt_string_len("fs/hefs-packet"));
- drive->fPacket.fPacketLba = drive->fLbaStart;
- drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
- drive->fPacket.fPacketContent = root;
+ mnt->fPacket.fPacketLba = mnt->fLbaStart;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ mnt->fPacket.fPacketContent = root;
+
+ mnt->fInput(mnt->fPacket);
- drive->fInput(drive->fPacket);
+ if (!KStringBuilder::Equals(root->fMagic, kHeFSMagic) || root->fVersion != kHeFSVersion) {
+ err_global_get() = kErrorDisk;
+ return YES;
+ }
if (!KStringBuilder::Equals(root->fMagic, kHeFSMagic) || root->fVersion != kHeFSVersion) {
err_global_get() = kErrorDiskIsCorrupted;
@@ -919,9 +916,9 @@ _Output Bool HeFileSystemParser::INodeDirectoryCtl_(_Input DriveTrait* drive,
return NO;
}
- if (Detail::hefsi_update_ind_status(root, drive, dir, flags, delete_or_create)) {
+ if (Detail::hefsi_update_ind_status(root, mnt, dir, flags, delete_or_create)) {
// todo: make it smarter for high-throughput.
- Detail::hefsi_balance_ind(root, drive);
+ Detail::hefsi_balance_ind(root, mnt);
mm_delete_heap((VoidPtr) root);
return YES;
@@ -931,37 +928,99 @@ _Output Bool HeFileSystemParser::INodeDirectoryCtl_(_Input DriveTrait* drive,
return NO;
}
-_Output Bool HeFileSystemParser::RemoveINodeDirectory(_Input DriveTrait* drive,
+_Output Bool HeFileSystemParser::RemoveINodeDirectory(_Input DriveTrait* mnt,
_Input const Int32 flags,
const Utf8Char* dir) {
- return this->INodeDirectoryCtl_(drive, flags, dir, YES);
+ return this->INodeDirectoryCtlManip(mnt, flags, dir, YES);
}
-_Output Bool HeFileSystemParser::CreateINodeDirectory(_Input DriveTrait* drive,
+_Output Bool HeFileSystemParser::CreateINodeDirectory(_Input DriveTrait* mnt,
_Input const Int32 flags,
const Utf8Char* dir) {
- return this->INodeDirectoryCtl_(drive, flags, dir, NO);
+ return this->INodeDirectoryCtlManip(mnt, flags, dir, NO);
}
-_Output Bool HeFileSystemParser::DeleteINode(_Input DriveTrait* drive, _Input const Int32 flags,
- const Utf8Char* dir, const Utf8Char* name) {
- return this->INodeCtl_(drive, flags, dir, name, YES);
+_Output Bool HeFileSystemParser::DeleteINode(_Input DriveTrait* mnt, _Input const Int32 flags,
+ const Utf8Char* dir, const Utf8Char* name,
+ const UInt8 kind) {
+ return this->INodeCtlManip(mnt, flags, dir, name, YES, kind);
}
-_Output Bool HeFileSystemParser::CreateINode(_Input DriveTrait* drive, _Input const Int32 flags,
- const Utf8Char* dir, const Utf8Char* name) {
- return this->INodeCtl_(drive, flags, dir, name, NO);
+_Output Bool HeFileSystemParser::CreateINode(_Input DriveTrait* mnt, _Input const Int32 flags,
+ const Utf8Char* dir, const Utf8Char* name,
+ const UInt8 kind) {
+ return this->INodeCtlManip(mnt, flags, dir, name, NO, kind);
+}
+
+_Output Bool HeFileSystemParser::INodeManip(_Input DriveTrait* mnt, VoidPtr block, SizeT block_sz,
+ const Utf8Char* dir, const Utf8Char* name,
+ const UInt8 kind, const BOOL is_input) {
+ if (urt_string_len(dir) > kHeFSFileNameLen) {
+ err_global_get() = kErrorDisk;
+ return NO;
+ }
+
+ if (urt_string_len(name) > kHeFSFileNameLen) {
+ err_global_get() = kErrorDisk;
+ return NO;
+ }
+
+ HEFS_BOOT_NODE* root = (HEFS_BOOT_NODE*) mm_new_heap(sizeof(HEFS_BOOT_NODE), Yes, No);
+
+ if (!root) {
+ err_global_get() = kErrorInvalidData;
+ return NO;
+ }
+
+ rt_copy_memory((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime,
+ rt_string_len("fs/hefs-packet"));
+
+ mnt->fPacket.fPacketLba = mnt->fLbaStart;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ mnt->fPacket.fPacketContent = root;
+
+ mnt->fInput(mnt->fPacket);
+
+ if (!KStringBuilder::Equals(root->fMagic, kHeFSMagic) || root->fVersion != kHeFSVersion) {
+ (Void)(kout << "Invalid Boot Node, HeFS partition is invalid." << kendl);
+ mm_delete_heap((VoidPtr) root);
+ err_global_get() = kErrorDisk;
+ return NO;
+ }
+
+ auto start = Detail::hefsi_fetch_in(root, mnt, dir, name, kind);
+
+ if (start) {
+ (Void)(kout << hex_number(start->fHashPath) << kendl);
+ (Void)(kout << hex_number(start->fOffsetSliceLow) << kendl);
+
+ if (start->fOffsetSliceLow) {
+ mnt->fPacket.fPacketLba = start->fOffsetSliceLow | (UInt64) start->fOffsetSliceHigh << 32;
+ mnt->fPacket.fPacketSize = block_sz;
+ mnt->fPacket.fPacketContent = block;
+
+ if (is_input) {
+ mnt->fInput(mnt->fPacket);
+ } else {
+ mnt->fOutput(mnt->fPacket);
+ }
+ }
+ }
+
+ mm_delete_heap((VoidPtr) root);
+ delete start;
+ return YES;
}
/// @brief Create a new file on the disk.
-/// @param drive The drive to write on.
+/// @param mnt The mnt 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::INodeCtl_(_Input DriveTrait* drive, _Input const Int32 flags,
- const Utf8Char* dir, const Utf8Char* name,
- const BOOL delete_or_create) {
+_Output Bool HeFileSystemParser::INodeCtlManip(_Input DriveTrait* mnt, _Input const Int32 flags,
+ const Utf8Char* dir, const Utf8Char* name,
+ const BOOL delete_or_create, const UInt8 kind) {
if (urt_string_len(name) > kHeFSFileNameLen) {
err_global_get() = kErrorDisk;
return NO;
@@ -990,14 +1049,19 @@ _Output Bool HeFileSystemParser::INodeCtl_(_Input DriveTrait* drive, _Input cons
return NO;
}
- rt_copy_memory((VoidPtr) "fs/hefs-packet", drive->fPacket.fPacketMime,
+ rt_copy_memory((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime,
rt_string_len("fs/hefs-packet"));
- drive->fPacket.fPacketLba = drive->fLbaStart;
- drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
- drive->fPacket.fPacketContent = root;
+ mnt->fPacket.fPacketLba = mnt->fLbaStart;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ mnt->fPacket.fPacketContent = root;
- drive->fInput(drive->fPacket);
+ mnt->fInput(mnt->fPacket);
+
+ if (!KStringBuilder::Equals(root->fMagic, kHeFSMagic) || root->fVersion != kHeFSVersion) {
+ err_global_get() = kErrorDisk;
+ return YES;
+ }
if (KStringBuilder::Equals(dir, kHeFSSearchAllStr)) {
kout << "Error: Invalid file name.\r";
@@ -1025,18 +1089,17 @@ _Output Bool HeFileSystemParser::INodeCtl_(_Input DriveTrait* drive, _Input cons
node->fDeleted = delete_or_create ? 1UL : 0UL;
node->fModified = 0;
node->fSize = 0;
- node->fKind = kHeFSFileKindRegular;
+ node->fKind = kind;
node->fFlags = flags;
node->fChecksum = 0;
- node->fChecksum = ke_calculate_crc32((Char*) node, sizeof(HEFS_INDEX_NODE));
node->fGID = 0;
node->fUID = 0;
node->fHashPath = Detail::hefsi_hash_64(name);
- if (Detail::hefsi_update_in_status(root, drive, dir, node, delete_or_create)) {
+ if (Detail::hefsi_update_in_status(root, mnt, dir, node, delete_or_create)) {
mm_delete_heap((VoidPtr) node);
- Detail::hefsi_balance_ind(root, drive);
+ Detail::hefsi_balance_ind(root, mnt);
err_global_get() = kErrorSuccess;
return YES;
@@ -1062,16 +1125,38 @@ Boolean fs_init_hefs(Void) {
HeFileSystemParser parser;
- parser.Format(&kMountPoint, kHeFSEncodingFlagsUTF8, kHeFSDefaultVoluneName);
+ parser.Format(&kMountPoint, kHeFSEncodingFlagsUTF8, kHeFSDefaultVolumeName);
MUST_PASS(parser.CreateINode(&kMountPoint, kHeFSEncodingFlagsBinary | kHeFSFlagsReadOnly,
- u8"/boot", u8".filetest"));
- MUST_PASS(parser.DeleteINode(&kMountPoint, kHeFSEncodingFlagsBinary | kHeFSFlagsReadOnly,
- u8"/boot", u8".filetest"));
- MUST_PASS(parser.CreateINode(&kMountPoint, kHeFSEncodingFlagsBinary | kHeFSFlagsReadOnly,
- u8"/network", u8".filetest"));
- MUST_PASS(parser.DeleteINode(&kMountPoint, kHeFSEncodingFlagsBinary | kHeFSFlagsReadOnly,
- u8"/network", u8".filetest"));
+ u8"/boot", u8"bootinfo.cfg", kHeFSFileKindRegular));
+
+ Utf8Char contents_1[kHeFSBlockLen] = {0};
+
+ urt_set_memory(contents_1, 0, kHeFSBlockLen);
+
+ MUST_PASS(parser.INodeManip(&kMountPoint, contents_1, kHeFSBlockLen, u8"/boot", u8"bootinfo.cfg",
+ kHeFSFileKindRegular, YES));
+
+ if (*contents_1 != u'\0') {
+ (Void)(kout << "/boot/bootinfo.cfg:" << kendl);
+ (Void)(kout8 << contents_1 << kendl8);
+ } else {
+ auto src =
+ u8"[boot]\r"
+ u8"path=bootz.efi\r"
+ u8"name=BootZ\r"
+ u8"[kernel]\r"
+ u8"path=krnl.efi\r"
+ u8"name=NeKernel\r"
+ u8"[chk]\r"
+ u8"path=chk.efi\r"
+ u8"name=SysChk\r";
+
+ urt_copy_memory((VoidPtr) src, contents_1, urt_string_len(src));
+
+ MUST_PASS(parser.INodeManip(&kMountPoint, contents_1, kHeFSBlockLen, u8"/boot",
+ u8"bootinfo.cfg", kHeFSFileKindRegular, NO));
+ }
return YES;
}