Luna/kernel/src/fs/ext2/FileSystem.h

158 lines
3.8 KiB
C
Raw Normal View History

#pragma once
#include "fs/VFS.h"
#include "fs/devices/DeviceRegistry.h"
#include <luna/HashMap.h>
#define EXT2_MAGIC 0xef53
namespace Ext2
{
struct [[gnu::packed]] Superblock
{
u32 nr_inodes;
u32 nr_blocks;
u32 nr_reserved_blocks;
u32 nr_free_blocks;
u32 nr_free_inodes;
u32 first_data_block;
u32 log_block_size;
u32 log_fragment_size;
u32 blocks_per_block_group;
u32 fragments_per_block_group;
u32 inodes_per_block_group;
u32 last_mount_time;
u32 last_write_time;
u16 mounts_since_last_fsck;
u16 mounts_allowed_before_fsck;
u16 signature;
u16 fs_state;
u16 error_action;
u16 minor_version;
u32 last_fsck_time;
u32 fsck_time_interval;
u32 os_id;
u32 major_version;
u16 reserved_block_uid;
u16 reserved_block_gid;
// TODO: Add extended superblock fields.
u8 padding[1024 - 84];
};
struct [[gnu::packed]] BlockGroupDescriptor
{
u32 block_usage_addr;
u32 inode_usage_addr;
u32 inode_table_start;
u16 nr_free_blocks;
u16 nr_free_inodes;
u16 nr_directories;
u8 padding[32 - 18];
};
struct [[gnu::packed]] RawInode
{
u16 mode;
u16 uid;
u32 size_low;
u32 atime;
u32 create_time;
u32 mtime;
u32 delete_time;
u16 gid;
u16 nlinks;
u32 sectors_used;
u32 flags;
u32 os_specific_1;
u32 direct_pointers[12];
u32 singly_indirect_ptr;
u32 doubly_indirect_ptr;
u32 triply_indirect_ptr;
u32 gen_number;
u32 extended_attrs;
u32 size_high;
u32 frag_addr;
u32 os_specific_2[3];
};
static_assert(sizeof(Superblock) == 1024);
static_assert(sizeof(BlockGroupDescriptor) == 32);
static_assert(sizeof(RawInode) == 128);
2023-06-22 16:34:22 +02:00
class Inode;
class FileSystem : public VFS::FileSystem
{
public:
SharedPtr<VFS::Inode> root_inode() const override
{
return m_root_inode;
}
Result<SharedPtr<VFS::Inode>> create_file_inode() override
{
return err(EROFS);
}
Result<SharedPtr<VFS::Inode>> create_dir_inode(SharedPtr<VFS::Inode>) override
{
return err(EROFS);
}
Result<SharedPtr<VFS::Inode>> create_device_inode(u32, u32) override
{
return err(EROFS);
}
Result<SharedPtr<VFS::Inode>> create_symlink_inode(StringView) override
{
return err(EROFS);
}
Result<void> set_mount_dir(SharedPtr<VFS::Inode>) override
{
return {};
}
bool is_readonly() const override
{
return true;
}
static Result<SharedPtr<VFS::FileSystem>> create(SharedPtr<Device> host_device);
dev_t host_device_id() const override
{
return m_host_device_id;
}
Result<SharedPtr<VFS::Inode>> find_inode_by_number(ino_t inode);
Result<const BlockGroupDescriptor*> find_block_group_descriptor(u32 index);
virtual ~FileSystem() = default;
private:
FileSystem();
SharedPtr<VFS::Inode> m_root_inode;
SharedPtr<Device> m_host_device;
dev_t m_host_device_id;
Superblock m_superblock;
u64 m_block_size;
u64 m_block_groups;
// FIXME: This inode cache will keep all inodes in it alive despite having no other references to it, but we're
// not worrying about that as for now the filesystem implementation is read-only.
HashMap<ino_t, SharedPtr<VFS::Inode>> m_inode_cache;
HashMap<u32, BlockGroupDescriptor> m_block_group_descriptor_cache;
2023-06-22 16:34:22 +02:00
friend class Inode;
};
}