2023-02-03 21:18:52 +00:00
|
|
|
#pragma once
|
|
|
|
#include "fs/VFS.h"
|
2023-03-18 08:10:33 +00:00
|
|
|
#include "fs/devices/DeviceRegistry.h"
|
2023-02-25 17:06:23 +00:00
|
|
|
#include <luna/Atomic.h>
|
2023-02-03 21:18:52 +00:00
|
|
|
#include <luna/Badge.h>
|
2023-03-10 23:52:39 +00:00
|
|
|
#include <luna/Buffer.h>
|
2023-02-27 14:14:07 +00:00
|
|
|
#include <luna/StaticString.h>
|
2023-02-03 21:18:52 +00:00
|
|
|
#include <luna/Vector.h>
|
|
|
|
|
|
|
|
namespace TmpFS
|
|
|
|
{
|
|
|
|
class FileSystem : public VFS::FileSystem
|
|
|
|
{
|
|
|
|
public:
|
2023-03-10 21:18:48 +00:00
|
|
|
SharedPtr<VFS::Inode> root_inode() const override
|
2023-02-03 21:18:52 +00:00
|
|
|
{
|
2023-03-10 21:18:48 +00:00
|
|
|
return m_root_inode;
|
2023-02-03 21:18:52 +00:00
|
|
|
}
|
|
|
|
|
2023-02-25 17:03:11 +00:00
|
|
|
Result<SharedPtr<VFS::Inode>> create_file_inode() override;
|
2023-02-27 14:04:29 +00:00
|
|
|
Result<SharedPtr<VFS::Inode>> create_dir_inode(SharedPtr<VFS::Inode> parent) override;
|
2023-03-18 08:10:33 +00:00
|
|
|
Result<SharedPtr<VFS::Inode>> create_device_inode(u32 major, u32 minor) override;
|
2023-02-25 17:03:11 +00:00
|
|
|
|
2023-02-03 21:18:52 +00:00
|
|
|
static Result<SharedPtr<VFS::FileSystem>> create();
|
|
|
|
|
|
|
|
virtual ~FileSystem() = default;
|
|
|
|
|
|
|
|
private:
|
2023-02-25 17:03:11 +00:00
|
|
|
FileSystem() = default;
|
2023-02-03 21:18:52 +00:00
|
|
|
|
2023-02-25 17:03:11 +00:00
|
|
|
void set_root(SharedPtr<VFS::Inode> root);
|
2023-02-03 21:18:52 +00:00
|
|
|
|
|
|
|
SharedPtr<VFS::Inode> m_root_inode;
|
2023-02-25 17:03:11 +00:00
|
|
|
|
2023-02-25 17:06:23 +00:00
|
|
|
Atomic<usize> m_next_inode_number { 2 };
|
2023-02-03 21:18:52 +00:00
|
|
|
};
|
|
|
|
|
2023-02-25 17:11:39 +00:00
|
|
|
class FileInode : public VFS::FileInode
|
2023-02-03 21:18:52 +00:00
|
|
|
{
|
|
|
|
public:
|
2023-02-25 17:11:39 +00:00
|
|
|
FileInode() = default;
|
2023-02-25 17:03:11 +00:00
|
|
|
|
|
|
|
void set_fs(FileSystem& fs, Badge<FileSystem>)
|
|
|
|
{
|
|
|
|
m_fs = &fs;
|
|
|
|
}
|
2023-02-03 21:18:52 +00:00
|
|
|
|
2023-02-25 17:03:11 +00:00
|
|
|
void set_inode_number(usize inum, Badge<FileSystem>)
|
|
|
|
{
|
|
|
|
m_inode_number = inum;
|
|
|
|
}
|
2023-02-03 21:18:52 +00:00
|
|
|
|
|
|
|
VFS::FileSystem& fs() const override
|
|
|
|
{
|
|
|
|
return *m_fs;
|
|
|
|
}
|
|
|
|
|
2023-02-25 17:03:11 +00:00
|
|
|
usize inode_number() const override
|
|
|
|
{
|
|
|
|
return m_inode_number;
|
|
|
|
}
|
|
|
|
|
2023-03-10 23:52:39 +00:00
|
|
|
Result<usize> read(u8*, usize, usize) const override;
|
|
|
|
|
|
|
|
Result<usize> write(const u8*, usize, usize) override;
|
|
|
|
|
2023-03-12 13:43:58 +00:00
|
|
|
Result<void> truncate(usize size) override;
|
|
|
|
|
2023-03-12 13:49:21 +00:00
|
|
|
usize size() override;
|
|
|
|
|
2023-03-12 15:55:46 +00:00
|
|
|
mode_t mode() override
|
|
|
|
{
|
|
|
|
return m_mode;
|
|
|
|
}
|
|
|
|
|
|
|
|
Result<void> chmod(mode_t mode) override
|
|
|
|
{
|
|
|
|
m_mode = mode;
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2023-02-25 17:11:39 +00:00
|
|
|
virtual ~FileInode() = default;
|
2023-02-03 21:18:52 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
VFS::FileSystem* m_fs;
|
2023-03-10 23:52:39 +00:00
|
|
|
Buffer m_data_buffer;
|
2023-02-25 17:03:11 +00:00
|
|
|
usize m_inode_number;
|
2023-03-18 08:10:33 +00:00
|
|
|
mode_t m_mode;
|
|
|
|
};
|
|
|
|
|
|
|
|
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-03-19 10:21:50 +00:00
|
|
|
bool blocking() const override
|
|
|
|
{
|
|
|
|
return m_device->blocking();
|
|
|
|
}
|
|
|
|
|
2023-03-18 08:10:33 +00:00
|
|
|
usize size() override
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
mode_t mode() override
|
|
|
|
{
|
|
|
|
return m_mode;
|
|
|
|
}
|
|
|
|
|
|
|
|
Result<void> chmod(mode_t mode) override
|
|
|
|
{
|
|
|
|
m_mode = mode;
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2023-02-03 21:18:52 +00:00
|
|
|
};
|
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;
|
|
|
|
}
|
|
|
|
|
2023-03-10 20:09:08 +00:00
|
|
|
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;
|
2023-03-28 19:15:26 +00:00
|
|
|
Option<VFS::DirectoryEntry> get(usize index) const override;
|
2023-02-25 18:06:50 +00:00
|
|
|
|
2023-03-10 23:52:39 +00:00
|
|
|
Result<usize> read(u8*, usize, usize) const override
|
|
|
|
{
|
|
|
|
return err(EISDIR);
|
|
|
|
}
|
|
|
|
|
|
|
|
Result<usize> write(const u8*, usize, usize) override
|
|
|
|
{
|
|
|
|
return err(EISDIR);
|
|
|
|
}
|
|
|
|
|
2023-03-12 13:43:58 +00:00
|
|
|
Result<void> truncate(usize) override
|
|
|
|
{
|
|
|
|
return err(EISDIR);
|
|
|
|
}
|
|
|
|
|
2023-03-19 10:21:50 +00:00
|
|
|
bool blocking() const override
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2023-03-12 13:49:21 +00:00
|
|
|
usize size() override
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-03-12 15:55:46 +00:00
|
|
|
mode_t mode() override
|
|
|
|
{
|
|
|
|
return m_mode;
|
|
|
|
}
|
|
|
|
|
|
|
|
Result<void> chmod(mode_t mode) override
|
|
|
|
{
|
|
|
|
m_mode = mode;
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2023-02-25 18:06:50 +00:00
|
|
|
VFS::FileSystem& fs() const override
|
|
|
|
{
|
|
|
|
return *m_fs;
|
|
|
|
}
|
|
|
|
|
|
|
|
usize inode_number() const override
|
|
|
|
{
|
|
|
|
return m_inode_number;
|
|
|
|
}
|
|
|
|
|
|
|
|
VFS::InodeType type() const override
|
|
|
|
{
|
|
|
|
return VFS::InodeType::Directory;
|
|
|
|
}
|
|
|
|
|
2023-02-25 18:22:05 +00:00
|
|
|
Result<SharedPtr<VFS::Inode>> create_file(const char* name) override;
|
2023-03-10 20:09:08 +00:00
|
|
|
Result<SharedPtr<VFS::Inode>> create_subdirectory(const char* name) override;
|
2023-02-25 18:22:05 +00:00
|
|
|
|
|
|
|
Result<void> add_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;
|
2023-02-25 18:22:05 +00:00
|
|
|
|
2023-03-10 20:09:08 +00:00
|
|
|
SharedPtr<VFS::Inode> m_self;
|
|
|
|
|
2023-03-28 19:15:26 +00:00
|
|
|
Vector<VFS::DirectoryEntry> m_entries;
|
2023-02-25 18:06:50 +00:00
|
|
|
};
|
2023-02-03 21:18:52 +00:00
|
|
|
}
|