#pragma once #include "fs/VFS.h" #include "fs/devices/DeviceRegistry.h" #include #define EXT2_MAGIC 0xef53 namespace Ext2 { struct [[gnu::packed]] Superblock { u32 nr_inodes; u32 nr_blocks; u32 nr_reserved; u32 nr_free_inodes; u32 nr_free_blocks; u32 superblock_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; u8 padding[1024 - 84]; }; static_assert(sizeof(Superblock) == 1024); class FileSystem : public VFS::FileSystem { public: SharedPtr root_inode() const override { return m_root_inode; } Result> create_file_inode() override { return err(EROFS); } Result> create_dir_inode(SharedPtr) override { return err(EROFS); } Result> create_device_inode(u32, u32) override { return err(EROFS); } Result> create_symlink_inode(StringView) override { return err(EROFS); } Result set_mount_dir(SharedPtr) override { return {}; } static Result> create(SharedPtr host_device); dev_t host_device_id() const override { return m_host_device_id; } Result> find_inode_by_number(ino_t inode); virtual ~FileSystem() = default; private: FileSystem(); SharedPtr m_root_inode; SharedPtr m_host_device; dev_t m_host_device_id; Superblock m_superblock; // 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> m_inode_cache; }; }