From 461fe537aa1f9533bfa5c2504cb84843b9eac501 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Mon, 29 Apr 2024 10:12:36 +0200 Subject: MHR-18: Filesystem fixes and improvements see ticket. - Implement CreateCatalog for file creation, an implementation of RemoveCatalog is also needed. - Boot Kit only takes a single root file now. Must be ending with '/'. Signed-off-by: Amlal El Mahrouss --- Private/Source/AppMain.cxx | 19 +- Private/Source/FS/NewFS.cxx | 400 ++++++++++++++++++++++++++++++----------- Private/Source/FileManager.cxx | 44 ++--- 3 files changed, 334 insertions(+), 129 deletions(-) (limited to 'Private/Source') diff --git a/Private/Source/AppMain.cxx b/Private/Source/AppMain.cxx index 8fa74459..404889d7 100644 --- a/Private/Source/AppMain.cxx +++ b/Private/Source/AppMain.cxx @@ -24,10 +24,21 @@ EXTERN_C NewOS::Void AppMain(NewOS::Void) { NewOS::FilesystemManagerInterface::Mount(newFS); if (newFS->GetImpl()) { - auto catalog = newFS->GetImpl()->GetCatalog("/Boot"); - if (catalog) { - NewOS::kcout << "Catalog-Path-Name: " << catalog->Name << NewOS::endl; - delete catalog; + NewCatalog* mountCatalog = newFS->GetImpl()->GetCatalog("/Boot/"); + + if (mountCatalog) { + delete newFS->GetImpl()->CreateCatalog("/Boot/System/", 0, kNewFSCatalogKindDir); + NewCatalog* newKernelCatalog = newFS->GetImpl()->CreateCatalog("/Boot/System/NewKernel"); + + if (newKernelCatalog) + NewOS::kcout << "Catalog-Path-Name: " << newKernelCatalog->Name << NewOS::endl; + + NewOS::kcout << "Catalog-Path-Name: " << mountCatalog->Name << NewOS::endl; + + delete newKernelCatalog; + delete mountCatalog; + } else { + delete newFS->GetImpl()->CreateCatalog("/Boot/", 0, kNewFSCatalogKindDir); } } diff --git a/Private/Source/FS/NewFS.cxx b/Private/Source/FS/NewFS.cxx index a5dfe45b..a91d440e 100644 --- a/Private/Source/FS/NewFS.cxx +++ b/Private/Source/FS/NewFS.cxx @@ -6,19 +6,20 @@ #ifdef __FSKIT_NEWFS__ +#include +#include #include #include #include -#include #include -#include -#include +#include using namespace NewOS; /// forward decl. -STATIC Lba ke_find_free_fork(SizeT sz, Int32 drv, NewCatalog* catalog, Boolean isDataFork); +STATIC Lba ke_find_free_fork(SizeT sz, Int32 drv, NewCatalog* catalog, + Boolean isDataFork); STATIC Lba ke_find_free_catalog(SizeT kind, Int32 drv); STATIC MountpointInterface sMountpointInterface; @@ -33,34 +34,35 @@ _Output NewFork* NewFSParser::CreateFork(_Input NewCatalog* catalog, Lba whereFork = 0; theFork.DataOffset = - ke_find_free_fork(theFork.DataSize, this->fDriveIndex, catalog, theFork.Kind == kNewFSDataForkKind); + ke_find_free_fork(theFork.DataSize, this->fDriveIndex, catalog, + theFork.Kind == kNewFSDataForkKind); theFork.Flags |= kNewFSFlagCreated; - Lba lba = theFork.Kind == kNewFSDataForkKind ? catalog->DataFork : catalog->ResourceFork; + Lba lba = theFork.Kind == kNewFSDataForkKind ? catalog->DataFork + : catalog->ResourceFork; - if (lba == 0) { + if (lba <= kNewFSAddressAsLba) { lba = whereFork; } else { - if (lba == 0) { + if (lba <= kNewFSAddressAsLba) { theFork.PreviousSibling = lba; } } if (theFork.Kind == kNewFSDataForkKind) { - if (catalog->DataFork == 0) { - catalog->DataFork = whereFork; - } else { - theFork.PreviousSibling = catalog->DataFork; - } + if (catalog->DataFork == 0) { + catalog->DataFork = whereFork; + } else { + theFork.PreviousSibling = catalog->DataFork; + } } else { - if (catalog->ResourceFork == 0) { - catalog->ResourceFork = whereFork; - } else { - theFork.PreviousSibling = catalog->ResourceFork; - } + if (catalog->ResourceFork == 0) { + catalog->ResourceFork = whereFork; + } else { + theFork.PreviousSibling = catalog->ResourceFork; + } } - if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) - return nullptr; + if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) return nullptr; auto drv = sMountpointInterface.GetAddressOf(this->fDriveIndex); @@ -90,7 +92,7 @@ _Output NewFork* NewFSParser::CreateFork(_Input NewCatalog* catalog, } /// Also update catalog. - this->WriteCatalog(catalog, nullptr); + this->WriteCatalog(catalog, nullptr, 0); return &theFork; } @@ -103,7 +105,8 @@ _Output NewFork* NewFSParser::CreateFork(_Input NewCatalog* catalog, /// @param name the fork name. /// @return the fork. _Output NewFork* NewFSParser::FindFork(_Input NewCatalog* catalog, - _Input const Char* name, Boolean isDataFork) { + _Input const Char* name, + Boolean isDataFork) { auto drv = sMountpointInterface.GetAddressOf(this->fDriveIndex); NewFork* theFork = nullptr; Lba lba = isDataFork ? catalog->DataFork : catalog->ResourceFork; @@ -160,6 +163,187 @@ _Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name) { _Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name, _Input const Int32& flags, _Input const Int32& kind) { + if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) return nullptr; + + Lba outLba = 0UL; + + if (kind == kNewFSCatalogKindDir && + name[rt_string_len(name) - 1] != NewFilesystemHelper::Separator()) + return nullptr; + + /// as well as this, we don't want that. + if (kind != kNewFSCatalogKindDir && + name[rt_string_len(name) - 1] == NewFilesystemHelper::Separator()) + return nullptr; + + NewCatalog* checkForCpy = this->FindCatalog(name, outLba); + + if (checkForCpy) { + return checkForCpy; + } + + char copyName[kNewFSNodeNameLen] = {0}; + + for (SizeT indexName = 0UL; indexName < rt_string_len(name); ++indexName) { + copyName[indexName] = name[indexName]; + } + + if (*copyName == 0) { + DbgLastError() = kErrorFileNotFound; + return nullptr; + } + + for (SizeT indexFill = 0; indexFill < rt_string_len(name); + ++indexFill) { + copyName[indexFill] = name[indexFill]; + } + + SizeT indexReverseCopy = rt_string_len(copyName); + + // zero character. + copyName[--indexReverseCopy] = 0; + + // mandatory / character. + copyName[--indexReverseCopy] = 0; + + while (copyName[indexReverseCopy] != '/') { + copyName[indexReverseCopy] = 0; + --indexReverseCopy; + } + + NewCatalog* catalog = this->FindCatalog(copyName, outLba); + + if (!catalog) { + return nullptr; + } + + if (catalog->Kind == kNewFSCatalogKindFile) { + delete catalog; + return nullptr; + } + + constexpr SizeT cDefaultForkSize = 8096; + + NewCatalog* catalogChild = new NewCatalog(); + + catalogChild->DataFork = 0UL; + catalogChild->ResourceFork = 0UL; + + catalogChild->ResourceForkOverallSize = cDefaultForkSize; + catalogChild->DataForkSize = cDefaultForkSize; + + catalogChild->NextSibling = 0UL; + catalogChild->PrevSibling = outLba; + catalogChild->Flags = flags; + catalogChild->Kind = kind; + catalogChild->Flags |= kNewFSFlagCreated; + + rt_copy_memory((VoidPtr)name, (VoidPtr)catalogChild->Name, + rt_string_len(name)); + + UInt16 sectorBuf[kNewFSMinimumSectorSz] = {0}; + + auto drive = sMountpointInterface.GetAddressOf(this->fDriveIndex); + + Lba startFree = catalogChild->PrevSibling + catalog->NextSibling; + + kcout << "Next-Catalog: " << hex_number(startFree) << endl; + + drive->fPacket.fPacketContent = sectorBuf; + drive->fPacket.fPacketSize = kNewFSMinimumSectorSz; + drive->fPacket.fLba = startFree; + + drive->fInput(&drive->fPacket); + + while (drive->fPacket.fPacketGood) { + NewCatalog* nextSibling = (NewCatalog*)sectorBuf; + + if (startFree <= kNewFSAddressAsLba) { + delete catalogChild; + delete catalog; + + return nullptr; + } + + /// allocation or reallocation or catalog... + if (StringBuilder::Equals(nextSibling->Name, name) || + (nextSibling->Name[0] == 0 && + nextSibling->Flags != kNewFSFlagCreated)) { + if ((nextSibling->Flags != kNewFSFlagCreated)) { + nextSibling->Flags = kNewFSFlagCreated; + + drive->fPacket.fPacketContent = catalogChild; + drive->fPacket.fPacketSize = kNewFSMinimumSectorSz; + drive->fPacket.fLba = startFree; + + if (catalogChild->Kind == kNewFSCatalogKindFile) { + rt_copy_memory((VoidPtr) "x-kind/file", (VoidPtr)catalogChild->Mime, + rt_string_len("x-kind/file")); + } else { + rt_copy_memory((VoidPtr) "x-kind/dir", (VoidPtr)catalogChild->Mime, + rt_string_len("x-kind/dir")); + } + + catalogChild->NextSibling = sizeof(NewCatalog) + + catalogChild->DataForkSize + + catalogChild->ResourceForkOverallSize; + + drive->fOutput(&drive->fPacket); + + kcout << "New OS: Create new catalog with success!\r\n"; + + Char sectBuf[sizeof(NewCatalog)] = {0}; + + drive->fPacket.fPacketContent = sectBuf; + drive->fPacket.fPacketSize = sizeof(NewCatalog); + drive->fPacket.fLba = catalogChild->PrevSibling; + + drive->fInput(&drive->fPacket); + + NewCatalog* prevCatalog = (NewCatalog*)sectBuf; + prevCatalog->NextSibling = startFree; + + drive->fOutput(&drive->fPacket); + + kcout << "Edit-Catalog: " << prevCatalog->Name << endl; + + Char sectorBufPartBlock[kNewFSMinimumSectorSz] = {0}; + + drive->fPacket.fPacketContent = sectorBufPartBlock; + drive->fPacket.fPacketSize = kNewFSMinimumSectorSz; + drive->fPacket.fLba = kNewFSAddressAsLba; + + drive->fInput(&drive->fPacket); + + NewPartitionBlock* partBlock = (NewPartitionBlock*)sectorBufPartBlock; + + partBlock->SectorCount -= 1; + partBlock->CatalogCount += 1; + partBlock->FreeCatalog -= 1; + + drive->fOutput(&drive->fPacket); + + delete catalog; + return catalogChild; + } else { + delete catalog; + return nullptr; + } + } + + //// @note that's how we find the next catalog in the partition block. + startFree += sizeof(NewFork) + sizeof(NewCatalog) + + nextSibling->DataForkSize + + nextSibling->ResourceForkOverallSize; + + drive->fPacket.fPacketContent = sectorBuf; + drive->fPacket.fPacketSize = kNewFSMinimumSectorSz; + drive->fPacket.fLba = startFree; + + drive->fInput(&drive->fPacket); + } + + delete catalog; return nullptr; } @@ -176,7 +360,7 @@ bool NewFSParser::Format(_Input _Output DriveTrait* drive) { return false; } - UInt16 sectorBuf[kNewFSMinimumSectorSz] = {0}; + Char sectorBuf[kNewFSMinimumSectorSz] = {0}; drive->fPacket.fPacketContent = sectorBuf; drive->fPacket.fPacketSize = kNewFSMinimumSectorSz; @@ -193,9 +377,12 @@ bool NewFSParser::Format(_Input _Output DriveTrait* drive) { rt_string_cmp(partBlock->Ident, kNewFSIdent, kNewFSIdentLen)) { /// partition is free and valid. + partBlock->Version = kNewFSVersionInteger; + rt_copy_memory((VoidPtr)kNewFSIdent, (VoidPtr)partBlock->Ident, kNewFSIdentLen); - rt_copy_memory((VoidPtr) "Untitled HD\0", (VoidPtr)partBlock->PartitionName, + rt_copy_memory((VoidPtr) "Untitled HD\0", + (VoidPtr)partBlock->PartitionName, rt_string_len("Untitled HD\0")); SizeT catalogCount = 0; @@ -203,7 +390,8 @@ bool NewFSParser::Format(_Input _Output DriveTrait* drive) { SizeT diskSize = drv_std_get_drv_size(); partBlock->Kind = kNewFSPartitionTypeStandard; - partBlock->StartCatalog = kNewFSCatalogStartAddress;; + partBlock->StartCatalog = kNewFSCatalogStartAddress; + ; partBlock->CatalogCount = catalogCount; partBlock->SectorCount = sectorCount; partBlock->DiskSize = diskSize; @@ -227,92 +415,99 @@ bool NewFSParser::Format(_Input _Output DriveTrait* drive) { return false; } -/// @brief -/// @param catalog -/// @param data +/// @brief Writes the data fork into a specific catalog. +/// @param catalog the catalog itself +/// @param data the data. /// @return -bool NewFSParser::WriteCatalog(_Input _Output NewCatalog* catalog, - voidPtr data) { +bool NewFSParser::WriteCatalog(_Input _Output NewCatalog* catalog, voidPtr data, + SizeT sizeOfData) { return false; } /// @brief /// @param catalogName /// @return -_Output NewCatalog* NewFSParser::FindCatalog(_Input const char* catalogName) { - if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) return nullptr; +_Output NewCatalog* NewFSParser::FindCatalog(_Input const char* catalogName, + Lba& outLba) { + if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) return nullptr; - Char* sectorBuf = new Char[sizeof(NewPartitionBlock)]; - auto drive = sMountpointInterface.GetAddressOf(this->fDriveIndex); + Char* sectorBuf = new Char[sizeof(NewPartitionBlock)]; + auto drive = sMountpointInterface.GetAddressOf(this->fDriveIndex); - drive->fPacket.fPacketContent = sectorBuf; - drive->fPacket.fPacketSize = sizeof(NewPartitionBlock); - drive->fPacket.fLba = kNewFSAddressAsLba; + drive->fPacket.fPacketContent = sectorBuf; + drive->fPacket.fPacketSize = sizeof(NewPartitionBlock); + drive->fPacket.fLba = kNewFSAddressAsLba; - drive->fInput(&drive->fPacket); + drive->fInput(&drive->fPacket); - NewPartitionBlock* part = (NewPartitionBlock*)sectorBuf; + NewPartitionBlock* part = (NewPartitionBlock*)sectorBuf; - kcout << "Drive-Kind: " << drive->fDriveKind() << endl; + kcout << "Drive-Kind: " << drive->fDriveKind() << endl; - kcout << "Partition-Name: " << part->PartitionName << endl; - kcout << "Start-Catalog: " << number(part->StartCatalog) << endl; - kcout << "Catalog-Count: " << number(part->CatalogCount) << endl; - kcout << "Free-Catalog: " << number(part->FreeCatalog) << endl; - kcout << "Free-Sectors: " << number(part->FreeSectors) << endl; - kcout << "Sector-Size: " << number(part->SectorSize) << endl; + kcout << "Partition-Name: " << part->PartitionName << endl; + kcout << "Start-Catalog: " << number(part->StartCatalog) << endl; + kcout << "Catalog-Count: " << number(part->CatalogCount) << endl; + kcout << "Free-Catalog: " << number(part->FreeCatalog) << endl; + kcout << "Free-Sectors: " << number(part->FreeSectors) << endl; + kcout << "Sector-Size: " << number(part->SectorSize) << endl; - auto start = part->StartCatalog; + auto start = part->StartCatalog; - drive->fPacket.fLba = start; - drive->fPacket.fPacketContent = sectorBuf; - drive->fPacket.fPacketSize = sizeof(NewCatalog); + drive->fPacket.fLba = start; + drive->fPacket.fPacketContent = sectorBuf; + drive->fPacket.fPacketSize = sizeof(NewCatalog); - drive->fInput(&drive->fPacket); + drive->fInput(&drive->fPacket); - while (drive->fPacket.fPacketGood) { - NewCatalog* catalog = (NewCatalog*)sectorBuf; + while (drive->fPacket.fPacketGood) { + NewCatalog* catalog = (NewCatalog*)sectorBuf; - if (StringBuilder::Equals(catalogName, catalog->Name)) { - NewCatalog* catalogPtr = new NewCatalog(); - rt_copy_memory(catalog, catalogPtr, sizeof(NewCatalog)); + if (StringBuilder::Equals(catalogName, catalog->Name)) { + NewCatalog* catalogPtr = new NewCatalog(); + rt_copy_memory(catalog, catalogPtr, sizeof(NewCatalog)); - delete[] sectorBuf; - return catalogPtr; - } + outLba = start; + delete[] sectorBuf; + return catalogPtr; + } - if (catalog->NextSibling == 0) - break; + start = catalog->NextSibling; - drive->fPacket.fLba = catalog->NextSibling; - drive->fPacket.fPacketSize = kNewFSMinimumSectorSz; - drive->fInput(&drive->fPacket); - } + if (start <= kNewFSAddressAsLba) break; + + drive->fPacket.fLba = start; + drive->fPacket.fPacketContent = sectorBuf; + drive->fPacket.fPacketSize = sizeof(NewCatalog); - delete[] sectorBuf; + drive->fInput(&drive->fPacket); + } - return nullptr; + outLba = 0UL; + delete[] sectorBuf; + + return nullptr; } /// @brief /// @param name /// @return _Output NewCatalog* NewFSParser::GetCatalog(_Input const char* name) { - return this->FindCatalog(name); + Lba unused = 0; + return this->FindCatalog(name, unused); } /// @brief /// @param catalog /// @return Boolean NewFSParser::CloseCatalog(_Input _Output NewCatalog* catalog) { - if (this->WriteCatalog(catalog, nullptr)) { - delete catalog; - catalog = nullptr; + if (this->WriteCatalog(catalog, nullptr, 0)) { + delete catalog; + catalog = nullptr; - return true; - } + return true; + } - return false; + return false; } /// @brief Mark catalog as removed. @@ -320,12 +515,12 @@ Boolean NewFSParser::CloseCatalog(_Input _Output NewCatalog* catalog) { /// @return Boolean NewFSParser::RemoveCatalog(_Input _Output NewCatalog* catalog) { if (!catalog) { - DbgLastError() = kErrorFileNotFound; - return false; + DbgLastError() = kErrorFileNotFound; + return false; } catalog->Flags |= kNewFSFlagDeleted; - this->WriteCatalog(catalog, nullptr); + this->WriteCatalog(catalog, nullptr, 0); return false; } @@ -340,12 +535,12 @@ Boolean NewFSParser::RemoveCatalog(_Input _Output NewCatalog* catalog) { /// @return VoidPtr NewFSParser::ReadCatalog(_Input _Output NewCatalog* catalog, SizeT dataSz) { - if (!catalog) { - DbgLastError() = kErrorFileNotFound; - return nullptr; - } - + if (!catalog) { + DbgLastError() = kErrorFileNotFound; return nullptr; + } + + return nullptr; } /// @brief Seek in the data fork. @@ -353,31 +548,31 @@ VoidPtr NewFSParser::ReadCatalog(_Input _Output NewCatalog* catalog, /// @param off /// @return bool NewFSParser::Seek(_Input _Output NewCatalog* catalog, SizeT off) { - if (!catalog) { - DbgLastError() = kErrorFileNotFound; - return false; - } - + if (!catalog) { + DbgLastError() = kErrorFileNotFound; return false; + } + + return false; } /// @brief Tell where we are inside the data fork. /// @param catalog /// @return SizeT NewFSParser::Tell(_Input _Output NewCatalog* catalog) { - if (!catalog) { - DbgLastError() = kErrorFileNotFound; - return false; - } + if (!catalog) { + DbgLastError() = kErrorFileNotFound; + return false; + } - return 0; + return 0; } /// @brief Find a free fork inside the filesystem. /// @param sz the size of the fork to set. /// @return the valid lba. -STATIC Lba ke_find_free_fork(SizeT sz, Int32 drv, NewCatalog* catalog, Boolean isDataFork) { - +STATIC Lba ke_find_free_fork(SizeT sz, Int32 drv, NewCatalog* catalog, + Boolean isDataFork) { if (sMountpointInterface.GetAddressOf(drv)) { auto drive = *sMountpointInterface.GetAddressOf(drv); @@ -413,7 +608,7 @@ STATIC Lba ke_find_free_fork(SizeT sz, Int32 drv, NewCatalog* catalog, Boolean i (fork->Flags == kNewFSFlagDeleted || fork->Flags == kNewFSFlagUnallocated)) { fork->DataSize = sz; - fork->Flags |= kNewFSFlagCreated; + fork->Flags = kNewFSFlagCreated; drive.fOutput(&drive.fPacket); @@ -443,7 +638,6 @@ STATIC Lba ke_find_free_fork(SizeT sz, Int32 drv, NewCatalog* catalog, Boolean i /// @param kind the catalog kind. /// @return the valid lba. STATIC Lba ke_find_free_catalog(SizeT kind, Int32 drv) { - if (sMountpointInterface.GetAddressOf(drv)) { auto drive = *sMountpointInterface.GetAddressOf(drv); UInt16 sectorBuf[kNewFSMinimumSectorSz] = {0}; @@ -478,7 +672,7 @@ STATIC Lba ke_find_free_catalog(SizeT kind, Int32 drv) { if (catalog->Flags == kNewFSFlagUnallocated || catalog->Flags == kNewFSFlagDeleted) { - catalog->Flags |= kNewFSFlagCreated; + catalog->Flags = kNewFSFlagCreated; catalog->Kind |= kind; return startLba; @@ -497,14 +691,14 @@ STATIC Lba ke_find_free_catalog(SizeT kind, Int32 drv) { namespace NewOS::Detail { Boolean fs_init_newfs(Void) noexcept { - sMountpointInterface.A() = construct_main_drive(); - sMountpointInterface.B() = construct_drive(); - sMountpointInterface.C() = construct_drive(); - sMountpointInterface.D() = construct_drive(); + sMountpointInterface.A() = construct_main_drive(); + sMountpointInterface.B() = construct_drive(); + sMountpointInterface.C() = construct_drive(); + sMountpointInterface.D() = construct_drive(); - sMountpointInterface.A().fVerify(&sMountpointInterface.A().fPacket); + sMountpointInterface.A().fVerify(&sMountpointInterface.A().fPacket); - return true; + return true; } } // namespace NewOS::Detail diff --git a/Private/Source/FileManager.cxx b/Private/Source/FileManager.cxx index 4742769c..aab3cff0 100644 --- a/Private/Source/FileManager.cxx +++ b/Private/Source/FileManager.cxx @@ -47,9 +47,9 @@ bool FilesystemManagerInterface::Mount(FilesystemManagerInterface* mountPtr) { #ifdef __FSKIT_NEWFS__ /// @brief Opens a new file. -/// @param path -/// @param r -/// @return +/// @param path +/// @param r +/// @return NodePtr NewFilesystemManager::Open(const char* path, const char* r) { if (!path || *path == 0) return nullptr; @@ -66,14 +66,14 @@ NodePtr NewFilesystemManager::Open(const char* path, const char* r) { } /// @brief Writes to a catalog -/// @param node -/// @param data -/// @param flags -/// @return +/// @param node +/// @param data +/// @param flags +/// @return Void NewFilesystemManager::Write(NodePtr node, VoidPtr data, - Int32 flags) { + Int32 flags, SizeT size) { if ((reinterpret_cast(node))->Kind == kNewFSCatalogKindFile) - fImpl->WriteCatalog(reinterpret_cast(node), data); + fImpl->WriteCatalog(reinterpret_cast(node), data, size); } /** @@ -82,10 +82,10 @@ Void NewFilesystemManager::Write(NodePtr node, VoidPtr data, */ /// @brief Reads from filesystem. -/// @param node -/// @param flags -/// @param sz -/// @return +/// @param node +/// @param flags +/// @param sz +/// @return VoidPtr NewFilesystemManager::Read(NodePtr node, Int32 flags, SizeT sz) { if ((reinterpret_cast(node))->Kind == kNewFSCatalogKindFile) return fImpl->ReadCatalog(reinterpret_cast(node), sz); @@ -94,18 +94,18 @@ VoidPtr NewFilesystemManager::Read(NodePtr node, Int32 flags, SizeT sz) { } /// @brief Seek from Catalog. -/// @param node -/// @param off -/// @return +/// @param node +/// @param off +/// @return bool NewFilesystemManager::Seek(NodePtr node, SizeT off) { if (!node || off == 0) return false; - + return fImpl->Seek(reinterpret_cast(node), off); } /// @brief Tell where the catalog is/ -/// @param node -/// @return +/// @param node +/// @return SizeT NewFilesystemManager::Tell(NodePtr node) { if (!node) return kNPos; @@ -113,8 +113,8 @@ SizeT NewFilesystemManager::Tell(NodePtr node) { } /// @brief Rewind the catalog. -/// @param node -/// @return +/// @param node +/// @return bool NewFilesystemManager::Rewind(NodePtr node) { if (!node) return false; @@ -122,7 +122,7 @@ bool NewFilesystemManager::Rewind(NodePtr node) { } /// @brief The filesystem implementation. -/// @return +/// @return NewFSParser* NewFilesystemManager::GetImpl() noexcept { return fImpl; } #endif // __FSKIT_NEWFS__ } // namespace NewOS -- cgit v1.2.3 From a21859d722597e4eb1216a4a48d08d8f2659b514 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Mon, 29 Apr 2024 16:59:14 +0200 Subject: MHR-18: Fixes and improvements regarding NewFS. Signed-off-by: Amlal El Mahrouss --- Private/KernelKit/PEF.hpp | 3 + Private/NewBoot/BootKit/BootKit.hxx | 8 +- Private/NewBoot/Source/makefile | 2 +- Private/Source/AppMain.cxx | 55 +++++-- Private/Source/FS/NewFS.cxx | 293 +++++++++++------------------------- 5 files changed, 141 insertions(+), 220 deletions(-) (limited to 'Private/Source') diff --git a/Private/KernelKit/PEF.hpp b/Private/KernelKit/PEF.hpp index 9fabb189..fe7430ab 100644 --- a/Private/KernelKit/PEF.hpp +++ b/Private/KernelKit/PEF.hpp @@ -103,4 +103,7 @@ enum { #define kPefStart "__ImageStart" +#define kPefForkKind "PEF!" +#define kPefForkKindFAT "FEP!" + #endif /* ifndef __PEF__ */ diff --git a/Private/NewBoot/BootKit/BootKit.hxx b/Private/NewBoot/BootKit/BootKit.hxx index 47a8c9a2..ca6f56ac 100644 --- a/Private/NewBoot/BootKit/BootKit.hxx +++ b/Private/NewBoot/BootKit/BootKit.hxx @@ -246,7 +246,7 @@ private: /// @param fileBlobs the blobs. /// @param blobCount the number of blobs to write. /// @param partBlock the NewFS partition block. - Boolean FormatCatalog(BFileDescriptor* fileBlobs, SizeT blobCount, + Boolean WriteRootCatalog(BFileDescriptor* fileBlobs, SizeT blobCount, NewPartitionBlock& partBlock) { if (partBlock.SectorSize != BootDev::kSectorSize) return false; @@ -381,13 +381,15 @@ inline Boolean BDiskFormatFactory::Format(const char* partName, partBlock->CatalogCount = blobCount; partBlock->Kind = kNewFSHardDrive; partBlock->SectorSize = sectorSz; - partBlock->FreeCatalog = fDiskDev.GetSectorsCount(); + partBlock->FreeCatalog = fDiskDev.GetSectorsCount() / sizeof(NewCatalog); partBlock->SectorCount = fDiskDev.GetSectorsCount(); partBlock->FreeSectors = fDiskDev.GetSectorsCount(); partBlock->StartCatalog = kNewFSCatalogStartAddress; partBlock->DiskSize = fDiskDev.GetDiskSize(); + partBlock->Flags |= kNewFSPartitionTypeBoot; - if (this->FormatCatalog(fileBlobs, blobCount, *partBlock)) { + /// if we can write a root catalog, then write the partition block. + if (this->WriteRootCatalog(fileBlobs, blobCount, *partBlock)) { fDiskDev.Leak().mBase = kNewFSAddressAsLba; fDiskDev.Leak().mSize = sectorSz; diff --git a/Private/NewBoot/Source/makefile b/Private/NewBoot/Source/makefile index 9f70d903..9018623f 100644 --- a/Private/NewBoot/Source/makefile +++ b/Private/NewBoot/Source/makefile @@ -75,7 +75,7 @@ run-efi-amd64: .PHONY: epm-img epm-img: - qemu-img create -f raw $(IMG) 512M + qemu-img create -f raw $(IMG) 1G qemu-img create -f raw $(IMG_2) 512M .PHONY: download-edk diff --git a/Private/Source/AppMain.cxx b/Private/Source/AppMain.cxx index 404889d7..6a23e20d 100644 --- a/Private/Source/AppMain.cxx +++ b/Private/Source/AppMain.cxx @@ -10,10 +10,12 @@ #include #include #include +#include #include #include #include #include +#include /// @file Main microkernel entrypoint. @@ -24,25 +26,52 @@ EXTERN_C NewOS::Void AppMain(NewOS::Void) { NewOS::FilesystemManagerInterface::Mount(newFS); if (newFS->GetImpl()) { - NewCatalog* mountCatalog = newFS->GetImpl()->GetCatalog("/Boot/"); + NewCatalog* mountCatalog = newFS->GetImpl()->GetCatalog("/Boot/"); - if (mountCatalog) { - delete newFS->GetImpl()->CreateCatalog("/Boot/System/", 0, kNewFSCatalogKindDir); - NewCatalog* newKernelCatalog = newFS->GetImpl()->CreateCatalog("/Boot/System/NewKernel"); + if (mountCatalog) { + delete newFS->GetImpl()->CreateCatalog("/Boot/System/", 0, + kNewFSCatalogKindDir); + NewCatalog* newKernelCatalog = + newFS->GetImpl()->CreateCatalog("/Boot/System/ExampleTextFile"); - if (newKernelCatalog) - NewOS::kcout << "Catalog-Path-Name: " << newKernelCatalog->Name << NewOS::endl; + if (newKernelCatalog) + NewOS::kcout << "Catalog-Path-Name: " << newKernelCatalog->Name + << NewOS::endl; - NewOS::kcout << "Catalog-Path-Name: " << mountCatalog->Name << NewOS::endl; + NewOS::kcout << "Catalog-Path-Name: " << mountCatalog->Name + << NewOS::endl; - delete newKernelCatalog; - delete mountCatalog; - } else { - delete newFS->GetImpl()->CreateCatalog("/Boot/", 0, kNewFSCatalogKindDir); - } + constexpr auto cDataSz = 512; + NewOS::Char theData[cDataSz] = { + "THIS FORK\rCONTAINS DATA\rAS\rYOU\rCAN\rSEE...THIS FORK\rCONTAINS " + "DATA\rAS\rYOU\rCAN\rSEE..THIS FORK\rCONTAINS " + "DATA\rAS\rYOU\rCAN\rSEE..THIS FORK\rCONTAINS " + "DATA\rAS\rYOU\rCAN\rSEE..THIS FORK\rCONTAINS " + "DATA\rAS\rYOU\rCAN\rSEE..THIS FORK\rCONTAINS " + "DATA\rAS\rYOU\rCAN\rSEE..THIS FORK\rCONTAINS " + "DATA\rAS\rYOU\rCAN\rSEE..THIS FORK\rCONTAINS " + "DATA\rAS\rYOU\rCAN\rSEE.."}; + + NewFork theFork{0}; + NewOS::rt_copy_memory((NewOS::VoidPtr) "EditableText", + (NewOS::VoidPtr)theFork.Name, + NewOS::rt_string_len("EditableText")); + + theFork.Kind = NewOS::kNewFSDataForkKind; + theFork.DataSize = cDataSz; + + newFS->GetImpl()->CreateFork(newKernelCatalog, theFork); + newFS->GetImpl()->WriteCatalog(newKernelCatalog, theData, cDataSz); + + delete newKernelCatalog; + delete mountCatalog; + } else { + delete newFS->GetImpl()->CreateCatalog("/Boot/", 0, kNewFSCatalogKindDir); + } } - while (NewOS::ProcessScheduler::Shared().Leak().Run() > 0); + while (NewOS::ProcessScheduler::Shared().Leak().Run() > 0) + ; delete newFS; } diff --git a/Private/Source/FS/NewFS.cxx b/Private/Source/FS/NewFS.cxx index a91d440e..57f61cd2 100644 --- a/Private/Source/FS/NewFS.cxx +++ b/Private/Source/FS/NewFS.cxx @@ -16,12 +16,6 @@ using namespace NewOS; -/// forward decl. - -STATIC Lba ke_find_free_fork(SizeT sz, Int32 drv, NewCatalog* catalog, - Boolean isDataFork); -STATIC Lba ke_find_free_catalog(SizeT kind, Int32 drv); - STATIC MountpointInterface sMountpointInterface; /// @brief Creates a new fork inside the New filesystem partition. @@ -31,68 +25,39 @@ STATIC MountpointInterface sMountpointInterface; _Output NewFork* NewFSParser::CreateFork(_Input NewCatalog* catalog, _Input NewFork& theFork) { if (catalog && theFork.Name[0] != 0 && theFork.DataSize > 0) { - Lba whereFork = 0; - - theFork.DataOffset = - ke_find_free_fork(theFork.DataSize, this->fDriveIndex, catalog, - theFork.Kind == kNewFSDataForkKind); - theFork.Flags |= kNewFSFlagCreated; - Lba lba = theFork.Kind == kNewFSDataForkKind ? catalog->DataFork - : catalog->ResourceFork; - - if (lba <= kNewFSAddressAsLba) { - lba = whereFork; - } else { - if (lba <= kNewFSAddressAsLba) { - theFork.PreviousSibling = lba; - } - } + theFork.Flags = kNewFSFlagCreated; + Lba lba = (theFork.Kind == kNewFSDataForkKind) ? catalog->DataFork + : catalog->ResourceFork; - if (theFork.Kind == kNewFSDataForkKind) { - if (catalog->DataFork == 0) { - catalog->DataFork = whereFork; - } else { - theFork.PreviousSibling = catalog->DataFork; - } - } else { - if (catalog->ResourceFork == 0) { - catalog->ResourceFork = whereFork; - } else { - theFork.PreviousSibling = catalog->ResourceFork; - } - } + if (lba <= kNewFSCatalogStartAddress) return nullptr; + + theFork.DataOffset = lba + sizeof(NewFork); if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) return nullptr; auto drv = sMountpointInterface.GetAddressOf(this->fDriveIndex); - drv->fPacket.fLba = whereFork; - drv->fPacket.fPacketSize = theFork.DataSize; - drv->fPacket.fPacketContent = (VoidPtr)&theFork; + Char cpyFork[sizeof(NewFork)] = {0}; - rt_copy_memory((VoidPtr) "fs/newfs-packet", drv->fPacket.fPacketMime, 16); + drv->fPacket.fLba = lba + sizeof(NewCatalog); + drv->fPacket.fPacketSize = sizeof(NewFork); + drv->fPacket.fPacketContent = (VoidPtr)cpyFork; - if (auto res = - fs_newfs_write(&sMountpointInterface, *drv, this->fDriveIndex); - res) { - switch (res) { - case 1: - DbgLastError() = kErrorDiskReadOnly; - break; - case 2: - DbgLastError() = kErrorDiskIsFull; - break; - DbgLastError() = kErrorNoSuchDisk; - break; + drv->fInput(&drv->fPacket); - default: - break; - } - return nullptr; - } + NewFork* cpyForkStruct = (NewFork*)cpyFork; - /// Also update catalog. - this->WriteCatalog(catalog, nullptr, 0); + if (cpyForkStruct->Flags == kNewFSFlagCreated) return nullptr; + + /// special treatment. + rt_copy_memory((VoidPtr) "fs/newfs-packet", drv->fPacket.fPacketMime, + rt_string_len("fs/newfs-packet")); + + drv->fPacket.fLba = lba; + drv->fPacket.fPacketSize = sizeof(NewFork); + drv->fPacket.fPacketContent = (VoidPtr)&theFork; + + drv->fOutput(&drv->fPacket); return &theFork; } @@ -171,7 +136,7 @@ _Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name, name[rt_string_len(name) - 1] != NewFilesystemHelper::Separator()) return nullptr; - /// as well as this, we don't want that. + /// as well as this, we don't want that. if (kind != kNewFSCatalogKindDir && name[rt_string_len(name) - 1] == NewFilesystemHelper::Separator()) return nullptr; @@ -193,8 +158,7 @@ _Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name, return nullptr; } - for (SizeT indexFill = 0; indexFill < rt_string_len(name); - ++indexFill) { + for (SizeT indexFill = 0; indexFill < rt_string_len(name); ++indexFill) { copyName[indexFill] = name[indexFill]; } @@ -207,14 +171,14 @@ _Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name, copyName[--indexReverseCopy] = 0; while (copyName[indexReverseCopy] != '/') { - copyName[indexReverseCopy] = 0; - --indexReverseCopy; + copyName[indexReverseCopy] = 0; + --indexReverseCopy; } NewCatalog* catalog = this->FindCatalog(copyName, outLba); if (!catalog) { - return nullptr; + return nullptr; } if (catalog->Kind == kNewFSCatalogKindFile) { @@ -222,13 +186,10 @@ _Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name, return nullptr; } - constexpr SizeT cDefaultForkSize = 8096; + constexpr SizeT cDefaultForkSize = 8192; NewCatalog* catalogChild = new NewCatalog(); - catalogChild->DataFork = 0UL; - catalogChild->ResourceFork = 0UL; - catalogChild->ResourceForkOverallSize = cDefaultForkSize; catalogChild->DataForkSize = cDefaultForkSize; @@ -259,21 +220,24 @@ _Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name, NewCatalog* nextSibling = (NewCatalog*)sectorBuf; if (startFree <= kNewFSAddressAsLba) { - delete catalogChild; - delete catalog; + delete catalogChild; + delete catalog; - return nullptr; + return nullptr; } /// allocation or reallocation or catalog... - if (StringBuilder::Equals(nextSibling->Name, name) || - (nextSibling->Name[0] == 0 && + if ((nextSibling->Name[0] == 0 && nextSibling->Flags != kNewFSFlagCreated)) { + catalogChild->DataFork = startFree + sizeof(NewCatalog); + catalogChild->ResourceFork = + startFree + sizeof(NewCatalog) + catalogChild->DataForkSize; + if ((nextSibling->Flags != kNewFSFlagCreated)) { nextSibling->Flags = kNewFSFlagCreated; drive->fPacket.fPacketContent = catalogChild; - drive->fPacket.fPacketSize = kNewFSMinimumSectorSz; + drive->fPacket.fPacketSize = sizeof(NewCatalog); drive->fPacket.fLba = startFree; if (catalogChild->Kind == kNewFSCatalogKindFile) { @@ -290,7 +254,7 @@ _Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name, drive->fOutput(&drive->fPacket); - kcout << "New OS: Create new catalog with success!\r\n"; + kcout << "New OS: Create new catalog successfully!\r\n"; Char sectBuf[sizeof(NewCatalog)] = {0}; @@ -379,11 +343,13 @@ bool NewFSParser::Format(_Input _Output DriveTrait* drive) { partBlock->Version = kNewFSVersionInteger; + const auto cUntitledHD = "New OS HD\0"; + rt_copy_memory((VoidPtr)kNewFSIdent, (VoidPtr)partBlock->Ident, kNewFSIdentLen); - rt_copy_memory((VoidPtr) "Untitled HD\0", - (VoidPtr)partBlock->PartitionName, - rt_string_len("Untitled HD\0")); + + rt_copy_memory((VoidPtr)cUntitledHD, (VoidPtr)partBlock->PartitionName, + rt_string_len(cUntitledHD)); SizeT catalogCount = 0; SizeT sectorCount = drv_std_get_sector_count(); @@ -391,8 +357,8 @@ bool NewFSParser::Format(_Input _Output DriveTrait* drive) { partBlock->Kind = kNewFSPartitionTypeStandard; partBlock->StartCatalog = kNewFSCatalogStartAddress; - ; - partBlock->CatalogCount = catalogCount; + partBlock->Flags |= kNewFSPartitionTypeStandard; + partBlock->CatalogCount = sectorCount / sizeof(NewCatalog); partBlock->SectorCount = sectorCount; partBlock->DiskSize = diskSize; partBlock->FreeCatalog = partBlock->StartCatalog; @@ -406,7 +372,7 @@ bool NewFSParser::Format(_Input _Output DriveTrait* drive) { return true; } - kcout << "New OS: Partition already exists.\r\n"; + kcout << "New OS: PartitionBlock already exists.\r\n"; /// return success as well, do not ignore that partition. return true; @@ -418,9 +384,51 @@ bool NewFSParser::Format(_Input _Output DriveTrait* drive) { /// @brief Writes the data fork into a specific catalog. /// @param catalog the catalog itself /// @param data the data. -/// @return +/// @return if the catalog w rote the contents successfully. bool NewFSParser::WriteCatalog(_Input _Output NewCatalog* catalog, voidPtr data, SizeT sizeOfData) { + if (sizeOfData > catalog->DataForkSize) return false; + if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) return false; + + NewFork* forkData = new NewFork(); + + auto drive = sMountpointInterface.GetAddressOf(this->fDriveIndex); + + auto startFork = catalog->DataFork; + + /// sanity check of the fork position as the condition to run the loop. + if (startFork >= kNewFSCatalogStartAddress) { + drive->fPacket.fPacketContent = forkData; + drive->fPacket.fPacketSize = sizeof(NewFork); + drive->fPacket.fLba = startFork; + + drive->fInput(&drive->fPacket); + + /// check if fork even exists. + if (forkData->Flags != kNewFSFlagCreated) { + DbgLastError() = kErrorDiskIsCorrupted; + + delete forkData; + return false; + } + + /// sanity check the fork. + if (forkData->DataOffset <= kNewFSCatalogStartAddress) { + DbgLastError() = kErrorDiskIsCorrupted; + + delete forkData; + return false; + } + + drive->fPacket.fPacketContent = data; + drive->fPacket.fPacketSize = sizeOfData; + drive->fPacket.fLba = forkData->DataOffset; + + drive->fOutput(&drive->fPacket); + + return true; + } + return false; } @@ -568,127 +576,6 @@ SizeT NewFSParser::Tell(_Input _Output NewCatalog* catalog) { return 0; } -/// @brief Find a free fork inside the filesystem. -/// @param sz the size of the fork to set. -/// @return the valid lba. -STATIC Lba ke_find_free_fork(SizeT sz, Int32 drv, NewCatalog* catalog, - Boolean isDataFork) { - if (sMountpointInterface.GetAddressOf(drv)) { - auto drive = *sMountpointInterface.GetAddressOf(drv); - - /// prepare packet. - bool done = false; - bool error = false; - - Lba lba = isDataFork ? catalog->DataFork : catalog->ResourceFork; - - while (!done) { - UInt16 sectorBuf[kNewFSMinimumSectorSz] = {0}; - - drive.fPacket.fPacketContent = sectorBuf; - drive.fPacket.fPacketSize = kNewFSMinimumSectorSz; - drive.fPacket.fLba = lba; - - drive.fInput(&drive.fPacket); - - if (!drive.fPacket.fPacketGood) { - ///! not a lot of choices, disk has become unreliable. - if (ke_calculate_crc32((Char*)sectorBuf, kNewFSMinimumSectorSz) != - drive.fPacket.fPacketCRC32) { - DbgLastError() = kErrorDiskIsCorrupted; - } - - error = true; - break; - } - - NewFork* fork = (NewFork*)sectorBuf; - - if (fork->DataSize == 0 && fork->Name[0] == 0 && - (fork->Flags == kNewFSFlagDeleted || - fork->Flags == kNewFSFlagUnallocated)) { - fork->DataSize = sz; - fork->Flags = kNewFSFlagCreated; - - drive.fOutput(&drive.fPacket); - - /// here it's either a read-only filesystem or something bad happened.' - if (!drive.fPacket.fPacketGood) { - DbgLastError() = kErrorDiskReadOnly; - - return 0; - } - - return lba; - } - - lba += sizeof(NewFork); - } - - if (error) { - DbgLastError() = kErrorDisk; - return 0; - } - } - - return 0; -} - -/// @brief find a free catalog. -/// @param kind the catalog kind. -/// @return the valid lba. -STATIC Lba ke_find_free_catalog(SizeT kind, Int32 drv) { - if (sMountpointInterface.GetAddressOf(drv)) { - auto drive = *sMountpointInterface.GetAddressOf(drv); - UInt16 sectorBuf[kNewFSMinimumSectorSz] = {0}; - - /// prepare packet. - - drive.fPacket.fPacketContent = sectorBuf; - drive.fPacket.fPacketSize = kNewFSMinimumSectorSz; - drive.fPacket.fLba = kNewFSAddressAsLba; - - drive.fInput(&drive.fPacket); - - NewPartitionBlock* partBlock = (NewPartitionBlock*)sectorBuf; - - /// check for a valid partition. - if (partBlock->PartitionName[0] != 0 && - rt_string_cmp(partBlock->Ident, kNewFSIdent, kNewFSIdentLen) == 0) { - auto startLba = partBlock->FreeCatalog; - - if (startLba == 0) { - DbgLastError() = kErrorDiskIsFull; - return 1; - } else { - while (startLba != 0) { - drive.fPacket.fPacketContent = sectorBuf; - drive.fPacket.fPacketSize = kNewFSMinimumSectorSz; - drive.fPacket.fLba = startLba; - - drive.fInput(&drive.fPacket); - - NewCatalog* catalog = (NewCatalog*)sectorBuf; - - if (catalog->Flags == kNewFSFlagUnallocated || - catalog->Flags == kNewFSFlagDeleted) { - catalog->Flags = kNewFSFlagCreated; - catalog->Kind |= kind; - - return startLba; - } - - startLba = catalog->NextSibling; - } - - return 0; - } - } - } - - return 0; -} - namespace NewOS::Detail { Boolean fs_init_newfs(Void) noexcept { sMountpointInterface.A() = construct_main_drive(); -- cgit v1.2.3