diff options
Diffstat (limited to 'Private/Source/FS')
| -rw-r--r-- | Private/Source/FS/NewFS.cxx | 251 |
1 files changed, 208 insertions, 43 deletions
diff --git a/Private/Source/FS/NewFS.cxx b/Private/Source/FS/NewFS.cxx index 1d7d3621..7eb79d10 100644 --- a/Private/Source/FS/NewFS.cxx +++ b/Private/Source/FS/NewFS.cxx @@ -7,13 +7,16 @@ #ifdef __FSKIT_NEWFS__ #include <FSKit/NewFS.hxx> +#include <KernelKit/HError.hpp> +#include <NewKit/Crc32.hpp> #include <NewKit/Utils.hpp> using namespace NewOS; -STATIC Lba ke_find_free_fork(SizeT sz); -STATIC Lba ke_find_free_catalog(SizeT sz); -STATIC Lba ke_find_free_data(SizeT sz); +/// forward decl. + +STATIC Lba ke_find_free_fork(SizeT sz, Int32 drv, NewCatalog* catalog); +STATIC Lba ke_find_free_catalog(SizeT kind, Int32 drv); STATIC MountpointInterface sMountpointInterface; @@ -26,7 +29,8 @@ _Output NewFork* NewFSParser::CreateFork(_Input NewCatalog* catalog, if (catalog && theFork.Name[0] != 0 && theFork.DataSize > 0) { Lba whereFork = 0; - theFork.DataOffset = ke_find_free_fork(theFork.DataSize); + theFork.DataOffset = + ke_find_free_fork(theFork.DataSize, this->fDriveIndex, catalog); theFork.Flags |= kNewFSFlagCreated; if (catalog->FirstFork == 0) { @@ -161,7 +165,55 @@ bool NewFSParser::Format(_Input _Output DriveTrait* drive) { return false; } - return true; + Char sectorBuf[kNewFSMinimumSectorSz] = {0}; + + drive->fPacket.fPacketContent = sectorBuf; + drive->fPacket.fPacketSize = kNewFSMinimumSectorSz; + drive->fPacket.fLba = kNewFSAddressAsLba; + + drive->fInput(&drive->fPacket); + + /// disk isnt faulty and data has been fetched. + if (drive->fPacket.fPacketGood) { + NewPartitionBlock* partBlock = (NewPartitionBlock*)sectorBuf; + + /// check for an empty partition here. + if (partBlock->PartitionName[0] == 0 && + rt_string_cmp(partBlock->Ident, kNewFSIdent, kNewFSIdentLen)) { + /// partition is free and valid. + + rt_copy_memory((VoidPtr)kNewFSIdent, (VoidPtr)partBlock->Ident, + kNewFSIdentLen); + rt_copy_memory((VoidPtr) "New OS\0", (VoidPtr)partBlock->PartitionName, + rt_string_len("New OS\0")); + + SizeT catalogCount = 0; + SizeT sectorCount = 0; + SizeT diskSize = 0; + + partBlock->Kind = kNewFSPartitionTypeStandard; + partBlock->StartCatalog = sizeof(NewPartitionBlock) + kNewFSAddressAsLba; + partBlock->CatalogCount = catalogCount; + partBlock->SectorCount = sectorCount; + partBlock->DiskSize = diskSize; + partBlock->FreeCatalog = partBlock->StartCatalog; + + drive->fPacket.fPacketContent = sectorBuf; + drive->fPacket.fPacketSize = kNewFSMinimumSectorSz; + drive->fPacket.fLba = kNewFSAddressAsLba; + + drive->fOutput(&drive->fPacket); + + return true; + } + + kcout << "New OS: Partition already exists.\r\n"; + + /// return success as well, do not ignore that partition. + return true; + } + + return false; } /// @brief @@ -173,73 +225,186 @@ bool NewFSParser::WriteCatalog(_Input _Output NewCatalog* catalog, return false; } -/// @brief -/// @param catalogName -/// @return +/// @brief +/// @param catalogName +/// @return _Output NewCatalog* NewFSParser::FindCatalog(_Input const char* catalogName) { return nullptr; } -/// @brief -/// @param name -/// @return +/// @brief +/// @param name +/// @return _Output NewCatalog* NewFSParser::GetCatalog(_Input const char* name) { return nullptr; } -/// @brief -/// @param catalog -/// @return +/// @brief +/// @param catalog +/// @return Boolean NewFSParser::CloseCatalog(_Input _Output NewCatalog* catalog) { - return false; + return true; } -/// @brief -/// @param catalog -/// @return +/// @brief Mark catalog as removed. +/// @param catalog The catalog structure. +/// @return Boolean NewFSParser::RemoveCatalog(_Input _Output NewCatalog* catalog) { + catalog->Flags |= kNewFSFlagDeleted; + this->WriteCatalog(catalog, nullptr); + return false; } -/// @brief -/// @param catalog -/// @param dataSz -/// @return +/// ***************************************************************** /// +/// Reading,Seek,Tell are unimplemented on catalogs, refer to forks I/O instead. +/// ***************************************************************** /// + +/// @brief +/// @param catalog +/// @param dataSz +/// @return VoidPtr NewFSParser::ReadCatalog(_Input _Output NewCatalog* catalog, SizeT dataSz) { return nullptr; } -/// @brief -/// @param catalog -/// @param off -/// @return +/// @brief +/// @param catalog +/// @param off +/// @return bool NewFSParser::Seek(_Input _Output NewCatalog* catalog, SizeT off) { return false; } -/// @brief -/// @param catalog -/// @return +/// @brief +/// @param catalog +/// @return SizeT NewFSParser::Tell(_Input _Output NewCatalog* catalog) { return 0; } -/// @brief -/// @param sz -/// @return -STATIC Lba ke_find_free_fork(SizeT sz) { 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) { + auto drive = *sMountpointInterface.GetAddressOf(drv); -/// @brief -/// @param sz -/// @return -STATIC Lba ke_find_free_catalog(SizeT sz) { return 0; } + if (drive) { + /// prepare packet. + bool done = false; + bool error = false; -/// @brief -/// @param sz -/// @return -STATIC Lba ke_find_free_data(SizeT sz) { return 0; } + Lba lba = catalog->LastFork; + + while (!done) { + Char 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(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) { + auto drive = *sMountpointInterface.GetAddressOf(drv); + + if (drive) { + Char 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 { return false; } +Boolean fs_init_newfs(Void) noexcept { return true; } } // namespace NewOS::Detail -#endif // ifdef __FSKIT_NEWFS__
\ No newline at end of file +#endif // ifdef __FSKIT_NEWFS__ |
