#pragma once #include "fs/tmpfs/FileSystem.h" #include #include #include #include #include namespace TmpFS { class FileInode : public VFS::FileInode { public: FileInode() = default; void set_fs(FileSystem& fs, Badge) { m_fs = &fs; } void set_inode_number(usize inum, Badge) { m_metadata.inum = inum; } VFS::FileSystem* fs() const override { return m_fs; } Result read(u8*, usize, usize) const override; Result write(const u8*, usize, usize) override; Result truncate(usize size) override; Result query_shared_memory(off_t offset, usize count) override; void did_link() override { m_metadata.nlinks++; } void did_unlink() override { m_metadata.nlinks--; } virtual ~FileInode() = default; private: VFS::FileSystem* m_fs; Buffer m_data_buffer; friend class FileSystem; }; class SymlinkInode : public VFS::FileInode { public: SymlinkInode() = default; VFS::InodeType type() const override { return VFS::InodeType::Symlink; } void set_fs(FileSystem& fs, Badge) { m_fs = &fs; } void set_inode_number(usize inum, Badge) { m_metadata.inum = inum; } Result set_link(StringView link, Badge) { m_link = TRY(String::from_string_view(link)); return {}; } VFS::FileSystem* fs() const override { return m_fs; } Result read(u8*, usize, usize) const override { return err(ENOTSUP); } Result write(const u8*, usize, usize) override { return err(ENOTSUP); } Result truncate(usize) override { return err(ENOTSUP); } void did_link() override { m_metadata.nlinks++; } void did_unlink() override { m_metadata.nlinks--; } Result readlink() override { return m_link.view(); } virtual ~SymlinkInode() = default; private: VFS::FileSystem* m_fs; String m_link; friend class FileSystem; }; class DeviceInode : public VFS::DeviceInode { public: DeviceInode() = default; VFS::InodeType type() const override { return m_device->is_block_device() ? VFS::InodeType::BlockDevice : VFS::InodeType::CharacterDevice; } void set_fs(FileSystem& fs, Badge) { m_fs = &fs; } void set_inode_number(usize inum, Badge) { m_metadata.inum = inum; } void set_device(SharedPtr device, Badge) { m_device = device; } void set_device_id(dev_t id, Badge) { m_metadata.devid = id; } Result query_shared_memory(off_t offset, usize count) override { return m_device->query_shared_memory(offset, count); } VFS::FileSystem* fs() const override { return m_fs; } Result read(u8* buf, usize offset, usize length) const override { return m_device->read(buf, offset, length); } Result write(const u8* buf, usize offset, usize length) override { return m_device->write(buf, offset, length); } Result truncate(usize) override { // POSIX says truncate is for regular files, but doesn't tell us what error to return for non-regular files. return err(EINVAL); } Result ioctl(int request, void* arg) override { return m_device->ioctl(request, arg); } Result isatty() const override { return m_device->isatty(); } bool will_block_if_read() const override { return m_device->will_block_if_read(); } void did_link() override { m_metadata.nlinks++; } void did_unlink() override { m_metadata.nlinks--; } virtual ~DeviceInode() = default; private: VFS::FileSystem* m_fs; SharedPtr m_device; friend class FileSystem; }; class DirInode : public VFS::Inode { public: DirInode() = default; void set_fs(FileSystem& fs, Badge) { m_fs = &fs; } void set_inode_number(usize inum, Badge) { m_metadata.inum = inum; } void set_self(SharedPtr self, Badge) { m_self = self; } Result> find(const char* name) const override; Option get(usize index) const override; Result read(u8*, usize, usize) const override { return err(EISDIR); } Result write(const u8*, usize, usize) override { return err(EISDIR); } Result truncate(usize) override { return err(EISDIR); } bool will_block_if_read() const override { return false; } VFS::FileSystem* fs() const override { return m_fs; } VFS::InodeType type() const override { return VFS::InodeType::Directory; } void did_link() override { } void did_unlink() override { m_self = {}; m_entries.clear(); } usize entries() const override { return m_entries.size(); } Result remove_entry(const char* name) override; Result> create_file(const char* name, mode_t mode) override; Result> create_subdirectory(const char* name, mode_t mode) override; Result add_entry(SharedPtr inode, const char* name); Result replace_entry(SharedPtr inode, const char* name); virtual ~DirInode() = default; private: VFS::FileSystem* m_fs; SharedPtr m_self; Vector m_entries; friend class FileSystem; }; }