summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/FSKit
diff options
context:
space:
mode:
Diffstat (limited to 'dev/kernel/FSKit')
-rw-r--r--dev/kernel/FSKit/Ext2.h202
-rw-r--r--dev/kernel/FSKit/Ext2IFS.h186
2 files changed, 195 insertions, 193 deletions
diff --git a/dev/kernel/FSKit/Ext2.h b/dev/kernel/FSKit/Ext2.h
index 42875c47..06370a8c 100644
--- a/dev/kernel/FSKit/Ext2.h
+++ b/dev/kernel/FSKit/Ext2.h
@@ -18,126 +18,126 @@
namespace Ext2 {
/// EXT2 Constants
-#define kExt2FSMagic (0xEF53)
-#define kExt2FSMaxFileNameLen (255U)
-#define kExt2FSSuperblockOffset (1024)
-#define kExt2FSRootInodeNumber (2)
-#define kExt2FSInodeSize (128U)
-#define kExt2FSBlockSizeBase (1024U)
+#define kExt2FSMagic (0xEF53)
+#define kExt2FSMaxFileNameLen (255U)
+#define kExt2FSSuperblockOffset (1024)
+#define kExt2FSRootInodeNumber (2)
+#define kExt2FSInodeSize (128U)
+#define kExt2FSBlockSizeBase (1024U)
-#define kExt2FSRev0 (0)
-#define kExt2FSRev1 (1)
+#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
+ kExt2FileTypeUnknown = 0,
+ kExt2FileTypeRegular = 1,
+ kExt2FileTypeDirectory = 2,
+ kExt2FileTypeCharDevice = 3,
+ kExt2FileTypeBlockDevice = 4,
+ kExt2FileTypeFIFO = 5,
+ kExt2FileTypeSocket = 6,
+ kExt2FileTypeSymbolicLink = 7
};
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
+ 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];
+ 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];
+ 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};
+ Kernel::UInt32 inodeNumber;
+ EXT2_INODE inode;
+ Kernel::UInt32 cursor{0};
};
class Ext2FileSystemMgr;
-} // namespace Ext2
+} // namespace Ext2
diff --git a/dev/kernel/FSKit/Ext2IFS.h b/dev/kernel/FSKit/Ext2IFS.h
index 87095bc6..2550cfea 100644
--- a/dev/kernel/FSKit/Ext2IFS.h
+++ b/dev/kernel/FSKit/Ext2IFS.h
@@ -3,131 +3,133 @@
#include <FSKit/Ext2.h>
#include <KernelKit/DriveMgr.h>
#include <KernelKit/HeapMgr.h>
-#include <NeKit/Utils.h>
-#include <NeKit/KernelPanic.h>
+#include <KernelKit/KPC.h>
#include <NeKit/ErrorOr.h>
-#include <KernelKit/KPC.h>
+#include <NeKit/KernelPanic.h>
+#include <NeKit/Utils.h>
namespace Ext2 {
/// @brief Context for an EXT2 filesystem on a given drive
-struct Context {
- Kernel::DriveTrait* drive{nullptr};
- EXT2_SUPER_BLOCK* superblock{nullptr};
-
- /// @brief context with a drive
- explicit Context(Kernel::DriveTrait* drv) : drive(drv) {}
-
- /// @brief Clean up
- ~Context() {
- if (superblock) {
- Kernel::mm_free_ptr(superblock);
- superblock = nullptr;
- }
- }
-
- Context(const Context&) = delete;
- Context& operator=(const Context&) = delete;
-
- Context(Context&& other) noexcept : drive(other.drive), superblock(other.superblock) {
- other.drive = nullptr;
- other.superblock = nullptr;
+struct Context {
+ Kernel::DriveTrait* drive{nullptr};
+ EXT2_SUPER_BLOCK* superblock{nullptr};
+
+ /// @brief context with a drive
+ explicit Context(Kernel::DriveTrait* drv) : drive(drv) {}
+
+ /// @brief Clean up
+ ~Context() {
+ if (superblock) {
+ Kernel::mm_free_ptr(superblock);
+ superblock = nullptr;
}
-
- Context& operator=(Context&& 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;
+ }
+
+ Context(const Context&) = delete;
+ Context& operator=(const Context&) = delete;
+
+ Context(Context&& other) noexcept : drive(other.drive), superblock(other.superblock) {
+ other.drive = nullptr;
+ other.superblock = nullptr;
+ }
+
+ Context& operator=(Context&& 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;
+ }
- inline Kernel::UInt32 BlockSize() const {
- if (!superblock) return kExt2FSBlockSizeBase;
- return kExt2FSBlockSizeBase << superblock->fLogBlockSize;
- }
+ inline Kernel::UInt32 BlockSize() const {
+ if (!superblock) return kExt2FSBlockSizeBase;
+ return kExt2FSBlockSizeBase << superblock->fLogBlockSize;
+ }
};
-inline bool ext2_read_block(Kernel::DriveTrait* drv, Kernel::UInt32 lba, void* buffer, Kernel::UInt32 size) {
- if (!drv || !buffer) return false;
+inline bool ext2_read_block(Kernel::DriveTrait* drv, Kernel::UInt32 lba, void* 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;
+ 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 void* buffer, Kernel::UInt32 size) {
- if (!drv || !buffer) return false;
+inline bool ext2_write_block(Kernel::DriveTrait* drv, Kernel::UInt32 lba, const void* buffer,
+ Kernel::UInt32 size) {
+ if (!drv || !buffer) return false;
- Kernel::DriveTrait::DrivePacket pkt{};
- pkt.fPacketContent = const_cast<void*>(buffer);
- pkt.fPacketSize = size;
- pkt.fPacketLba = lba;
- drv->fOutput(pkt);
- return pkt.fPacketGood;
+ Kernel::DriveTrait::DrivePacket pkt{};
+ pkt.fPacketContent = const_cast<void*>(buffer);
+ pkt.fPacketSize = size;
+ pkt.fPacketLba = lba;
+ drv->fOutput(pkt);
+ return pkt.fPacketGood;
}
// Load superblock
inline Kernel::ErrorOr<EXT2_SUPER_BLOCK*> ext2_load_superblock(Context* ctx) {
- if (!ctx || !ctx->drive) return Kernel::ErrorOr<EXT2_SUPER_BLOCK*>(Kernel::kErrorInvalidData);
+ 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);
+ 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);
- }
+ 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);
- }
+ 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);
+ ctx->superblock = sb;
+ return Kernel::ErrorOr<EXT2_SUPER_BLOCK*>(sb);
}
// Load inode
-inline Kernel::ErrorOr<Ext2Node*> ext2_load_inode(Context* ctx, Kernel::UInt32 inodeNumber) {
- if (!ctx || !ctx->superblock) return Kernel::ErrorOr<Ext2Node*>(Kernel::kErrorInvalidData);
+inline Kernel::ErrorOr<Ext2Node*> ext2_load_inode(Context* 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 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;
+ 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;
- Kernel::UInt32 index = (inodeNumber - 1) % inodesPerGroup;
+ // Compute block group and index within group
+ Kernel::UInt32 inodesPerGroup = ctx->superblock->fInodesPerGroup;
+ Kernel::UInt32 group = (inodeNumber - 1) / inodesPerGroup;
+ Kernel::UInt32 index = (inodeNumber - 1) % inodesPerGroup;
- // dummy: just offset first inode
- Kernel::UInt32 inodeTableBlock = ctx->superblock->fFirstInode + group;
+ // 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);
- }
+ 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);
+ ext2Node->cursor = 0;
+ return Kernel::ErrorOr<Ext2Node*>(ext2Node);
}
inline Kernel::UInt32 inode_offset(const Context* ctx, Kernel::UInt32 inodeNumber) {
- if (!ctx || !ctx->superblock) return 0;
- return ((inodeNumber - 1) % ctx->superblock->fInodesPerGroup) * ctx->superblock->fInodeSize;
+ if (!ctx || !ctx->superblock) return 0;
+ return ((inodeNumber - 1) % ctx->superblock->fInodesPerGroup) * ctx->superblock->fInodeSize;
}
-} // namespace Ext2
+} // namespace Ext2