diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2025-11-24 03:02:43 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal@nekernel.org> | 2025-11-24 03:02:43 +0100 |
| commit | 83d870e58457a1d335a1d9b9966a6a1887cc297b (patch) | |
| tree | 72888f88c7728c82f3f6df1f4f70591de15eab36 /src/kernel/FSKit | |
| parent | ab37adbacf0f33845804c788b39680cd754752a8 (diff) | |
feat! breaking changes on kernel sources.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'src/kernel/FSKit')
| -rw-r--r-- | src/kernel/FSKit/Defines.h | 12 | ||||
| -rw-r--r-- | src/kernel/FSKit/Ext2+IFS.h | 273 | ||||
| -rw-r--r-- | src/kernel/FSKit/Ext2.h | 148 | ||||
| -rw-r--r-- | src/kernel/FSKit/IndexableProperty.h | 58 | ||||
| -rw-r--r-- | src/kernel/FSKit/NeFS.h | 413 | ||||
| -rw-r--r-- | src/kernel/FSKit/OpenHeFS.h | 434 |
6 files changed, 1338 insertions, 0 deletions
diff --git a/src/kernel/FSKit/Defines.h b/src/kernel/FSKit/Defines.h new file mode 100644 index 00000000..c5bf8f88 --- /dev/null +++ b/src/kernel/FSKit/Defines.h @@ -0,0 +1,12 @@ +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +#include <NeKit/Defines.h> + +#define FSKIT_VERSION "1.0.0" +#define FSKIT_VERSION_BCD 0x0100 diff --git a/src/kernel/FSKit/Ext2+IFS.h b/src/kernel/FSKit/Ext2+IFS.h new file mode 100644 index 00000000..01ca4c90 --- /dev/null +++ b/src/kernel/FSKit/Ext2+IFS.h @@ -0,0 +1,273 @@ +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +#include <FSKit/Ext2.h> +#include <KernelKit/DriveMgr.h> +#include <KernelKit/HeapMgr.h> +#include <KernelKit/KPC.h> +#include <NeKit/ErrorOr.h> +#include <NeKit/KernelPanic.h> +#include <NeKit/Utils.h> + +namespace Kernel { +/// @brief Context for an EXT2 filesystem on a given drive +class Ext2Context final { + public: + DriveTrait* drive{nullptr}; + EXT2_SUPER_BLOCK* superblock{nullptr}; + + /// @brief context with a drive + Ext2Context(Kernel::DriveTrait* drv) : drive(drv) {} + + /// @brief Clean up + ~Ext2Context() { + if (superblock) { + Kernel::mm_free_ptr(superblock); + superblock = nullptr; + } + } + + Ext2Context(const Ext2Context&) = delete; + Ext2Context& operator=(const Ext2Context&) = delete; + + Ext2Context(Ext2Context&& other) noexcept : drive(other.drive), superblock(other.superblock) { + other.drive = nullptr; + other.superblock = nullptr; + } + + Ext2Context& operator=(Ext2Context&& other) noexcept { + if (this != &other) { + if (superblock) { + Kernel::mm_free_ptr(superblock); + } + drive = other.drive; + superblock = other.superblock; + other.drive = nullptr; + other.superblock = nullptr; + } + return *this; + } + + SizeT BlockSize() const { + if (!superblock) return kExt2FSBlockSizeBase; + return kExt2FSBlockSizeBase << superblock->fLogBlockSize; + } + + operator BOOL() { return superblock != nullptr; } +}; + +/// ======================================================================= /// +/// IFS FUNCTIONS +/// ======================================================================= /// + +inline BOOL ext2_read_block(Kernel::DriveTrait* drv, Kernel::UInt32 lba, VoidPtr buffer, + Kernel::UInt32 size) { + if (!drv || !buffer) return false; + + Kernel::DriveTrait::DrivePacket pkt{}; + pkt.fPacketContent = buffer; + pkt.fPacketSize = size; + pkt.fPacketLba = lba; + drv->fInput(pkt); + + return pkt.fPacketGood; +} + +inline BOOL ext2_write_block(Kernel::DriveTrait* drv, Kernel::UInt32 lba, const VoidPtr buffer, + Kernel::UInt32 size) { + if (!drv || !buffer) return false; + + Kernel::DriveTrait::DrivePacket pkt{}; + pkt.fPacketContent = const_cast<VoidPtr>(buffer); + pkt.fPacketSize = size; + pkt.fPacketLba = lba; + drv->fOutput(pkt); + return pkt.fPacketGood; +} + +inline Kernel::ErrorOr<EXT2_SUPER_BLOCK*> ext2_load_superblock(Ext2Context* ctx) { + if (!ctx || !ctx->drive) return Kernel::ErrorOr<EXT2_SUPER_BLOCK*>(Kernel::kErrorInvalidData); + + auto buf = Kernel::mm_alloc_ptr(sizeof(EXT2_SUPER_BLOCK), true, false); + if (!buf) return Kernel::ErrorOr<EXT2_SUPER_BLOCK*>(Kernel::kErrorHeapOutOfMemory); + + Kernel::UInt32 blockLba = kExt2FSSuperblockOffset / ctx->drive->fSectorSz; + + if (!ext2_read_block(ctx->drive, blockLba, buf, sizeof(EXT2_SUPER_BLOCK))) { + Kernel::mm_free_ptr(buf); + return Kernel::ErrorOr<EXT2_SUPER_BLOCK*>(Kernel::kErrorDisk); + } + + auto sb = reinterpret_cast<EXT2_SUPER_BLOCK*>(buf); + if (sb->fMagic != kExt2FSMagic) { + Kernel::mm_free_ptr(buf); + return Kernel::ErrorOr<EXT2_SUPER_BLOCK*>(Kernel::kErrorInvalidData); + } + + ctx->superblock = sb; + return Kernel::ErrorOr<EXT2_SUPER_BLOCK*>(sb); +} + +// Load inode +inline Kernel::ErrorOr<Ext2Node*> ext2_load_inode(Ext2Context* ctx, Kernel::UInt32 inodeNumber) { + if (!ctx || !ctx->superblock) return Kernel::ErrorOr<Ext2Node*>(Kernel::kErrorInvalidData); + + auto nodePtr = Kernel::mm_alloc_ptr(sizeof(Ext2Node), true, false); + if (!nodePtr) return Kernel::ErrorOr<Ext2Node*>(Kernel::kErrorHeapOutOfMemory); + + auto ext2Node = reinterpret_cast<Ext2Node*>(nodePtr); + ext2Node->inodeNumber = inodeNumber; + + // Compute block group and index within group + Kernel::UInt32 inodesPerGroup = ctx->superblock->fInodesPerGroup; + Kernel::UInt32 group = (inodeNumber - 1) / inodesPerGroup; + + // dummy: just offset first inode + Kernel::UInt32 inodeTableBlock = ctx->superblock->fFirstInode + group; + + if (!ext2_read_block(ctx->drive, inodeTableBlock, &ext2Node->inode, sizeof(EXT2_INODE))) { + Kernel::mm_free_ptr(nodePtr); + return Kernel::ErrorOr<Ext2Node*>(Kernel::kErrorDisk); + } + + ext2Node->cursor = 0; + return Kernel::ErrorOr<Ext2Node*>(ext2Node); +} + +/* + * Ext2FileSystemParser Class + * + * Provides high-level interface for EXT2 filesystem operations + */ +class Ext2FileSystemParser final { + private: + Ext2Context fCtx; // Internal EXT2 context + + public: + /* + * Constructor + * Initializes the parser with a drive interface + * + * @param drive: Pointer to drive trait for disk I/O operations + */ + explicit Ext2FileSystemParser(DriveTrait* drive); + + NE_COPY_DELETE(Ext2FileSystemParser) + + /* + * Open a file or directory by path + * + * @param path: Full path to the file/directory (e.g., "/home/user/file.txt") + * @param restrict_type: Access mode restriction (e.g., "r", "w", "rw") + * @return: VoidPtr handle to the opened file/directory, or nullptr on failure + */ + VoidPtr Open(const char* path, const char* restrict_type); + + /* + * Read data from an open file node + * + * @param node: File node handle returned by Open() + * @param flags: Read operation flags + * @param size: Number of bytes to read + * @return: Pointer to allocated buffer containing read data, or nullptr on failure + * Caller is responsible for freeing the returned buffer + */ + VoidPtr Read(VoidPtr node, Int32 flags, SizeT size); + + /* + * Write data to an open file node + * + * @param node: File node handle returned by Open() + * @param data: Buffer containing data to write + * @param flags: Write operation flags + * @param size: Number of bytes to write + */ + Void Write(VoidPtr node, VoidPtr data, Int32 flags, SizeT size); + + /* + * Seek to a specific position in the file + * + * @param node: File node handle + * @param offset: Byte offset from beginning of file + * @return: true on success, false on failure + */ + BOOL Seek(VoidPtr node, SizeT offset); + + /* + * Get current position in the file + * + * @param node: File node handle + * @return: Current byte offset from beginning of file + */ + SizeT Tell(VoidPtr node); + + /* + * Reset file position to beginning + * + * @param node: File node handle + * @return: true on success, false on failure + */ + BOOL Rewind(VoidPtr node); + + /* + * Read data from a named file within a directory node + * + * @param name: Name of file within the directory + * @param node: Directory node handle + * @param flags: Read operation flags + * @param size: Number of bytes to read + * @return: Pointer to allocated buffer containing read data, or nullptr on failure + */ + VoidPtr Read(const char* name, VoidPtr node, Int32 flags, SizeT size); + + /* + * Write data to a named file within a directory node + * + * @param name: Name of file within the directory + * @param node: Directory node handle + * @param data: Buffer containing data to write + * @param flags: Write operation flags + * @param size: Number of bytes to write + */ + Void Write(const char* name, VoidPtr node, VoidPtr data, Int32 flags, SizeT size); + + /* + * Create a new regular file + * + * @param path: Full path for the new file + * @return: VoidPtr handle to the created file, or nullptr on failure + */ + VoidPtr Create(const char* path); + + /* + * Create a new directory + * + * @param path: Full path for the new directory + * @return: VoidPtr handle to the created directory, or nullptr on failure + */ + VoidPtr CreateDirectory(const char* path); + + /* + * Close and free a file/directory node + * Note: This method is not shown in the implementation but would typically be needed + * + * @param node: Node handle to close and free + */ + Void Close(VoidPtr node); + + /* + * Get file/directory information + * Note: This method is not shown in the implementation but would typically be needed + * + * @param node: Node handle + * @param info: Structure to fill with file information (size, type, permissions, etc.) + * @return: true on success, false on failure + */ + BOOL GetInfo(VoidPtr node, VoidPtr info); +}; +} // namespace Kernel diff --git a/src/kernel/FSKit/Ext2.h b/src/kernel/FSKit/Ext2.h new file mode 100644 index 00000000..e979e556 --- /dev/null +++ b/src/kernel/FSKit/Ext2.h @@ -0,0 +1,148 @@ +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +#include <CompilerKit/CompilerKit.h> +#include <KernelKit/DriveMgr.h> +#include <NeKit/Defines.h> +#include <NeKit/KString.h> +#include <hint/CompilerHint.h> + +/// @file Ext2.h +/// @brief EXT2 filesystem structures, constants, and base wrappers. + +/// EXT2 Constants +#define kExt2FSMagic (0xEF53) +#define kExt2FSMaxFileNameLen (255U) +#define kExt2FSSuperblockOffset (1024) +#define kExt2FSRootInodeNumber (2) +#define kExt2FSInodeSize (128U) +#define kExt2FSBlockSizeBase (1024U) + +#define kExt2FSRev0 (0) +#define kExt2FSRev1 (1) + +/// EXT2 file types +enum { + kExt2FileTypeUnknown = 0, + kExt2FileTypeRegular = 1, + kExt2FileTypeDirectory = 2, + kExt2FileTypeCharDevice = 3, + kExt2FileTypeBlockDevice = 4, + kExt2FileTypeFIFO = 5, + kExt2FileTypeSocket = 6, + kExt2FileTypeSymbolicLink = 7 +}; + +typedef struct EXT2_GROUP_DESCRIPTOR final { + UInt32 fBlockBitmap; + UInt32 fInodeBitmap; + UInt32 fInodeTable; + UInt16 fFreeBlocksCount; + UInt16 fFreeInodesCount; + UInt16 fBgUsedDirsCount; + UInt16 fBgPad; + UInt32 fBgReserved[3]; +} EXT2_GROUP_DESCRIPTOR; + +struct PACKED EXT2_SUPER_BLOCK final { + Kernel::UInt32 fInodeCount; + Kernel::UInt32 fBlockCount; + Kernel::UInt32 fReservedBlockCount; + Kernel::UInt32 fFreeBlockCount; + Kernel::UInt32 fFreeInodeCount; + Kernel::UInt32 fFirstDataBlock; + Kernel::UInt32 fLogBlockSize; + Kernel::UInt32 fLogFragmentSize; + Kernel::UInt32 fBlocksPerGroup; + Kernel::UInt32 fFragmentsPerGroup; + Kernel::UInt32 fInodesPerGroup; + Kernel::UInt32 fMountTime; + Kernel::UInt32 fWriteTime; + Kernel::UInt16 fMountCount; + Kernel::UInt16 fMaxMountCount; + Kernel::UInt16 fMagic; + Kernel::UInt16 fState; + Kernel::UInt16 fErrors; + Kernel::UInt16 fMinorRevision; + Kernel::UInt32 fLastCheck; + Kernel::UInt32 fCheckInterval; + Kernel::UInt32 fCreatorOS; + Kernel::UInt32 fRevisionLevel; + Kernel::UInt16 fDefaultUID; + Kernel::UInt16 fDefaultGID; + + // EXT2_DYNAMIC_REV fields + Kernel::UInt32 fFirstInode; + Kernel::UInt16 fInodeSize; + Kernel::UInt16 fBlockGroupNumber; + Kernel::UInt32 fFeatureCompat; + Kernel::UInt32 fFeatureIncompat; + Kernel::UInt32 fFeatureROCompat; + Kernel::UInt8 fUUID[16]; + Kernel::Char fVolumeName[16]; + Kernel::Char fLastMounted[64]; + Kernel::UInt32 fAlgoBitmap; + + Kernel::UInt8 fPreallocBlocks; + Kernel::UInt8 fPreallocDirBlocks; + Kernel::UInt16 fReservedGDTBlocks; + + Kernel::UInt8 fJournalUUID[16]; + Kernel::UInt32 fJournalInode; + Kernel::UInt32 fJournalDevice; + Kernel::UInt32 fLastOrphan; + + Kernel::UInt32 fHashSeed[4]; + Kernel::UInt8 fDefHashVersion; + Kernel::UInt8 fReservedCharPad; + Kernel::UInt16 fReservedWordPad; + Kernel::UInt32 fDefaultMountOpts; + Kernel::UInt32 fFirstMetaBlockGroup; + + Kernel::UInt8 fReserved[760]; // Padding to make 1024 bytes +}; + +struct PACKED EXT2_INODE final { + Kernel::UInt16 fMode; + Kernel::UInt16 fUID; + Kernel::UInt32 fSize; + Kernel::UInt32 fAccessTime; + Kernel::UInt32 fCreateTime; + Kernel::UInt32 fModifyTime; + Kernel::UInt32 fDeleteTime; + Kernel::UInt16 fGID; + Kernel::UInt16 fLinksCount; + Kernel::UInt32 fBlocks; + Kernel::UInt32 fFlags; + Kernel::UInt32 fOSD1; + + Kernel::UInt32 fBlock[15]; // direct 0-11, indirect 12, double 13, triple 14 + + Kernel::UInt32 fGeneration; + Kernel::UInt32 fFileACL; + Kernel::UInt32 fDirACL; + Kernel::UInt32 fFragmentAddr; + + Kernel::UInt8 fOSD2[12]; +}; + +/// Directory entry +struct PACKED EXT2_DIR_ENTRY final { + Kernel::UInt32 fInode; + Kernel::UInt16 fRecordLength; + Kernel::UInt8 fNameLength; + Kernel::UInt8 fFileType; + Kernel::Char fName[kExt2FSMaxFileNameLen]; +}; + +/// VFS usage +struct Ext2Node { + Kernel::UInt32 inodeNumber; + EXT2_INODE inode; + Kernel::UInt32 cursor{0}; +}; diff --git a/src/kernel/FSKit/IndexableProperty.h b/src/kernel/FSKit/IndexableProperty.h new file mode 100644 index 00000000..a89e78b8 --- /dev/null +++ b/src/kernel/FSKit/IndexableProperty.h @@ -0,0 +1,58 @@ +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +#include <CFKit/Property.h> +#include <CompilerKit/CompilerKit.h> +#include <KernelKit/DriveMgr.h> + +#define kIndexerCatalogNameLength (256U) +#define kIndexerClaimed (0xCF) +#define kIndexerUnclaimed (0xCA) + +namespace Kernel { +namespace Indexer { + struct Index final { + public: + Char Drive[kDriveNameLen]{}; + Char Path[kIndexerCatalogNameLength]{}; + }; + + class IndexableProperty final : public Property { + public: + explicit IndexableProperty() : Property() { + KBasicString<> strProp(kMaxPropLen); + strProp += "/prop/indexable"; + + this->GetKey() = strProp; + } + + ~IndexableProperty() override = default; + + NE_COPY_DEFAULT(IndexableProperty) + + public: + Index& Leak() noexcept; + + public: + Void AddFlag(UInt16 flag); + Void RemoveFlag(UInt16 flag); + UInt16 HasFlag(UInt16 flag); + + private: + Index 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 Kernel diff --git a/src/kernel/FSKit/NeFS.h b/src/kernel/FSKit/NeFS.h new file mode 100644 index 00000000..54861dec --- /dev/null +++ b/src/kernel/FSKit/NeFS.h @@ -0,0 +1,413 @@ +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + + 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 <CompilerKit/CompilerKit.h> +#include <KernelKit/DriveMgr.h> +#include <NeKit/Defines.h> +#include <NeKit/KString.h> +#include <hint/CompilerHint.h> + +/** + @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 kNeFSVolumeName "NeFS Volume" + +#define kNeFSMinimumDiskSize (mib_cast(8)) + +#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(Kernel::Char)) +#define kNeFSLbaType (Kernel::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 (199) + +#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, + kNeFSStatusCount, +}; + +/// @brief Catalog record type. +struct PACKED NEFS_CATALOG_STRUCT final { + BOOL ForkOrCatalog : 1 {0}; + + Kernel::Char Name[kNeFSCatalogNameLen] = {0}; + Kernel::Char Mime[kNeFSMimeNameLen] = {0}; + + /// Catalog flags. + Kernel::UInt16 Flags; + + /// Catalog allocation status. + Kernel::UInt16 Status; + + /// Custom catalog flags. + Kernel::UInt16 CatalogFlags; + + /// Catalog kind. + Kernel::Int32 Kind; + + /// Size of the data fork. + Kernel::Lba DataForkSize; + + /// Size of all resource forks. + Kernel::Lba ResourceForkSize; + + /// Forks LBA. + Kernel::Lba DataFork; + Kernel::Lba ResourceFork; + + /// Buddy allocation tracker. + Kernel::Lba NextSibling; + Kernel::Lba PrevSibling; + + /// Best-buddy tracker. + Kernel::Lba NextBestSibling; + Kernel::Lba NextPrevSibling; + + Kernel::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}; + + Kernel::Char ForkName[kNeFSForkNameLen] = {0}; + Kernel::Char CatalogName[kNeFSCatalogNameLen] = {0}; + + Kernel::Int32 Flags; + Kernel::Int32 Kind; + + Kernel::Int64 ResourceId; + Kernel::Int32 ResourceKind; + Kernel::Int32 ResourceFlags; + + Kernel::Lba DataOffset; // 8 Where to look for this data? + Kernel::SizeT DataSize; /// Data size according using sector count. + + Kernel::Lba NextSibling; + Kernel::Lba PreviousSibling; +}; + +/// @brief Partition block type +struct PACKED NEFS_ROOT_PARTITION_BLOCK final { + Kernel::Char Ident[kNeFSIdentLen] = {0}; + Kernel::Char PartitionName[kNeFSPartLen] = {0}; + + Kernel::Int32 Flags; + Kernel::Int32 Kind; + + Kernel::Lba StartCatalog; + Kernel::SizeT CatalogCount; + + Kernel::SizeT DiskSize; + + Kernel::SizeT FreeCatalog; + Kernel::SizeT FreeSectors; + + Kernel::SizeT SectorCount; + Kernel::SizeT SectorSize; + + Kernel::UInt64 Version; + + Kernel::Lba EpmBlock; + + Kernel::Char Pad[kNeFSPadLen]; +}; + +namespace Kernel { +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_DELETE(NeFileSystemParser) + + NE_MOVE_DELETE(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 Int32 flags, + const Char* part_name); + + public: + UInt32 mDriveIndex{kNeFSSubDriveA}; +}; + +/// +/// \name NeFileSystemHelper +/// \brief Filesystem helper class. +/// + +class NeFileSystemHelper final { + public: + STATIC const Char* Root(); + STATIC const Char* UpDir(); + STATIC Char Separator(); + STATIC 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; + } + + (Void)(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; + + (Void)(kout << "XML commit: " << xml_data << " to 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 Kernel diff --git a/src/kernel/FSKit/OpenHeFS.h b/src/kernel/FSKit/OpenHeFS.h new file mode 100644 index 00000000..bd392fc3 --- /dev/null +++ b/src/kernel/FSKit/OpenHeFS.h @@ -0,0 +1,434 @@ +/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/DriveMgr.h>
+#include <KernelKit/UserMgr.h>
+#include <NeKit/Crc32.h>
+#include <NeKit/Defines.h>
+#include <NeKit/KString.h>
+#include <hint/CompilerHint.h>
+
+/// @file OpenHeFS.h
+/// @brief OpenHeFS filesystem support.
+
+#define kOpenHeFSVersion (0x0104)
+#define kOpenHeFSMagic "OpenHeFS"
+#define kOpenHeFSMagicLen (9U)
+
+#define kOpenHeFSBlockLen (512U)
+#define kOpenHeFSFileNameLen (256U)
+#define kOpenHeFSPartNameLen (128U)
+
+#define kOpenHeFSMinimumDiskSize (gib_cast(128))
+
+#define kOpenHeFSDefaultVolumeName u8"OpenHeFS Volume"
+
+#define kOpenHeFSINDStartOffset (sizeof(HEFS_BOOT_NODE))
+#define kOpenHeFSINStartOffset (sizeof(HEFS_INDEX_NODE_DIRECTORY))
+
+#define kOpenHeFSRootDirectory "/"
+#define kOpenHeFSRootDirectoryU8 u8"/"
+
+#define kOpenHeFSSeparator '/'
+#define kOpenHeFSUpDir ".."
+
+#define kOpenHeFSRootDirectoryLen (2U)
+
+#define kOpenHeFSSearchAllStr u8"*"
+
+struct HEFS_BOOT_NODE;
+struct HEFS_INDEX_NODE;
+struct HEFS_INDEX_NODE_DIRECTORY;
+struct HEFS_JOURNAL_NODE;
+
+enum : UInt8 {
+ kOpenHeFSHardDrive = 0xC0, // Hard Drive
+ kOpenHeFSSolidStateDrive = 0xC1, // Solid State Drive
+ kOpenHeFSOpticalDrive = 0x0C, // Blu-Ray/DVD
+ kOpenHeFSMassStorageDevice = 0xCC, // USB
+ kOpenHeFSScsiDrive = 0xC4, // SCSI Hard Drive
+ kOpenHeFSFlashDrive = 0xC6,
+ kOpenHeFSUnknown = 0xFF, // Unknown device.
+ kOpenHeFSDriveCount = 8,
+};
+
+enum : UInt8 {
+ kOpenHeFSStatusUnlocked = 0x18,
+ kOpenHeFSStatusLocked,
+ kOpenHeFSStatusError,
+ kOpenHeFSStatusInvalid,
+ kOpenHeFSStatusCount,
+};
+
+enum : UInt16 {
+ kOpenHeFSEncodingFlagsUTF8 = 0x50,
+ kOpenHeFSEncodingFlagsUTF16,
+ kOpenHeFSEncodingFlagsUTF32,
+ kOpenHeFSEncodingFlagsUTF16BE,
+ kOpenHeFSEncodingFlagsUTF16LE,
+ kOpenHeFSEncodingFlagsUTF32BE,
+ kOpenHeFSEncodingFlagsUTF32LE,
+ kOpenHeFSEncodingFlagsUTF8BE,
+ kOpenHeFSEncodingFlagsUTF8LE,
+ kOpenHeFSEncodingFlagsBinary,
+ kOpenHeFSEncodingFlagsCount = 11,
+ kOpenHeFSFlagsNone = 0,
+ kOpenHeFSFlagsReadOnly = 0x100,
+ kOpenHeFSFlagsHidden,
+ kOpenHeFSFlagsSystem,
+ kOpenHeFSFlagsArchive,
+ kOpenHeFSFlagsDevice,
+ kOpenHeFSFlagsCount = 7
+};
+
+inline constexpr UInt16 kOpenHeFSFileKindRegular = 0x00;
+inline constexpr UInt16 kOpenHeFSFileKindDirectory = 0x01;
+inline constexpr UInt16 kOpenHeFSFileKindBlock = 0x02;
+inline constexpr UInt16 kOpenHeFSFileKindCharacter = 0x03;
+inline constexpr UInt16 kOpenHeFSFileKindFIFO = 0x04;
+inline constexpr UInt16 kOpenHeFSFileKindSocket = 0x05;
+inline constexpr UInt16 kOpenHeFSFileKindSymbolicLink = 0x06;
+inline constexpr UInt16 kOpenHeFSFileKindUnknown = 0x07;
+inline constexpr UInt16 kOpenHeFSFileKindCount = 0x08;
+
+/// @brief OpenHeFS blocks are array containing sparse blocks of data.
+/// @details The blocks are used to store the data of a file. Each block is a pointer to a block of
+/// data on the disk.
+inline constexpr UInt16 kOpenHeFSSliceCount = 0x10;
+
+inline constexpr UInt16 kOpenHeFSInvalidVID = 0xFFFF;
+
+namespace Kernel {
+/// @brief Access time type.
+/// @details Used to keep track of the INode, INodeDir allocation status.
+typedef UInt64 ATime;
+
+/// @brief OpenHeFS Boot node.
+/// @details Acts like a superblock, it contains the information about the filesystem.
+/// @note The boot node is the first block of the filesystem.
+struct PACKED HEFS_BOOT_NODE final {
+ Char fMagic[kOpenHeFSMagicLen]; /// @brief Magic number of the filesystem.
+ Utf8Char fVolName[kOpenHeFSPartNameLen]; /// @brief Volume name.
+ UInt32 fVersion; /// @brief Version of the filesystem.
+ UInt64 fBadSectors; /// @brief Number of bad sectors in the filesystem.
+ UInt64 fSectorCount; /// @brief Number of sectors in the filesystem.
+ UInt64 fSectorSize; /// @brief Size of the sector.
+ UInt32 fChecksum; /// @brief Checksum of the boot node.
+ UInt8 fDiskKind; /// @brief Kind of the drive. (Hard Drive, Solid State Drive, Optical
+ /// Drive, etc).
+ UInt8 fEncoding; /// @brief Encoding of the filesystem. (UTF-8, UTF-16, etc).
+ UInt64 fStartIND; /// @brief Start of the INode directory tree.
+ UInt64 fEndIND; /// @brief End of the INode directory tree.
+ UInt64 fINDCount; /// @brief Number of leafs in the INode tree.
+ UInt64 fDiskSize; /// @brief Size of the disk. (Could be a virtual size, that is not the
+ /// real size of the disk.)
+ UInt16 fDiskStatus; /// @brief Status of the disk. (locked, unlocked, error, invalid).
+ UInt16 fDiskFlags; /// @brief Flags of the disk. (read-only, read-write, etc).
+ UInt16 fVID; /// @brief Virtual Identification Number within an EPM disk. (0xFFFF if not used).
+ UInt64 fStartIN; /// @brief Start INodes range
+ UInt64 fEndIN; /// @brief End INodes range
+ UInt64 fStartBlock; /// @brief Start Blocks range
+ UInt64 fEndBlock; /// @brief End Blocks range
+ UInt64 fJournalLBA; /// @brief Boot Node's COW journal LBA.
+ Char fPad[264];
+};
+
+inline constexpr ATime kOpenHeFSTimeInvalid = 0x0000000000000000;
+inline constexpr ATime kOpenHeFSTimeMax = 0xFFFFFFFFFFFFFFFF - 1;
+
+/// @brief Journal Node structure
+/// @param fHashPath target hash path
+/// @param fStatus target status
+/// @param fCopyElem copy of element
+/// @param fCopyKind kind of element
+struct PACKED HEFS_JOURNAL_NODE {
+ UInt64 fHashPath;
+ UInt64 fStatus;
+ UInt64 fCopyElem;
+ UInt8 fCopyKind;
+ UInt8 fPad[487];
+};
+
+/// @brief This enum defines the opcode of the journal, here mentioned as 'kinds'
+enum HeFSJournalKind : UInt8 {
+ kJournalKindInvalid = 0x00,
+ kJournalKindWrite = 0x01,
+ kJournalKindRename = 0x02,
+ kJournalKindDelete = 0x03,
+ kJournalKindFlagEdit = 0x04,
+ kJournalKindCreate = 0x05,
+ kJournalKindCount,
+};
+
+/// @brief OpenHeFS index node.
+/// @details This structure is used to store the file information of a file.
+/// @note The index node is a special type of INode that contains the file information.
+/// @note The index node is used to store the file information of a file.
+struct PACKED HEFS_INDEX_NODE final {
+ UInt64 fHashPath; /// @brief File name.
+ UInt32 fFlags; /// @brief File flags.
+ UInt16 fKind; /// @brief File kind. (Regular, Directory, Block, Character, FIFO, Socket,
+ /// Symbolic Link, Unknown).
+ UInt32 fSize; /// @brief File size.
+ UInt32 fChecksum; /// @brief Checksum.
+
+ Boolean fSymLink; /// @brief Is this a symbolic link? (if yes, the fName is the path to
+ /// the file and blocklinkstart and end contains it's inodes.)
+
+ ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps.
+ UInt32 fUID, fGID; /// @brief User ID and Group ID of the file.
+ UInt32 fMode; /// @brief File mode. (read, write, execute, etc).
+
+ /// @brief Extents system by using blocks
+ /// @details Using an offset to ask fBase, and fLength to compute each slice's length.
+ UInt32 fOffsetSliceLow;
+ UInt32 fOffsetSliceHigh;
+
+ Char fPad[437];
+};
+
+enum {
+ kOpenHeFSInvalidColor = 0,
+ kOpenHeFSRed = 100,
+ kOpenHeFSBlack,
+ kOpenHeFSColorCount,
+};
+
+/// @brief OpenHeFS directory node.
+/// @details This structure is used to store the directory information of a file.
+/// @note The directory node is a special type of INode that contains the directory entries.
+struct PACKED HEFS_INDEX_NODE_DIRECTORY final {
+ UInt64 fHashPath; /// @brief Directory path as FNV hash.
+
+ UInt32 fFlags; /// @brief File flags.
+ UInt16 fReserved; /// @note Reserved for future use.
+ UInt32 fEntryCount; /// @brief Entry Count of this directory inode.
+ UInt32 fChecksum; /// @brief Checksum of the file, index node checksum.
+
+ ATime fCreated, fAccessed, fModified,
+ fDeleted; /// @brief File timestamps and allocation status.
+ UInt32 fUID, fGID; /// @brief User ID and Group ID of the file.
+ UInt32 fMode; /// @brief File mode. (read, write, execute, etc).
+
+ /// @note These slices are organized as:
+ /// [0] = OFFSET
+ /// [1] = SIZE
+ /// @note Thus the += 2 when iterating over them.
+ UInt64 fINSlices[kOpenHeFSSliceCount]; /// @brief Start of the index node.
+
+ UInt8 fColor; /// @brief Color of the node. (Red or Black).
+ Lba fNext, fPrev, fChild, fParent; /// @brief Red-black tree pointers.
+
+ Char fPad[285];
+};
+} // namespace Kernel
+
+namespace Kernel::Detail {
+/// @brief OpenHeFS get year from ATime.
+/// @param raw_atime the raw ATime value.
+/// @return the year value.
+/// @note The year is stored in the upper 32 bits of the ATime value.
+inline UInt32 hefs_year_get(ATime raw_atime) noexcept {
+ return (raw_atime) >> 32;
+}
+
+/// @brief OpenHeFS get month from ATime.
+/// @param raw_atime the raw ATime value.
+/// @return the month value.
+/// @note The month is stored in the upper 24 bits of the ATime value.
+inline UInt32 hefs_month_get(ATime raw_atime) noexcept {
+ return (raw_atime) >> 24;
+}
+
+/// @brief OpenHeFS get day from ATime.
+/// @param raw_atime the raw ATime value.
+/// @return the day value.
+/// @note The day is stored in the upper 16 bits of the ATime value.
+inline UInt32 hefs_day_get(ATime raw_atime) noexcept {
+ return (raw_atime) >> 16;
+}
+
+/// @brief OpenHeFS get hour from ATime.
+/// @param raw_atime the raw ATime value.
+/// @return the hour value.
+/// @note The hour is stored in the upper 8 bits of the ATime value.
+inline UInt32 hefs_hour_get(ATime raw_atime) noexcept {
+ return (raw_atime) >> 8;
+}
+
+/// @brief OpenHeFS get minute from ATime.
+/// @param raw_atime the raw ATime value.
+/// @return the minute value.
+/// @note The minute is stored in the lower 8 bits of the ATime value.
+inline UInt32 hefs_minute_get(ATime raw_atime) noexcept {
+ return (raw_atime) &0xFF;
+}
+
+inline constexpr UInt32 kOpenHeFSBaseYear = 1970;
+inline constexpr UInt32 kOpenHeFSBaseMonth = 1;
+inline constexpr UInt32 kOpenHeFSBaseDay = 1;
+inline constexpr UInt32 kOpenHeFSBaseHour = 0;
+inline constexpr UInt32 kOpenHeFSBaseMinute = 0;
+
+inline const Char* hefs_status_to_string(UInt16 status) noexcept {
+ switch (status) {
+ case kOpenHeFSStatusUnlocked:
+ return "Unlocked";
+ case kOpenHeFSStatusLocked:
+ return "Locked";
+ case kOpenHeFSStatusError:
+ return "Error";
+ case kOpenHeFSStatusInvalid:
+ return "Invalid";
+ default:
+ return "Unknown";
+ }
+}
+
+inline const Char* hefs_drive_kind_to_string(UInt8 kind) noexcept {
+ switch (kind) {
+ case kOpenHeFSHardDrive:
+ return "Hard Drive";
+ case kOpenHeFSSolidStateDrive:
+ return "Solid State Drive";
+ case kOpenHeFSOpticalDrive:
+ return "Optical Drive";
+ case kOpenHeFSMassStorageDevice:
+ return "Mass Storage Device";
+ case kOpenHeFSScsiDrive:
+ return "SCSI/SAS Drive";
+ case kOpenHeFSFlashDrive:
+ return "Flash Drive";
+ case kOpenHeFSUnknown:
+ default:
+ return "Unknown";
+ }
+}
+
+inline const Char* hefs_encoding_to_string(UInt8 encoding) noexcept {
+ switch (encoding) {
+ case kOpenHeFSEncodingFlagsUTF8:
+ return "UTF-8";
+ case kOpenHeFSEncodingFlagsUTF16:
+ return "UTF-16";
+ case kOpenHeFSEncodingFlagsUTF32:
+ return "UTF-32";
+ case kOpenHeFSEncodingFlagsUTF16BE:
+ return "UTF-16BE";
+ case kOpenHeFSEncodingFlagsUTF16LE:
+ return "UTF-16LE";
+ case kOpenHeFSEncodingFlagsUTF32BE:
+ return "UTF-32BE";
+ case kOpenHeFSEncodingFlagsUTF32LE:
+ return "UTF-32LE";
+ case kOpenHeFSEncodingFlagsUTF8BE:
+ return "UTF-8BE";
+ case kOpenHeFSEncodingFlagsUTF8LE:
+ return "UTF-8LE";
+ default:
+ return "Unknown";
+ }
+}
+
+inline const Char* hefs_file_kind_to_string(UInt16 kind) noexcept {
+ switch (kind) {
+ case kOpenHeFSFileKindRegular:
+ return "Regular File";
+ case kOpenHeFSFileKindDirectory:
+ return "Directory";
+ case kOpenHeFSFileKindBlock:
+ return "Block Device";
+ case kOpenHeFSFileKindCharacter:
+ return "Character Device";
+ case kOpenHeFSFileKindFIFO:
+ return "FIFO";
+ case kOpenHeFSFileKindSocket:
+ return "Socket";
+ case kOpenHeFSFileKindSymbolicLink:
+ return "Symbolic Link";
+ case kOpenHeFSFileKindUnknown:
+ default:
+ return "Unknown";
+ }
+}
+
+inline const Char* hefs_file_flags_to_string(UInt32 flags) noexcept {
+ switch (flags) {
+ case kOpenHeFSFlagsNone:
+ return "No Flags";
+ case kOpenHeFSFlagsReadOnly:
+ return "Read Only";
+ case kOpenHeFSFlagsHidden:
+ return "Hidden";
+ case kOpenHeFSFlagsSystem:
+ return "System";
+ case kOpenHeFSFlagsArchive:
+ return "Archive";
+ case kOpenHeFSFlagsDevice:
+ return "Device";
+ default:
+ return "Unknown";
+ }
+}
+} // namespace Kernel::Detail
+
+namespace Kernel {
+/// @brief OpenHeFS filesystem parser class.
+/// @details This class is used to parse the OpenHeFS filesystem.
+class HeFileSystemParser final {
+ public:
+ HeFileSystemParser() = default;
+ ~HeFileSystemParser() = default;
+
+ public:
+ HeFileSystemParser(const HeFileSystemParser&) = delete;
+ HeFileSystemParser& operator=(const HeFileSystemParser&) = delete;
+
+ HeFileSystemParser(HeFileSystemParser&&) = delete;
+ HeFileSystemParser& operator=(HeFileSystemParser&&) = delete;
+
+ public:
+ /// @brief Make a EPM+OpenHeFS 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 Int32 flags,
+ const Utf8Char* part_name);
+
+ _Output Bool CreateINodeDirectory(_Input DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* dir);
+
+ _Output Bool RemoveINodeDirectory(_Input DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* dir);
+
+ _Output Bool CreateINode(_Input DriveTrait* drive, _Input const Int32 flags, const Utf8Char* dir,
+ const Utf8Char* name, const UInt8 kind);
+
+ _Output Bool DeleteINode(_Input DriveTrait* drive, _Input const Int32 flags, const Utf8Char* dir,
+ const Utf8Char* name, const UInt8 kind);
+
+ _Output Bool INodeManip(_Input DriveTrait* drive, VoidPtr block, SizeT block_sz,
+ const Utf8Char* dir, const Utf8Char* name, const UInt8 kind,
+ const BOOL input);
+
+ private:
+ _Output Bool INodeCtlManip(_Input DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* dir, const Utf8Char* name, const BOOL delete_or_create,
+ const UInt8 kind);
+
+ _Output Bool INodeDirectoryCtlManip(_Input DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* dir, const BOOL delete_or_create);
+};
+
+namespace OpenHeFS {
+
+ /// @brief Initialize OpenHeFS inside the main disk.
+ /// @return Whether it successfuly formated it or not.
+ Boolean fs_init_openhefs(Void) noexcept;
+} // namespace OpenHeFS
+} // namespace Kernel
|
