kernel: Move TmpFS::*Inode into a separate file
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
3a3473b9c2
commit
27d9cd0e87
@ -46,6 +46,7 @@ set(SOURCES
|
||||
src/fs/MBR.cpp
|
||||
src/fs/GPT.cpp
|
||||
src/fs/tmpfs/FileSystem.cpp
|
||||
src/fs/tmpfs/Inode.cpp
|
||||
src/fs/devices/DeviceRegistry.cpp
|
||||
src/fs/devices/NullDevice.cpp
|
||||
src/fs/devices/ZeroDevice.cpp
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "fs/tmpfs/FileSystem.h"
|
||||
#include "fs/Mount.h"
|
||||
#include "fs/devices/DeviceRegistry.h"
|
||||
#include "fs/tmpfs/Inode.h"
|
||||
#include <luna/Alloc.h>
|
||||
#include <luna/CString.h>
|
||||
#include <luna/Ignore.h>
|
||||
@ -76,131 +76,4 @@ namespace TmpFS
|
||||
{
|
||||
m_root_inode = root;
|
||||
}
|
||||
|
||||
Result<SharedPtr<VFS::Inode>> DirInode::find(const char* name) const
|
||||
{
|
||||
for (const auto& entry : m_entries)
|
||||
{
|
||||
if (!strcmp(name, entry.name.chars())) return entry.inode;
|
||||
}
|
||||
|
||||
return err(ENOENT);
|
||||
}
|
||||
|
||||
Result<void> DirInode::replace_entry(SharedPtr<VFS::Inode> inode, const char* name)
|
||||
{
|
||||
for (auto& entry : m_entries)
|
||||
{
|
||||
if (!strcmp(name, entry.name.chars()))
|
||||
{
|
||||
entry.inode = inode;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return err(ENOENT);
|
||||
}
|
||||
|
||||
Option<VFS::DirectoryEntry> DirInode::get(usize index) const
|
||||
{
|
||||
if (index >= m_entries.size()) return {};
|
||||
|
||||
return m_entries[index];
|
||||
}
|
||||
|
||||
Result<void> DirInode::add_entry(SharedPtr<VFS::Inode> inode, const char* name)
|
||||
{
|
||||
if (find(name).has_value()) return err(EEXIST);
|
||||
|
||||
VFS::DirectoryEntry entry { inode, name };
|
||||
|
||||
TRY(m_entries.try_append(move(entry)));
|
||||
|
||||
inode->did_link();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<void> DirInode::remove_entry(const char* name)
|
||||
{
|
||||
SharedPtr<VFS::Inode> inode = TRY(find(name));
|
||||
|
||||
if (inode->type() == VFS::InodeType::Directory && inode->entries() != 2) return err(ENOTEMPTY);
|
||||
|
||||
if (inode->is_mountpoint()) return err(EBUSY);
|
||||
|
||||
m_entries.remove_first_matching(
|
||||
[&](const VFS::DirectoryEntry& entry) { return !strcmp(entry.name.chars(), name); });
|
||||
|
||||
inode->did_unlink();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<SharedPtr<VFS::Inode>> DirInode::create_file(const char* name)
|
||||
{
|
||||
auto inode = TRY(m_fs->create_file_inode());
|
||||
|
||||
TRY(add_entry(inode, name));
|
||||
|
||||
return inode;
|
||||
}
|
||||
|
||||
Result<SharedPtr<VFS::Inode>> DirInode::create_subdirectory(const char* name)
|
||||
{
|
||||
auto inode = TRY(m_fs->create_dir_inode(m_self));
|
||||
|
||||
TRY(add_entry(inode, name));
|
||||
|
||||
return inode;
|
||||
}
|
||||
|
||||
Result<usize> FileInode::read(u8* buf, usize offset, usize length) const
|
||||
{
|
||||
if (length == 0) return 0;
|
||||
|
||||
if (offset > m_data_buffer.size()) return 0;
|
||||
if (offset + length > m_data_buffer.size()) length = m_data_buffer.size() - offset;
|
||||
|
||||
memcpy(buf, m_data_buffer.data() + offset, length);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
Result<usize> FileInode::write(const u8* buf, usize offset, usize length)
|
||||
{
|
||||
if (length == 0) return 0;
|
||||
|
||||
if (offset > m_data_buffer.size())
|
||||
{
|
||||
// Fill the in-between space with zeroes.
|
||||
usize old_size = m_data_buffer.size();
|
||||
usize zeroes = offset - old_size;
|
||||
|
||||
TRY(m_data_buffer.try_resize(offset));
|
||||
|
||||
memset(m_data_buffer.data() + old_size, 0, zeroes);
|
||||
}
|
||||
|
||||
u8* slice = TRY(m_data_buffer.slice(offset, length));
|
||||
memcpy(slice, buf, length);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
Result<void> FileInode::truncate(usize size)
|
||||
{
|
||||
usize old_size = m_data_buffer.size();
|
||||
|
||||
TRY(m_data_buffer.try_resize(size));
|
||||
|
||||
if (size > old_size) memset(m_data_buffer.data() + old_size, 0, size - old_size);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
usize FileInode::size() const
|
||||
{
|
||||
return m_data_buffer.size();
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,6 @@
|
||||
#include "fs/VFS.h"
|
||||
#include "fs/devices/DeviceRegistry.h"
|
||||
#include <luna/Atomic.h>
|
||||
#include <luna/Badge.h>
|
||||
#include <luna/Buffer.h>
|
||||
#include <luna/StaticString.h>
|
||||
#include <luna/String.h>
|
||||
#include <luna/Vector.h>
|
||||
|
||||
namespace TmpFS
|
||||
{
|
||||
@ -45,466 +40,4 @@ namespace TmpFS
|
||||
|
||||
dev_t m_host_device_id;
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
return m_mode;
|
||||
}
|
||||
|
||||
u32 uid() const override
|
||||
{
|
||||
return m_uid;
|
||||
}
|
||||
|
||||
u32 gid() const override
|
||||
{
|
||||
return m_gid;
|
||||
}
|
||||
|
||||
nlink_t nlinks() const override
|
||||
{
|
||||
return (nlink_t)m_nlinks;
|
||||
}
|
||||
|
||||
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 SymlinkInode : public VFS::FileInode
|
||||
{
|
||||
public:
|
||||
SymlinkInode() = default;
|
||||
|
||||
VFS::InodeType type() const override
|
||||
{
|
||||
return VFS::InodeType::Symlink;
|
||||
}
|
||||
|
||||
void set_fs(FileSystem& fs, Badge<FileSystem>)
|
||||
{
|
||||
m_fs = &fs;
|
||||
}
|
||||
|
||||
void set_inode_number(usize inum, Badge<FileSystem>)
|
||||
{
|
||||
m_inode_number = inum;
|
||||
}
|
||||
|
||||
Result<void> set_link(StringView link, Badge<FileSystem>)
|
||||
{
|
||||
m_link = TRY(String::from_string_view(link));
|
||||
return {};
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
return err(ENOTSUP);
|
||||
}
|
||||
|
||||
Result<usize> write(const u8*, usize, usize) override
|
||||
{
|
||||
return err(ENOTSUP);
|
||||
}
|
||||
|
||||
Result<void> truncate(usize) override
|
||||
{
|
||||
return err(ENOTSUP);
|
||||
}
|
||||
|
||||
usize size() const override
|
||||
{
|
||||
return m_link.length();
|
||||
}
|
||||
|
||||
mode_t mode() const override
|
||||
{
|
||||
return 0777;
|
||||
}
|
||||
|
||||
u32 uid() const override
|
||||
{
|
||||
return m_uid;
|
||||
}
|
||||
|
||||
u32 gid() const override
|
||||
{
|
||||
return m_gid;
|
||||
}
|
||||
|
||||
nlink_t nlinks() const override
|
||||
{
|
||||
return (nlink_t)m_nlinks;
|
||||
}
|
||||
|
||||
Result<void> chmod(mode_t) override
|
||||
{
|
||||
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--;
|
||||
}
|
||||
|
||||
Result<StringView> readlink() override
|
||||
{
|
||||
return m_link.view();
|
||||
}
|
||||
|
||||
virtual ~SymlinkInode() = default;
|
||||
|
||||
private:
|
||||
VFS::FileSystem* m_fs;
|
||||
String m_link;
|
||||
usize m_inode_number;
|
||||
u32 m_uid { 0 };
|
||||
u32 m_gid { 0 };
|
||||
u32 m_nlinks { 0 };
|
||||
};
|
||||
|
||||
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<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;
|
||||
}
|
||||
|
||||
void set_device_id(dev_t id, Badge<FileSystem>)
|
||||
{
|
||||
m_device_id = id;
|
||||
}
|
||||
|
||||
VFS::FileSystem* fs() const override
|
||||
{
|
||||
return m_fs;
|
||||
}
|
||||
|
||||
dev_t device_id() const override
|
||||
{
|
||||
return m_device_id;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
Result<u64> ioctl(int request, void* arg) override
|
||||
{
|
||||
return m_device->ioctl(request, arg);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
nlink_t nlinks() const override
|
||||
{
|
||||
return (nlink_t)m_nlinks;
|
||||
}
|
||||
|
||||
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;
|
||||
mode_t m_mode;
|
||||
u32 m_uid { 0 };
|
||||
u32 m_gid { 0 };
|
||||
u32 m_nlinks { 0 };
|
||||
dev_t m_device_id { 0 };
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Result<SharedPtr<VFS::Inode>> find(const char* name) const override;
|
||||
Option<VFS::DirectoryEntry> get(usize index) const override;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
bool blocking() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
usize size() const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 {};
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
virtual ~DirInode() = default;
|
||||
|
||||
private:
|
||||
VFS::FileSystem* m_fs;
|
||||
usize m_inode_number;
|
||||
mode_t m_mode;
|
||||
u32 m_uid { 0 };
|
||||
u32 m_gid { 0 };
|
||||
|
||||
SharedPtr<VFS::Inode> m_self;
|
||||
|
||||
Vector<VFS::DirectoryEntry> m_entries;
|
||||
};
|
||||
}
|
||||
|
131
kernel/src/fs/tmpfs/Inode.cpp
Normal file
131
kernel/src/fs/tmpfs/Inode.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
#include "fs/tmpfs/Inode.h"
|
||||
|
||||
namespace TmpFS
|
||||
{
|
||||
Result<SharedPtr<VFS::Inode>> DirInode::find(const char* name) const
|
||||
{
|
||||
for (const auto& entry : m_entries)
|
||||
{
|
||||
if (!strcmp(name, entry.name.chars())) return entry.inode;
|
||||
}
|
||||
|
||||
return err(ENOENT);
|
||||
}
|
||||
|
||||
Result<void> DirInode::replace_entry(SharedPtr<VFS::Inode> inode, const char* name)
|
||||
{
|
||||
for (auto& entry : m_entries)
|
||||
{
|
||||
if (!strcmp(name, entry.name.chars()))
|
||||
{
|
||||
entry.inode = inode;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return err(ENOENT);
|
||||
}
|
||||
|
||||
Option<VFS::DirectoryEntry> DirInode::get(usize index) const
|
||||
{
|
||||
if (index >= m_entries.size()) return {};
|
||||
|
||||
return m_entries[index];
|
||||
}
|
||||
|
||||
Result<void> DirInode::add_entry(SharedPtr<VFS::Inode> inode, const char* name)
|
||||
{
|
||||
if (find(name).has_value()) return err(EEXIST);
|
||||
|
||||
VFS::DirectoryEntry entry { inode, name };
|
||||
|
||||
TRY(m_entries.try_append(move(entry)));
|
||||
|
||||
inode->did_link();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<void> DirInode::remove_entry(const char* name)
|
||||
{
|
||||
SharedPtr<VFS::Inode> inode = TRY(find(name));
|
||||
|
||||
if (inode->type() == VFS::InodeType::Directory && inode->entries() != 2) return err(ENOTEMPTY);
|
||||
|
||||
if (inode->is_mountpoint()) return err(EBUSY);
|
||||
|
||||
m_entries.remove_first_matching(
|
||||
[&](const VFS::DirectoryEntry& entry) { return !strcmp(entry.name.chars(), name); });
|
||||
|
||||
inode->did_unlink();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<SharedPtr<VFS::Inode>> DirInode::create_file(const char* name)
|
||||
{
|
||||
auto inode = TRY(m_fs->create_file_inode());
|
||||
|
||||
TRY(add_entry(inode, name));
|
||||
|
||||
return inode;
|
||||
}
|
||||
|
||||
Result<SharedPtr<VFS::Inode>> DirInode::create_subdirectory(const char* name)
|
||||
{
|
||||
auto inode = TRY(m_fs->create_dir_inode(m_self));
|
||||
|
||||
TRY(add_entry(inode, name));
|
||||
|
||||
return inode;
|
||||
}
|
||||
|
||||
Result<usize> FileInode::read(u8* buf, usize offset, usize length) const
|
||||
{
|
||||
if (length == 0) return 0;
|
||||
|
||||
if (offset > m_data_buffer.size()) return 0;
|
||||
if (offset + length > m_data_buffer.size()) length = m_data_buffer.size() - offset;
|
||||
|
||||
memcpy(buf, m_data_buffer.data() + offset, length);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
Result<usize> FileInode::write(const u8* buf, usize offset, usize length)
|
||||
{
|
||||
if (length == 0) return 0;
|
||||
|
||||
if (offset > m_data_buffer.size())
|
||||
{
|
||||
// Fill the in-between space with zeroes.
|
||||
usize old_size = m_data_buffer.size();
|
||||
usize zeroes = offset - old_size;
|
||||
|
||||
TRY(m_data_buffer.try_resize(offset));
|
||||
|
||||
memset(m_data_buffer.data() + old_size, 0, zeroes);
|
||||
}
|
||||
|
||||
u8* slice = TRY(m_data_buffer.slice(offset, length));
|
||||
memcpy(slice, buf, length);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
Result<void> FileInode::truncate(usize size)
|
||||
{
|
||||
usize old_size = m_data_buffer.size();
|
||||
|
||||
TRY(m_data_buffer.try_resize(size));
|
||||
|
||||
if (size > old_size) memset(m_data_buffer.data() + old_size, 0, size - old_size);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
usize FileInode::size() const
|
||||
{
|
||||
return m_data_buffer.size();
|
||||
}
|
||||
}
|
472
kernel/src/fs/tmpfs/Inode.h
Normal file
472
kernel/src/fs/tmpfs/Inode.h
Normal file
@ -0,0 +1,472 @@
|
||||
#pragma once
|
||||
#include "fs/tmpfs/FileSystem.h"
|
||||
#include <luna/Badge.h>
|
||||
#include <luna/Buffer.h>
|
||||
#include <luna/StaticString.h>
|
||||
#include <luna/String.h>
|
||||
#include <luna/Vector.h>
|
||||
|
||||
namespace TmpFS
|
||||
{
|
||||
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
|
||||
{
|
||||
return m_mode;
|
||||
}
|
||||
|
||||
u32 uid() const override
|
||||
{
|
||||
return m_uid;
|
||||
}
|
||||
|
||||
u32 gid() const override
|
||||
{
|
||||
return m_gid;
|
||||
}
|
||||
|
||||
nlink_t nlinks() const override
|
||||
{
|
||||
return (nlink_t)m_nlinks;
|
||||
}
|
||||
|
||||
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 SymlinkInode : public VFS::FileInode
|
||||
{
|
||||
public:
|
||||
SymlinkInode() = default;
|
||||
|
||||
VFS::InodeType type() const override
|
||||
{
|
||||
return VFS::InodeType::Symlink;
|
||||
}
|
||||
|
||||
void set_fs(FileSystem& fs, Badge<FileSystem>)
|
||||
{
|
||||
m_fs = &fs;
|
||||
}
|
||||
|
||||
void set_inode_number(usize inum, Badge<FileSystem>)
|
||||
{
|
||||
m_inode_number = inum;
|
||||
}
|
||||
|
||||
Result<void> set_link(StringView link, Badge<FileSystem>)
|
||||
{
|
||||
m_link = TRY(String::from_string_view(link));
|
||||
return {};
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
return err(ENOTSUP);
|
||||
}
|
||||
|
||||
Result<usize> write(const u8*, usize, usize) override
|
||||
{
|
||||
return err(ENOTSUP);
|
||||
}
|
||||
|
||||
Result<void> truncate(usize) override
|
||||
{
|
||||
return err(ENOTSUP);
|
||||
}
|
||||
|
||||
usize size() const override
|
||||
{
|
||||
return m_link.length();
|
||||
}
|
||||
|
||||
mode_t mode() const override
|
||||
{
|
||||
return 0777;
|
||||
}
|
||||
|
||||
u32 uid() const override
|
||||
{
|
||||
return m_uid;
|
||||
}
|
||||
|
||||
u32 gid() const override
|
||||
{
|
||||
return m_gid;
|
||||
}
|
||||
|
||||
nlink_t nlinks() const override
|
||||
{
|
||||
return (nlink_t)m_nlinks;
|
||||
}
|
||||
|
||||
Result<void> chmod(mode_t) override
|
||||
{
|
||||
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--;
|
||||
}
|
||||
|
||||
Result<StringView> readlink() override
|
||||
{
|
||||
return m_link.view();
|
||||
}
|
||||
|
||||
virtual ~SymlinkInode() = default;
|
||||
|
||||
private:
|
||||
VFS::FileSystem* m_fs;
|
||||
String m_link;
|
||||
usize m_inode_number;
|
||||
u32 m_uid { 0 };
|
||||
u32 m_gid { 0 };
|
||||
u32 m_nlinks { 0 };
|
||||
};
|
||||
|
||||
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<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;
|
||||
}
|
||||
|
||||
void set_device_id(dev_t id, Badge<FileSystem>)
|
||||
{
|
||||
m_device_id = id;
|
||||
}
|
||||
|
||||
VFS::FileSystem* fs() const override
|
||||
{
|
||||
return m_fs;
|
||||
}
|
||||
|
||||
dev_t device_id() const override
|
||||
{
|
||||
return m_device_id;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
Result<u64> ioctl(int request, void* arg) override
|
||||
{
|
||||
return m_device->ioctl(request, arg);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
nlink_t nlinks() const override
|
||||
{
|
||||
return (nlink_t)m_nlinks;
|
||||
}
|
||||
|
||||
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;
|
||||
mode_t m_mode;
|
||||
u32 m_uid { 0 };
|
||||
u32 m_gid { 0 };
|
||||
u32 m_nlinks { 0 };
|
||||
dev_t m_device_id { 0 };
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Result<SharedPtr<VFS::Inode>> find(const char* name) const override;
|
||||
Option<VFS::DirectoryEntry> get(usize index) const override;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
bool blocking() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
usize size() const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 {};
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
virtual ~DirInode() = default;
|
||||
|
||||
private:
|
||||
VFS::FileSystem* m_fs;
|
||||
usize m_inode_number;
|
||||
mode_t m_mode;
|
||||
u32 m_uid { 0 };
|
||||
u32 m_gid { 0 };
|
||||
|
||||
SharedPtr<VFS::Inode> m_self;
|
||||
|
||||
Vector<VFS::DirectoryEntry> m_entries;
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user