Kernel: Initial work on filesystem

We support now ext2 directory listing. File reading is not yet supported.
This commit is contained in:
Bananymous
2023-02-20 01:46:00 +02:00
parent 247f03c79e
commit 80006ea137
12 changed files with 867 additions and 103 deletions

View File

@@ -41,7 +41,7 @@ namespace Kernel
virtual uint32_t sector_size() const override { return m_sector_words * 2; }
virtual const char* type() const override { return "PATA"; }
virtual bool read(uint32_t lba, uint32_t sector_count, uint8_t* buffer) override;
virtual bool read_sectors(uint32_t lba, uint32_t sector_count, uint8_t* buffer) override;
protected:
virtual bool initialize() override;

View File

@@ -5,17 +5,40 @@
namespace Kernel
{
struct GUID
{
uint32_t data1;
uint16_t data2;
uint16_t data3;
uint8_t data4[8];
};
class DiskDevice
{
public:
struct Partition
{
uint8_t type_guid[16];
uint8_t guid[16];
uint64_t start_lba;
uint64_t end_lba;
uint64_t attributes;
char name[72];
Partition(DiskDevice&, const GUID&, const GUID&, uint64_t, uint64_t, uint64_t, const char*);
const GUID& type() const { return m_type; }
const GUID& guid() const { return m_guid; }
uint64_t lba_start() const { return m_lba_start; }
uint64_t lba_end() const { return m_lba_end; }
uint64_t attributes() const { return m_attributes; }
const char* name() const { return m_name; }
const DiskDevice& device() const { return m_device; }
bool read_sectors(uint32_t lba, uint32_t sector_count, uint8_t* buffer);
bool is_used() const { uint8_t zero[16] {}; return memcmp(&m_type, zero, 16); }
private:
DiskDevice& m_device;
const GUID m_type;
const GUID m_guid;
const uint64_t m_lba_start;
const uint64_t m_lba_end;
const uint64_t m_attributes;
char m_name[72];
};
public:
@@ -24,9 +47,11 @@ namespace Kernel
virtual bool initialize() = 0;
bool initialize_partitions();
virtual bool read(uint32_t lba, uint32_t sector_count, uint8_t* buffer) = 0;
virtual bool read_sectors(uint32_t lba, uint32_t sector_count, uint8_t* buffer) = 0;
virtual uint32_t sector_size() const = 0;
BAN::Vector<Partition>& partitions() { return m_partitions; }
private:
BAN::Vector<Partition> m_partitions;
};
@@ -39,6 +64,7 @@ namespace Kernel
private:
DiskIO();
void try_add_device(DiskDevice*);
private:
BAN::Vector<DiskDevice*> m_devices;

View File

@@ -0,0 +1,188 @@
#pragma once
#include <BAN/String.h>
#include <kernel/DiskIO.h>
#include <kernel/FS/FileSystem.h>
namespace Kernel
{
namespace Ext2
{
struct Superblock
{
uint32_t inodes_count;
uint32_t blocks_count;
uint32_t r_blocks_count;
uint32_t free_blocks_count;
uint32_t free_inodes_count;
uint32_t first_data_block;
uint32_t log_block_size;
uint32_t log_frag_size;
uint32_t blocks_per_group;
uint32_t frags_per_group;
uint32_t inodes_per_group;
uint32_t mtime;
uint32_t wtime;
uint16_t mnt_count;
uint16_t max_mnt_count;
uint16_t magic;
uint16_t state;
uint16_t errors;
uint16_t minor_rev_level;
uint32_t lastcheck;
uint32_t checkinterval;
uint32_t creator_os;
uint32_t rev_level;
uint16_t def_resuid;
uint16_t def_resgid;
// -- EXT2_DYNAMIC_REV Specific --
uint8_t __extension_start[0];
uint32_t first_ino;
uint16_t inode_size;
uint16_t block_group_nr;
uint32_t feature_compat;
uint32_t feature_incompat;
uint32_t feature_ro_compat;
uint8_t uuid[16];
uint8_t volume_name[16];
char last_mounted[64];
uint32_t algo_bitmap;
// -- Performance Hints --
uint8_t s_prealloc_blocks;
uint8_t s_prealloc_dir_blocks;
uint16_t __alignment;
// -- Journaling Support --
uint8_t journal_uuid[16];
uint32_t journal_inum;
uint32_t journal_dev;
uint32_t last_orphan;
// -- Directory Indexing Support --
uint32_t hash_seed[4];
uint8_t def_hash_version;
uint8_t __padding[3];
// -- Other options --
uint32_t default_mount_options;
uint32_t first_meta_bg;
};
struct BlockGroupDescriptor
{
uint32_t block_bitmap;
uint32_t inode_bitmap;
uint32_t inode_table;
uint16_t free_blocks_count;
uint16_t free_inodes_count;
uint16_t used_dirs_count;
uint16_t __padding;
//uint8_t reserved[12];
};
struct Inode
{
uint16_t mode;
uint16_t uid;
uint32_t size;
uint32_t atime;
uint32_t ctime;
uint32_t mtime;
uint32_t dtime;
uint16_t gid;
uint16_t links_count;
uint32_t blocks;
uint32_t flags;
uint32_t osd1;
uint32_t block[15];
uint32_t generation;
uint32_t file_acl;
uint32_t dir_acl;
uint32_t faddr;
uint32_t osd2[3];
};
struct LinkedDirectoryEntry
{
uint32_t inode;
uint16_t rec_len;
uint8_t name_len;
uint8_t file_type;
char name[0];
};
}
class Ext2FS;
class Ext2Inode : public Inode
{
public:
virtual bool is_directory() const override;
virtual bool is_regular_file() const override;
virtual uint16_t uid() const override { return m_inode.uid; }
virtual uint16_t gid() const override { return m_inode.gid; }
virtual uint32_t size() const override { return m_inode.size; }
virtual BAN::StringView name() const override { return m_name; }
virtual BAN::ErrorOr<BAN::Vector<uint8_t>> read_all() const override;
virtual BAN::ErrorOr<BAN::Vector<BAN::RefCounted<Inode>>> directory_inodes() const override;
virtual BAN::ErrorOr<BAN::RefCounted<Inode>> directory_find(BAN::StringView) const override;
private:
Ext2Inode() {}
Ext2Inode(Ext2FS* fs, Ext2::Inode inode, BAN::StringView name)
: m_fs(fs)
, m_inode(inode)
, m_name(name)
{}
private:
Ext2FS* m_fs = nullptr;
Ext2::Inode m_inode;
BAN::String m_name;
friend class Ext2FS;
};
class Ext2FS : public FileSystem
{
public:
static BAN::ErrorOr<Ext2FS*> create(DiskDevice::Partition&);
virtual const BAN::RefCounted<Inode> root_inode() const override { return m_root_inode; }
private:
Ext2FS(DiskDevice::Partition& partition)
: m_partition(partition)
{}
BAN::ErrorOr<void> initialize_superblock();
BAN::ErrorOr<void> initialize_block_group_descriptors();
BAN::ErrorOr<void> initialize_root_inode();
BAN::ErrorOr<Ext2::Inode> read_inode(uint32_t);
BAN::ErrorOr<BAN::Vector<uint8_t>> read_block(uint32_t);
const Ext2::Superblock& superblock() const { return m_superblock; }
const Ext2::Inode& ext2_root_inode() const;
private:
DiskDevice::Partition& m_partition;
BAN::RefCounted<Inode> m_root_inode;
Ext2::Superblock m_superblock;
BAN::Vector<Ext2::BlockGroupDescriptor> m_block_group_descriptors;
friend class Ext2Inode;
};
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include <BAN/Memory.h>
#include <kernel/FS/Inode.h>
namespace Kernel
{
class FileSystem
{
public:
virtual const BAN::RefCounted<Inode> root_inode() const = 0;
};
}

View File

@@ -0,0 +1,28 @@
#pragma once
#include <BAN/ForwardList.h>
#include <BAN/Memory.h>
#include <stdint.h>
namespace Kernel
{
class Inode
{
public:
virtual bool is_directory() const = 0;
virtual bool is_regular_file() const = 0;
virtual uint16_t uid() const = 0;
virtual uint16_t gid() const = 0;
virtual uint32_t size() const = 0;
virtual BAN::StringView name() const = 0;
virtual BAN::ErrorOr<BAN::Vector<uint8_t>> read_all() const = 0;
virtual BAN::ErrorOr<BAN::Vector<BAN::RefCounted<Inode>>> directory_inodes() const = 0;
virtual BAN::ErrorOr<BAN::RefCounted<Inode>> directory_find(BAN::StringView) const = 0;
};
}

View File

@@ -0,0 +1,26 @@
#pragma once
#include <kernel/FS/FileSystem.h>
namespace Kernel
{
class VirtualFileSystem : public FileSystem
{
public:
static void initialize(BAN::RefCounted<Inode> root_inode);
static VirtualFileSystem& get();
static bool is_initialized();
virtual const BAN::RefCounted<Inode> root_inode() const override { return m_root_inode; }
private:
VirtualFileSystem(BAN::RefCounted<Inode> root_inode)
: m_root_inode(root_inode)
{}
private:
BAN::RefCounted<Inode> m_root_inode;
};
}