From a13e1c0911c0627184bc38f18c7fdda64447b3ad Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sun, 23 Mar 2025 19:13:48 +0100 Subject: meta(kernel): Reworked repository's filesystem structure. Removing useless parts of the project too. Signed-off-by: Amlal El Mahrouss --- dev/kernel/FSKit/Defines.h | 12 + dev/kernel/FSKit/HeFS.h | 59 +++++ dev/kernel/FSKit/IndexableProperty.h | 63 +++++ dev/kernel/FSKit/NeFS.h | 445 +++++++++++++++++++++++++++++++++++ 4 files changed, 579 insertions(+) create mode 100644 dev/kernel/FSKit/Defines.h create mode 100644 dev/kernel/FSKit/HeFS.h create mode 100644 dev/kernel/FSKit/IndexableProperty.h create mode 100644 dev/kernel/FSKit/NeFS.h (limited to 'dev/kernel/FSKit') diff --git a/dev/kernel/FSKit/Defines.h b/dev/kernel/FSKit/Defines.h new file mode 100644 index 00000000..9431a9c0 --- /dev/null +++ b/dev/kernel/FSKit/Defines.h @@ -0,0 +1,12 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +#define FSKIT_VERSION "1.0.0" +#define FSKIT_VERSION_BCD 0x0100 diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h new file mode 100644 index 00000000..6911ddef --- /dev/null +++ b/dev/kernel/FSKit/HeFS.h @@ -0,0 +1,59 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +/// @file HeFS.h +/// @brief HeFS filesystem support. + +#define kHeFSVersion (0x0100) +#define kHeFSMagic " HeFS" +#define kHeFSMagicLen (8) + +#define kHeFSFileNameLen (256U) +#define kHeFSPartNameLen (256U) + +#define kHeFSMinimumDiskSize (gib_cast(64)) + +enum +{ + kHeFSInvalidDrive, + kHeFSHDDDrive, + kHeFSSSDDrive, + kHeFSMassStorageDrive, + kHeFSSCSIDrive, + kHeFSDriveCount, +}; + +struct HeFS_BOOT_NODE; + +struct HeFS_BOOT_NODE final +{ + NeOS::Char fMagic[kHeFSMagicLen]; + NeOS::Char fPartName[kHeFSPartNameLen]; + NeOS::UInt32 fVersion; + NeOS::UInt64 fBadSectors; + NeOS::UInt64 fSectorCount; + NeOS::UInt64 fSectorSize; + NeOS::UInt32 fChecksum; + NeOS::UInt8 fDriveKind; + NeOS::UInt8 fTextEncoding; + NeOS::UInt64 fRootINode; + NeOS::UInt64 fRecoveryINode; +}; + +struct HeFS_INDEX_NODE +{ + NeOS::Char fName[kHeFSFileNameLen]; + NeOS::UInt32 fFlags; + NeOS::UInt16 fKind; + NeOS::UInt32 fSize; + NeOS::Lba fFirstINode; + NeOS::Lba fLastINode; + NeOS::UInt32 fChecksum; +}; \ No newline at end of file diff --git a/dev/kernel/FSKit/IndexableProperty.h b/dev/kernel/FSKit/IndexableProperty.h new file mode 100644 index 00000000..6a79bc1b --- /dev/null +++ b/dev/kernel/FSKit/IndexableProperty.h @@ -0,0 +1,63 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include + +#define kIndexerCatalogNameLength 256U +#define kIndexerClaimed 0xCF + +namespace NeOS +{ + namespace Indexer + { + struct IndexProperty final + { + public: + Char Drive[kDriveNameLen]; + Char Path[kIndexerCatalogNameLength]; + }; + + class IndexableProperty final : public Property + { + public: + explicit IndexableProperty() + : Property() + { + NeOS::KString strProp(kMaxPropLen); + strProp += "/prop/indexable"; + + this->GetKey() = strProp; + } + + ~IndexableProperty() override = default; + + NE_COPY_DEFAULT(IndexableProperty); + + public: + IndexProperty& Leak() noexcept; + + public: + void AddFlag(Int16 flag); + void RemoveFlag(Int16 flag); + Int16 HasFlag(Int16 flag); + + private: + IndexProperty fIndex; + UInt32 fFlags; + }; + + /// @brief Index a file into the indexer instance. + /// @param filename path + /// @param filenameLen used bytes in path. + /// @param indexer the filesystem indexer. + /// @return none. + Void fs_index_file(const Char* filename, SizeT filenameLen, IndexableProperty& indexer); + } // namespace Indexer +} // namespace NeOS diff --git a/dev/kernel/FSKit/NeFS.h b/dev/kernel/FSKit/NeFS.h new file mode 100644 index 00000000..b2f7095d --- /dev/null +++ b/dev/kernel/FSKit/NeFS.h @@ -0,0 +1,445 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + + FILE: NeFS.h + PURPOSE: NeFS (New extended File System) support. + + Revision History: + + ?/?/?: Added file (amlel) + 12/02/24: Add UUID macro for EPM and GPT partition schemes. + 3/16/24: Add mandatory sector size, kNeFSSectorSz is set to 2048 by +default. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include +#include +#include + +/** + @brief New extended File System specification. + @author Amlal EL Mahrouss (Amlal EL Mahrouss, amlalelmahrouss at icloud dot com) +*/ + +#define kNeFSInvalidFork (-1) +#define kNeFSInvalidCatalog (-1) +#define kNeFSCatalogNameLen (256) + +#define kNeFSMinimumDiskSize (gib_cast(4)) + +#define kNeFSSectorSz (512) + +#define kNeFSIdentLen (8) +#define kNeFSIdent " NeFS" +#define kNeFSPadLen (392) + +#define kNeFSMetaFilePrefix '$' + +#define kNeFSVersionInteger (0x0129) +#define kNeFSVerionString "1.2.9" + +/// @brief Standard fork types. +#define kNeFSDataFork "main_data" +#define kNeFSResourceFork "main_rsrc" + +#define kNeFSForkSize (sizeof(NEFS_FORK_STRUCT)) + +#define kNeFSPartitionTypeStandard (7) +#define kNeFSPartitionTypePage (8) +#define kNeFSPartitionTypeBoot (9) + +#define kNeFSCatalogKindFile (1) +#define kNeFSCatalogKindDir (2) +#define kNeFSCatalogKindAlias (3) + +//! Shared between network and/or partitions. Export forks as .zip when copying. +#define kNeFSCatalogKindShared (4) + +#define kNeFSCatalogKindResource (5) +#define kNeFSCatalogKindExecutable (6) + +#define kNeFSCatalogKindPage (8) + +#define kNeFSCatalogKindDevice (9) +#define kNeFSCatalogKindLock (10) + +#define kNeFSCatalogKindRLE (11) +#define kNeFSCatalogKindMetaFile (12) + +#define kNeFSCatalogKindTTF (13) +#define kNeFSCatalogKindRIFF (14) +#define kNeFSCatalogKindMPEG (15) +#define kNeFSCatalogKindMOFF (16) + +#define kNeFSSeparator '/' +#define kNeFSSeparatorAlt '/' + +#define kNeFSUpDir ".." +#define kNeFSRoot "/" +#define kNeFSRootAlt "/" + +#define kNeFSLF '\r' +#define kNeFSEOF (-1) + +#define kNeFSBitWidth (sizeof(NeOS::Char)) +#define kNeFSLbaType (NeOS::Lba) + +/// @note Start after the partition map header. (Virtual addressing) +#define kNeFSRootCatalogStartAddress (1024) +#define kNeFSCatalogStartAddress (kNeFSRootCatalogStartAddress + sizeof(NEFS_ROOT_PARTITION_BLOCK)) + +#define kResourceTypeDialog (10) +#define kResourceTypeString (11) +#define kResourceTypeMenu (12) +#define kResourceTypeSound (13) +#define kResourceTypeFont (14) +#define kNeFSPartLen (32) + +#define kNeFSFlagDeleted (70) +#define kNeFSFlagUnallocated (0) +#define kNeFSFlagCreated (71) + +#define kNeFSMimeNameLen (200) +#define kNeFSForkNameLen (200) + +#define kNeFSFrameworkExt ".fwrk/" +#define kNeFSStepsExt ".step/" +#define kNeFSApplicationExt ".app/" +#define kNeFSJournalExt ".jrnl" + +struct NEFS_CATALOG_STRUCT; +struct NEFS_FORK_STRUCT; +struct NEFS_ROOT_PARTITION_BLOCK; + +enum +{ + kNeFSHardDrive = 0xC0, // Hard Drive + kNeFSSolidStateDrive = 0xC1, // Solid State Drive + kNeFSOpticalDrive = 0x0C, // Blu-Ray/DVD + kNeFSMassStorageDevice = 0xCC, // USB + kNeFSScsiDrive = 0xC4, // SCSI Hard Drive + kNeFSFlashDrive = 0xC6, + kNeFSUnknown = 0xFF, // Unknown device. + kNeFSDriveCount = 7, +}; + +enum +{ + kNeFSStatusUnlocked = 0x18, + kNeFSStatusLocked, + kNeFSStatusError, + kNeFSStatusInvalid, +}; + +/// @brief Catalog type. +struct PACKED NEFS_CATALOG_STRUCT final +{ + BOOL ForkOrCatalog : 1 {0}; + + NeOS::Char Name[kNeFSCatalogNameLen] = {0}; + NeOS::Char Mime[kNeFSMimeNameLen] = {0}; + + /// Catalog flags. + NeOS::UInt16 Flags; + + /// Catalog allocation status. + NeOS::UInt16 Status; + + /// Custom catalog flags. + NeOS::UInt16 CatalogFlags; + + /// Catalog kind. + NeOS::Int32 Kind; + + /// Size of the data fork. + NeOS::Lba DataForkSize; + + /// Size of all resource forks. + NeOS::Lba ResourceForkSize; + + /// Forks LBA. + NeOS::Lba DataFork; + NeOS::Lba ResourceFork; + + /// Buddy allocation tracker. + NeOS::Lba NextSibling; + NeOS::Lba PrevSibling; + + /// Best-buddy tracker. + NeOS::Lba NextBestSibling; + NeOS::Lba NextPrevSibling; + + NeOS::UInt32 Checksum; +}; + +/// @brief Fork type, contains a data page. +/// @note The way we store is way different than how other filesystems do, specific chunk of code are +/// written into either the data fork or resource fork, the resource fork is reserved for file metadata. +/// whereas the data fork is reserved for file data. +struct PACKED NEFS_FORK_STRUCT final +{ + BOOL ForkOrCatalog : 1 {1}; + + NeOS::Char ForkName[kNeFSForkNameLen] = {0}; + NeOS::Char CatalogName[kNeFSCatalogNameLen] = {0}; + + NeOS::Int32 Flags; + NeOS::Int32 Kind; + + NeOS::Int64 ResourceId; + NeOS::Int32 ResourceKind; + NeOS::Int32 ResourceFlags; + + NeOS::Lba DataOffset; // 8 Where to look for this data? + NeOS::SizeT DataSize; /// Data size according using sector count. + + NeOS::Lba NextSibling; + NeOS::Lba PreviousSibling; + + NeOS::Char Pad[2] = {0}; +}; + +/// @brief Partition block type +struct PACKED NEFS_ROOT_PARTITION_BLOCK final +{ + NeOS::Char Ident[kNeFSIdentLen] = {0}; + NeOS::Char PartitionName[kNeFSPartLen] = {0}; + + NeOS::Int32 Flags; + NeOS::Int32 Kind; + + NeOS::Lba StartCatalog; + NeOS::SizeT CatalogCount; + + NeOS::SizeT DiskSize; + + NeOS::SizeT FreeCatalog; + NeOS::SizeT FreeSectors; + + NeOS::SizeT SectorCount; + NeOS::SizeT SectorSize; + + NeOS::UInt64 Version; + + NeOS::Lba EpmBlock; + + NeOS::Char Pad[kNeFSPadLen]; +}; + +namespace NeOS +{ + class NeFileSystemParser; + class NeFileSystemJournal; + class NeFileSystemHelper; + + enum + { + kNeFSSubDriveA, + kNeFSSubDriveB, + kNeFSSubDriveC, + kNeFSSubDriveD, + kNeFSSubDriveInvalid, + kNeFSSubDriveCount, + }; + + /// \brief Resource fork kind. + enum + { + kNeFSRsrcForkKind = 0, + kNeFSDataForkKind = 1 + }; + + /// + /// \name NeFileSystemParser + /// \brief NeFS parser class. (catalog creation, remove removal, root, + /// forks...) Designed like the DOM, detects the filesystem automatically. + /// + class NeFileSystemParser final + { + public: + explicit NeFileSystemParser() = default; + ~NeFileSystemParser() = default; + + public: + NE_COPY_DEFAULT(NeFileSystemParser); + + public: + /// @brief Creates a new fork inside the NeFS partition. + /// @param catalog it's catalog + /// @param theFork the fork itself. + /// @return the fork + _Output BOOL CreateFork(_Input NEFS_FORK_STRUCT& in); + + /// @brief Find fork inside New filesystem. + /// @param catalog the catalog. + /// @param name the fork name. + /// @return the fork. + _Output NEFS_FORK_STRUCT* FindFork(_Input NEFS_CATALOG_STRUCT* catalog, + _Input const Char* name, + Boolean data); + + _Output Void RemoveFork(_Input NEFS_FORK_STRUCT* fork); + + _Output Void CloseFork(_Input NEFS_FORK_STRUCT* fork); + + _Output NEFS_CATALOG_STRUCT* FindCatalog(_Input const Char* catalog_name, Lba& ou_lba, Bool search_hidden = YES, Bool local_search = NO); + + _Output NEFS_CATALOG_STRUCT* GetCatalog(_Input const Char* name); + + _Output NEFS_CATALOG_STRUCT* CreateCatalog(_Input const Char* name, + _Input const Int32& flags, + _Input const Int32& kind); + + _Output NEFS_CATALOG_STRUCT* CreateCatalog(_Input const Char* name); + + _Output Bool WriteCatalog(_Input const Char* catalog, + _Input Bool rsrc, + _Input VoidPtr data, + _Input SizeT sz, + _Input const Char* name); + + _Output VoidPtr ReadCatalog(_Input _Output NEFS_CATALOG_STRUCT* catalog, + _Input Bool isRsrcFork, + _Input SizeT dataSz, + _Input const Char* forkName); + + _Output Bool Seek(_Input _Output NEFS_CATALOG_STRUCT* catalog, SizeT off); + + _Output SizeT Tell(_Input _Output NEFS_CATALOG_STRUCT* catalog); + + _Output Bool RemoveCatalog(_Input const Char* catalog); + + _Output Bool CloseCatalog(_InOut NEFS_CATALOG_STRUCT* catalog); + + /// @brief Make a EPM+NeFS drive out of the disk. + /// @param drive The drive to write on. + /// @return If it was sucessful, see err_local_get(). + _Output Bool Format(_Input _Output DriveTrait* drive, _Input const Lba endLba, _Input const Int32 flags, const Char* part_name); + + public: + UInt32 mDriveIndex{kNeFSSubDriveA}; + }; + + /// + /// \name NeFileSystemHelper + /// \brief Filesystem helper and utils. + /// + + class NeFileSystemHelper final + { + public: + STATIC const Char* Root(); + STATIC const Char* UpDir(); + STATIC const Char Separator(); + STATIC const Char MetaFile(); + }; + + /// @brief Journal class for NeFS. + class NeFileSystemJournal final + { + private: + NEFS_CATALOG_STRUCT* mNode{nullptr}; + + public: + explicit NeFileSystemJournal(const char* stamp = nullptr) + { + if (!stamp) + { + kout << "Invalid: Journal Stamp, using default name.\r"; + return; + } + + kout << "Info: Journal stamp: " << stamp << kendl; + rt_copy_memory((VoidPtr)stamp, this->mStamp, rt_string_len(stamp)); + } + + ~NeFileSystemJournal() = default; + + NE_COPY_DEFAULT(NeFileSystemJournal); + + Bool CreateJournal(NeFileSystemParser* parser) + { + if (!parser) + return NO; + + delete parser->CreateCatalog("/etc/xml/", 0, kNeFSCatalogKindDir); + mNode = parser->CreateCatalog(mStamp); + + if (!mNode) + return NO; + + return YES; + } + + Bool GetJournal(NeFileSystemParser* parser) + { + if (!parser) + return NO; + + auto node = parser->GetCatalog(mStamp); + + if (node) + { + mNode = node; + return YES; + } + + return NO; + } + + Bool ReleaseJournal() + { + if (mNode) + { + delete mNode; + mNode = nullptr; + return YES; + } + + return NO; + } + + Bool CommitJournal(NeFileSystemParser* parser, + Char* xml_data, + Char* journal_name) + { + if (!parser || + !mNode) + return NO; + + NEFS_FORK_STRUCT new_fork{}; + + rt_copy_memory(mStamp, new_fork.CatalogName, rt_string_len(mStamp)); + rt_copy_memory(journal_name, new_fork.ForkName, rt_string_len(journal_name)); + + new_fork.ResourceKind = 0; + new_fork.ResourceId = 0; + new_fork.ResourceFlags = 0; + new_fork.DataSize = rt_string_len(xml_data); + new_fork.Kind = kNeFSRsrcForkKind; + + if (!parser->CreateFork(new_fork)) + return NO; + + kout << "XML Commited: " << xml_data << "\r\nTo Journal Fork: " << journal_name << kendl; + + auto ret = parser->WriteCatalog(new_fork.CatalogName, YES, xml_data, rt_string_len(xml_data), new_fork.ForkName); + + return ret; + } + + private: + Char mStamp[kNeFSCatalogNameLen] = {"/etc/xml/journal" kNeFSJournalExt}; + }; + + namespace NeFS + { + Boolean fs_init_nefs(Void) noexcept; + } // namespace NeFS +} // namespace NeOS -- cgit v1.2.3