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

362 lines
7.7 KiB
C
Raw Normal View History

#pragma once
#include "fs/VFS.h"
#include "fs/devices/DeviceRegistry.h"
2023-02-25 17:06:23 +00:00
#include <luna/Atomic.h>
#include <luna/Badge.h>
#include <luna/Buffer.h>
#include <luna/StaticString.h>
#include <luna/Vector.h>
namespace TmpFS
{
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;
Result<SharedPtr<VFS::Inode>> create_dir_inode(SharedPtr<VFS::Inode> parent) override;
Result<SharedPtr<VFS::Inode>> create_device_inode(u32 major, u32 minor) override;
Result<void> set_mount_dir(SharedPtr<VFS::Inode> parent) override;
static Result<SharedPtr<VFS::FileSystem>> create();
virtual ~FileSystem() = default;
private:
FileSystem() = default;
void set_root(SharedPtr<VFS::Inode> root);
SharedPtr<VFS::Inode> m_root_inode;
2023-02-25 17:06:23 +00:00
Atomic<usize> m_next_inode_number { 2 };
};
class FileInode : public VFS::FileInode
{
public:
FileInode() = default;
void set_fs(FileSystem& fs, Badge<FileSystem>)
{
m_fs = &fs;
}
void set_inode_number(usize inum, Badge<FileSystem>)
{
m_inode_number = inum;
}
VFS::FileSystem* fs() const override
{
return m_fs;
}
usize inode_number() const override
{
return m_inode_number;
}
Result<usize> read(u8*, usize, usize) const override;
Result<usize> write(const u8*, usize, usize) override;
Result<void> truncate(usize size) override;
usize size() const override;
mode_t mode() const override
2023-03-12 15:55:46 +00:00
{
return m_mode;
}
u32 uid() const override
{
return m_uid;
}
u32 gid() const override
{
return m_gid;
}
2023-03-12 15:55:46 +00:00
Result<void> chmod(mode_t mode) override
{
m_mode = mode;
return {};
}
Result<void> chown(u32 uid, u32 gid) override
{
m_uid = uid;
m_gid = gid;
return {};
}
void did_link() override
{
m_nlinks++;
}
void did_unlink() override
{
m_nlinks--;
}
virtual ~FileInode() = default;
private:
VFS::FileSystem* m_fs;
Buffer m_data_buffer;
usize m_inode_number;
mode_t m_mode;
u32 m_uid { 0 };
u32 m_gid { 0 };
u32 m_nlinks { 0 };
};
class DeviceInode : public VFS::DeviceInode
{
public:
DeviceInode() = default;
void set_fs(FileSystem& fs, Badge<FileSystem>)
{
m_fs = &fs;
}
void set_inode_number(usize inum, Badge<FileSystem>)
{
m_inode_number = inum;
}
void set_device(SharedPtr<Device> device, Badge<FileSystem>)
{
m_device = device;
}
VFS::FileSystem* fs() const override
{
return m_fs;
}
usize inode_number() const override
{
return m_inode_number;
}
Result<usize> read(u8* buf, usize offset, usize length) const override
{
return m_device->read(buf, offset, length);
}
Result<usize> write(const u8* buf, usize offset, usize length) override
{
return m_device->write(buf, offset, length);
}
Result<void> 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);
}
2023-04-09 09:22:57 +00:00
Result<u64> ioctl(int request, void* arg) override
{
return m_device->ioctl(request, arg);
}
2023-03-19 10:21:50 +00:00
bool blocking() const override
{
return m_device->blocking();
}
usize size() const override
{
return m_device->size();
}
mode_t mode() const override
{
return m_mode;
}
u32 uid() const override
{
return m_uid;
}
u32 gid() const override
{
return m_gid;
}
Result<void> chmod(mode_t mode) override
{
m_mode = mode;
return {};
}
Result<void> chown(u32 uid, u32 gid) override
{
m_uid = uid;
m_gid = gid;
return {};
}
void did_link() override
{
m_nlinks++;
}
void did_unlink() override
{
m_nlinks--;
}
virtual ~DeviceInode() = default;
private:
VFS::FileSystem* m_fs;
SharedPtr<Device> m_device;
usize m_inode_number;
2023-03-12 15:55:46 +00:00
mode_t m_mode;
u32 m_uid { 0 };
u32 m_gid { 0 };
u32 m_nlinks { 0 };
};
2023-02-25 18:06:50 +00:00
class DirInode : public VFS::Inode
{
public:
DirInode() = default;
void set_fs(FileSystem& fs, Badge<FileSystem>)
{
m_fs = &fs;
}
void set_inode_number(usize inum, Badge<FileSystem>)
{
m_inode_number = inum;
}
void set_self(SharedPtr<VFS::Inode> self, Badge<FileSystem>)
{
m_self = self;
}
2023-02-25 18:06:50 +00:00
Result<SharedPtr<VFS::Inode>> find(const char* name) const override;
Option<VFS::DirectoryEntry> get(usize index) const override;
2023-02-25 18:06:50 +00:00
Result<usize> read(u8*, usize, usize) const override
{
return err(EISDIR);
}
Result<usize> write(const u8*, usize, usize) override
{
return err(EISDIR);
}
Result<void> truncate(usize) override
{
return err(EISDIR);
}
2023-03-19 10:21:50 +00:00
bool blocking() const override
{
return false;
}
usize size() const override
{
return 0;
}
mode_t mode() const override
2023-03-12 15:55:46 +00:00
{
return m_mode;
}
u32 uid() const override
{
return m_uid;
}
u32 gid() const override
{
return m_gid;
}
2023-03-12 15:55:46 +00:00
Result<void> chmod(mode_t mode) override
{
m_mode = mode;
return {};
}
Result<void> chown(u32 uid, u32 gid) override
{
m_uid = uid;
m_gid = gid;
return {};
}
VFS::FileSystem* fs() const override
2023-02-25 18:06:50 +00:00
{
return m_fs;
2023-02-25 18:06:50 +00:00
}
usize inode_number() const override
{
return m_inode_number;
}
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<void> remove_entry(const char* name) override;
Result<SharedPtr<VFS::Inode>> create_file(const char* name) override;
Result<SharedPtr<VFS::Inode>> create_subdirectory(const char* name) override;
Result<void> add_entry(SharedPtr<VFS::Inode> inode, const char* name);
Result<void> replace_entry(SharedPtr<VFS::Inode> inode, const char* name);
2023-02-25 18:06:50 +00:00
virtual ~DirInode() = default;
private:
VFS::FileSystem* m_fs;
usize m_inode_number;
2023-03-12 15:55:46 +00:00
mode_t m_mode;
u32 m_uid { 0 };
u32 m_gid { 0 };
SharedPtr<VFS::Inode> m_self;
Vector<VFS::DirectoryEntry> m_entries;
2023-02-25 18:06:50 +00:00
};
}