kernel/VFS: Rework the metadata system so that there is a single metadata struct
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
apio 2023-08-01 17:20:28 +02:00
parent 4c87d72b44
commit dc35c42371
Signed by: apio
GPG Key ID: B8A7D06E42258954
28 changed files with 203 additions and 494 deletions

View File

@ -18,17 +18,15 @@ void InitRD::initialize()
g_initrd.initialize((void*)virtual_initrd_address, bootboot.initrd_size); g_initrd.initialize((void*)virtual_initrd_address, bootboot.initrd_size);
} }
static Result<void> vfs_create_dir_if_not_exists(const char* path, mode_t mode, uid_t uid, gid_t gid) static Result<void> vfs_create_dir_if_not_exists(const char* path, mode_t mode)
{ {
auto rc = VFS::create_directory(path, Credentials {}); auto rc = VFS::create_directory(path, mode & (mode_t)~S_IFMT, Credentials {});
if (rc.has_error()) if (rc.has_error())
{ {
if (rc.error() == EEXIST) return {}; if (rc.error() == EEXIST) return {};
return rc.release_error(); return rc.release_error();
} }
auto dir = rc.value(); auto dir = rc.value();
dir->chmod(mode & (mode_t)~S_IFMT);
dir->chown(uid, gid);
return {}; return {};
} }
@ -39,14 +37,12 @@ Result<void> InitRD::populate_vfs()
{ {
if (entry.type == TarStream::EntryType::RegularFile) if (entry.type == TarStream::EntryType::RegularFile)
{ {
auto file = TRY(VFS::create_file(entry.name.chars(), Credentials {})); auto file = TRY(VFS::create_file(entry.name.chars(), entry.mode & (mode_t)~S_IFMT, Credentials {}));
file->write(entry.data(), 0, entry.size); file->write(entry.data(), 0, entry.size);
file->chmod(entry.mode & (mode_t)~S_IFMT);
file->chown(entry.uid, entry.gid);
} }
else if (entry.type == TarStream::EntryType::Directory) else if (entry.type == TarStream::EntryType::Directory)
{ {
TRY(vfs_create_dir_if_not_exists(entry.name.chars(), entry.mode, entry.uid, entry.gid)); TRY(vfs_create_dir_if_not_exists(entry.name.chars(), entry.mode));
} }
} }

View File

@ -42,39 +42,14 @@ class MountInode : public VFS::Inode, public LinkedListNode<MountInode>
return false; return false;
} }
usize size() const override const VFS::InodeMetadata& metadata() const override
{ {
return 0; return m_mount_root_inode->metadata();
} }
mode_t mode() const override Result<void> set_metadata(const VFS::InodeMetadata& metadata) override
{ {
return m_mount_root_inode->mode(); return m_mount_root_inode->set_metadata(metadata);
}
u32 uid() const override
{
return m_mount_root_inode->uid();
}
u32 gid() const override
{
return m_mount_root_inode->gid();
}
nlink_t nlinks() const override
{
return m_mount_root_inode->nlinks();
}
Result<void> chmod(mode_t mode) override
{
return m_mount_root_inode->chmod(mode);
}
Result<void> chown(u32 uid, u32 gid) override
{
return m_mount_root_inode->chown(uid, gid);
} }
VFS::FileSystem* fs() const override VFS::FileSystem* fs() const override
@ -82,11 +57,6 @@ class MountInode : public VFS::Inode, public LinkedListNode<MountInode>
return m_mountee.ptr(); return m_mountee.ptr();
} }
usize inode_number() const override
{
return m_mount_root_inode->inode_number();
}
VFS::InodeType type() const override VFS::InodeType type() const override
{ {
return VFS::InodeType::Directory; return VFS::InodeType::Directory;
@ -122,14 +92,14 @@ class MountInode : public VFS::Inode, public LinkedListNode<MountInode>
return m_mount_root_inode->remove_entry(name); return m_mount_root_inode->remove_entry(name);
} }
Result<SharedPtr<VFS::Inode>> create_file(const char* name) override Result<SharedPtr<VFS::Inode>> create_file(const char* name, mode_t mode) override
{ {
return m_mount_root_inode->create_file(name); return m_mount_root_inode->create_file(name, mode);
} }
Result<SharedPtr<VFS::Inode>> create_subdirectory(const char* name) override Result<SharedPtr<VFS::Inode>> create_subdirectory(const char* name, mode_t mode) override
{ {
return m_mount_root_inode->create_subdirectory(name); return m_mount_root_inode->create_subdirectory(name, mode);
} }
Result<void> add_entry(SharedPtr<VFS::Inode> inode, const char* name) override Result<void> add_entry(SharedPtr<VFS::Inode> inode, const char* name) override

View File

@ -14,8 +14,14 @@ Result<void> Pipe::create(SharedPtr<VFS::Inode>& rpipe, SharedPtr<VFS::Inode>& w
pipe->m_reader = reader.ptr(); pipe->m_reader = reader.ptr();
writer->m_pipe = reader->m_pipe = pipe; writer->m_pipe = reader->m_pipe = pipe;
writer->chown(auth.euid, auth.egid); writer->m_metadata.inum = 0;
reader->chown(auth.euid, auth.egid); writer->m_metadata.uid = auth.euid;
writer->m_metadata.gid = auth.egid;
writer->m_metadata.mode = 0200;
reader->m_metadata.inum = 0;
reader->m_metadata.uid = auth.euid;
reader->m_metadata.gid = auth.egid;
reader->m_metadata.mode = 0400;
rpipe = reader; rpipe = reader;
wpipe = writer; wpipe = writer;

View File

@ -45,9 +45,10 @@ class PipeInodeBase : public VFS::FileInode
return m_pipe->will_block_if_read(); return m_pipe->will_block_if_read();
} }
usize size() const override const VFS::InodeMetadata& metadata() const override
{ {
return m_pipe->m_data_buffer.size(); m_metadata.size = m_pipe->m_data_buffer.size();
return m_metadata;
} }
void did_link() override void did_link() override
@ -58,23 +59,6 @@ class PipeInodeBase : public VFS::FileInode
{ {
} }
Result<void> chmod(mode_t) override
{
return err(ENOTSUP);
}
Result<void> chown(u32 uid, u32 gid) override
{
m_uid = uid;
m_gid = gid;
return {};
}
usize inode_number() const override
{
return 0;
}
VFS::FileSystem* fs() const override VFS::FileSystem* fs() const override
{ {
return nullptr; return nullptr;
@ -86,8 +70,6 @@ class PipeInodeBase : public VFS::FileInode
protected: protected:
SharedPtr<Pipe> m_pipe; SharedPtr<Pipe> m_pipe;
u32 m_uid { 0 };
u32 m_gid { 0 };
}; };
class PipeWriter : public PipeInodeBase class PipeWriter : public PipeInodeBase
@ -104,11 +86,6 @@ class PipeWriter : public PipeInodeBase
return m_pipe->write(buf, offset, length); return m_pipe->write(buf, offset, length);
} }
mode_t mode() const override
{
return 0200;
}
~PipeWriter(); ~PipeWriter();
friend class Pipe; friend class Pipe;
@ -128,11 +105,6 @@ class PipeReader : public PipeInodeBase
check(false); check(false);
} }
mode_t mode() const override
{
return 0400;
}
~PipeReader(); ~PipeReader();
friend class Pipe; friend class Pipe;

View File

@ -69,7 +69,8 @@ namespace VFS
return resolve_path_impl(path, auth, current_inode, follow_last_symlink, symlinks_followed); return resolve_path_impl(path, auth, current_inode, follow_last_symlink, symlinks_followed);
} }
Result<SharedPtr<Inode>> create_directory(const char* path, Credentials auth, SharedPtr<Inode> working_directory) Result<SharedPtr<Inode>> create_directory(const char* path, mode_t mode, Credentials auth,
SharedPtr<Inode> working_directory)
{ {
auto parent_path = TRY(PathParser::dirname(path)); auto parent_path = TRY(PathParser::dirname(path));
@ -81,10 +82,11 @@ namespace VFS
TRY(validate_filename(child_name.view())); TRY(validate_filename(child_name.view()));
return parent_inode->create_subdirectory(child_name.chars()); return parent_inode->create_subdirectory(child_name.chars(), mode);
} }
Result<SharedPtr<Inode>> create_file(const char* path, Credentials auth, SharedPtr<Inode> working_directory) Result<SharedPtr<Inode>> create_file(const char* path, mode_t mode, Credentials auth,
SharedPtr<Inode> working_directory)
{ {
auto parent_path = TRY(PathParser::dirname(path)); auto parent_path = TRY(PathParser::dirname(path));
@ -96,7 +98,7 @@ namespace VFS
TRY(validate_filename(child_name.view())); TRY(validate_filename(child_name.view()));
return parent_inode->create_file(child_name.chars()); return parent_inode->create_file(child_name.chars(), mode);
} }
Result<void> validate_filename(StringView name) Result<void> validate_filename(StringView name)
@ -135,45 +137,51 @@ namespace VFS
{ {
if (auth.euid == 0) return true; if (auth.euid == 0) return true;
if (inode->uid() == auth.euid) { return inode->mode() & S_IXUSR; } const auto& metadata = inode->metadata();
if (inode->gid() == auth.egid) { return inode->mode() & S_IXGRP; }
return inode->mode() & S_IXOTH; if (metadata.uid == auth.euid) { return metadata.mode & S_IXUSR; }
if (metadata.gid == auth.egid) { return metadata.mode & S_IXGRP; }
return metadata.mode & S_IXOTH;
} }
bool can_write(SharedPtr<Inode> inode, Credentials auth) bool can_write(SharedPtr<Inode> inode, Credentials auth)
{ {
if (auth.euid == 0) return true; if (auth.euid == 0) return true;
if (inode->uid() == auth.euid) { return inode->mode() & S_IWUSR; } const auto& metadata = inode->metadata();
if (inode->gid() == auth.egid) { return inode->mode() & S_IWGRP; }
return inode->mode() & S_IWOTH; if (metadata.uid == auth.euid) { return metadata.mode & S_IWUSR; }
if (metadata.gid == auth.egid) { return metadata.mode & S_IWGRP; }
return metadata.mode & S_IWOTH;
} }
bool can_read(SharedPtr<Inode> inode, Credentials auth) bool can_read(SharedPtr<Inode> inode, Credentials auth)
{ {
if (auth.euid == 0) return true; if (auth.euid == 0) return true;
if (inode->uid() == auth.euid) { return inode->mode() & S_IRUSR; } const auto& metadata = inode->metadata();
if (inode->gid() == auth.egid) { return inode->mode() & S_IRGRP; }
return inode->mode() & S_IROTH; if (metadata.uid == auth.euid) { return metadata.mode & S_IRUSR; }
if (metadata.gid == auth.egid) { return metadata.mode & S_IRGRP; }
return metadata.mode & S_IROTH;
} }
bool is_setuid(SharedPtr<Inode> inode) bool is_setuid(SharedPtr<Inode> inode)
{ {
return inode->mode() & S_ISUID; return inode->metadata().mode & S_ISUID;
} }
bool is_setgid(SharedPtr<Inode> inode) bool is_setgid(SharedPtr<Inode> inode)
{ {
return inode->mode() & S_ISGID; return inode->metadata().mode & S_ISGID;
} }
bool is_sticky(SharedPtr<Inode> inode) bool is_sticky(SharedPtr<Inode> inode)
{ {
return inode->mode() & S_ISVTX; return inode->metadata().mode & S_ISVTX;
} }
bool is_seekable(SharedPtr<Inode> inode) bool is_seekable(SharedPtr<Inode> inode)

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include "arch/Timer.h"
#include <bits/makedev.h> #include <bits/makedev.h>
#include <bits/timespec.h>
#include <luna/SharedPtr.h> #include <luna/SharedPtr.h>
#include <luna/StaticString.h> #include <luna/StaticString.h>
#include <luna/StringView.h> #include <luna/StringView.h>
@ -20,6 +22,21 @@ namespace VFS
Socket, Socket,
}; };
struct InodeMetadata
{
ino_t inum;
size_t size { 0 };
mode_t mode;
nlink_t nlinks { 1 };
uid_t uid { 0 };
gid_t gid { 0 };
dev_t devid { 0 };
struct timespec atime;
struct timespec mtime;
struct timespec ctime;
};
class Inode; class Inode;
class FileSystem : public Shareable class FileSystem : public Shareable
@ -27,11 +44,11 @@ namespace VFS
public: public:
virtual SharedPtr<Inode> root_inode() const = 0; virtual SharedPtr<Inode> root_inode() const = 0;
virtual Result<SharedPtr<Inode>> create_file_inode() = 0; virtual Result<SharedPtr<Inode>> create_file_inode(mode_t mode) = 0;
virtual Result<SharedPtr<Inode>> create_dir_inode(SharedPtr<Inode> parent) = 0; virtual Result<SharedPtr<Inode>> create_dir_inode(SharedPtr<Inode> parent, mode_t mode) = 0;
virtual Result<SharedPtr<Inode>> create_device_inode(u32 major, u32 minor) = 0; virtual Result<SharedPtr<Inode>> create_device_inode(u32 major, u32 minor, mode_t mode) = 0;
virtual Result<SharedPtr<Inode>> create_symlink_inode(StringView link) = 0; virtual Result<SharedPtr<Inode>> create_symlink_inode(StringView link) = 0;
@ -101,9 +118,9 @@ namespace VFS
virtual Option<DirectoryEntry> get(usize index) const = 0; virtual Option<DirectoryEntry> get(usize index) const = 0;
virtual Result<SharedPtr<Inode>> create_file(const char* name) = 0; virtual Result<SharedPtr<Inode>> create_file(const char* name, mode_t mode) = 0;
virtual Result<SharedPtr<Inode>> create_subdirectory(const char* name) = 0; virtual Result<SharedPtr<Inode>> create_subdirectory(const char* name, mode_t mode) = 0;
virtual Result<void> add_entry(SharedPtr<Inode> inode, const char* name) = 0; virtual Result<void> add_entry(SharedPtr<Inode> inode, const char* name) = 0;
@ -128,29 +145,16 @@ namespace VFS
return StringView {}; return StringView {};
} }
virtual dev_t device_id() const virtual const InodeMetadata& metadata() const
{ {
return luna_dev_makedev(0, 0); return m_metadata;
} }
// Metadata accessors virtual Result<void> set_metadata(const InodeMetadata& metadata)
virtual usize size() const = 0;
virtual mode_t mode() const = 0;
virtual nlink_t nlinks() const
{ {
return 1; m_metadata = metadata;
} m_metadata.ctime = *Timer::realtime_clock();
return {};
virtual u32 uid() const
{
return 0;
}
virtual u32 gid() const
{
return 0;
} }
virtual bool is_mountpoint() const virtual bool is_mountpoint() const
@ -161,11 +165,6 @@ namespace VFS
virtual void did_link() = 0; virtual void did_link() = 0;
virtual void did_unlink() = 0; virtual void did_unlink() = 0;
// Metadata changers
virtual Result<void> chmod(mode_t mode) = 0;
virtual Result<void> chown(u32 uid, u32 gid) = 0;
// Generic VFS-related methods // Generic VFS-related methods
virtual FileSystem* fs() const = 0; virtual FileSystem* fs() const = 0;
@ -173,8 +172,6 @@ namespace VFS
virtual InodeType type() const = 0; virtual InodeType type() const = 0;
virtual usize inode_number() const = 0;
virtual void add_handle() virtual void add_handle()
{ {
auto* f = fs(); auto* f = fs();
@ -186,9 +183,12 @@ namespace VFS
auto* f = fs(); auto* f = fs();
if (f) f->remove_handle(); if (f) f->remove_handle();
} }
protected:
mutable InodeMetadata m_metadata;
}; };
class FileInode : Inode class FileInode : public Inode
{ {
public: public:
Result<SharedPtr<Inode>> find(const char*) const override Result<SharedPtr<Inode>> find(const char*) const override
@ -201,12 +201,12 @@ namespace VFS
return {}; return {};
} }
Result<SharedPtr<Inode>> create_file(const char*) override Result<SharedPtr<Inode>> create_file(const char*, mode_t) override
{ {
return err(ENOTDIR); return err(ENOTDIR);
} }
Result<SharedPtr<Inode>> create_subdirectory(const char*) override Result<SharedPtr<Inode>> create_subdirectory(const char*, mode_t) override
{ {
return err(ENOTDIR); return err(ENOTDIR);
} }
@ -244,7 +244,7 @@ namespace VFS
virtual ~FileInode() = default; virtual ~FileInode() = default;
}; };
class DeviceInode : Inode class DeviceInode : public Inode
{ {
public: public:
Result<SharedPtr<Inode>> find(const char*) const override Result<SharedPtr<Inode>> find(const char*) const override
@ -257,12 +257,12 @@ namespace VFS
return {}; return {};
} }
Result<SharedPtr<Inode>> create_file(const char*) override Result<SharedPtr<Inode>> create_file(const char*, mode_t) override
{ {
return err(ENOTDIR); return err(ENOTDIR);
} }
Result<SharedPtr<Inode>> create_subdirectory(const char*) override Result<SharedPtr<Inode>> create_subdirectory(const char*, mode_t) override
{ {
return err(ENOTDIR); return err(ENOTDIR);
} }
@ -299,10 +299,10 @@ namespace VFS
SharedPtr<VFS::Inode> working_directory = {}, SharedPtr<VFS::Inode> working_directory = {},
bool follow_last_symlink = true); bool follow_last_symlink = true);
Result<SharedPtr<Inode>> create_directory(const char* path, Credentials auth, Result<SharedPtr<Inode>> create_directory(const char* path, mode_t mode, Credentials auth,
SharedPtr<VFS::Inode> working_directory = {}); SharedPtr<VFS::Inode> working_directory = {});
Result<SharedPtr<Inode>> create_file(const char* path, Credentials auth, Result<SharedPtr<Inode>> create_file(const char* path, mode_t mode, Credentials auth,
SharedPtr<VFS::Inode> working_directory = {}); SharedPtr<VFS::Inode> working_directory = {});
Result<void> validate_filename(StringView name); Result<void> validate_filename(StringView name);

View File

@ -36,8 +36,7 @@ namespace DeviceRegistry
Result<void> create_special_device_inode(SharedPtr<VFS::FileSystem> fs, const DeviceDescriptor& descriptor) Result<void> create_special_device_inode(SharedPtr<VFS::FileSystem> fs, const DeviceDescriptor& descriptor)
{ {
auto inode = TRY(fs->create_device_inode(descriptor.major, descriptor.minor)); auto inode = TRY(fs->create_device_inode(descriptor.major, descriptor.minor, descriptor.mode));
inode->chmod(descriptor.mode);
TRY(fs->root_inode()->add_entry(inode, descriptor.name)); TRY(fs->root_inode()->add_entry(inode, descriptor.name));
return {}; return {};

View File

@ -49,7 +49,14 @@ namespace Ext2
auto inode = TRY(adopt_shared_if_nonnull(new (std::nothrow) Ext2::Inode({}, this))); auto inode = TRY(adopt_shared_if_nonnull(new (std::nothrow) Ext2::Inode({}, this)));
TRY(m_host_device->read((u8*)&inode->m_raw_inode, inode_address, INODE_SIZE)); TRY(m_host_device->read((u8*)&inode->m_raw_inode, inode_address, INODE_SIZE));
inode->m_type = vfs_type_from_ext2_type(inode->m_raw_inode.mode); inode->m_type = vfs_type_from_ext2_type(inode->m_raw_inode.mode);
inode->m_inum = inum; inode->m_metadata.inum = inum;
inode->m_metadata.size = (m_uses_extended_size && (inode->m_type == VFS::InodeType::RegularFile))
? ((u64)inode->m_raw_inode.size_high << 32) | (u64)inode->m_raw_inode.size_low
: inode->m_raw_inode.size_low;
inode->m_metadata.mode = inode->m_raw_inode.mode & 07777;
inode->m_metadata.nlinks = inode->m_raw_inode.nlinks;
inode->m_metadata.uid = inode->m_raw_inode.uid;
inode->m_metadata.gid = inode->m_raw_inode.gid;
#ifdef EXT2_DEBUG #ifdef EXT2_DEBUG
kdbgln("ext2: Read inode %lu with mode %#x (%#x + %#o), size %lu", inum, inode->m_raw_inode.mode, kdbgln("ext2: Read inode %lu with mode %#x (%#x + %#o), size %lu", inum, inode->m_raw_inode.mode,

View File

@ -127,17 +127,17 @@ namespace Ext2
return m_root_inode; return m_root_inode;
} }
Result<SharedPtr<VFS::Inode>> create_file_inode() override Result<SharedPtr<VFS::Inode>> create_file_inode(mode_t) override
{ {
return err(EROFS); return err(EROFS);
} }
Result<SharedPtr<VFS::Inode>> create_dir_inode(SharedPtr<VFS::Inode>) override Result<SharedPtr<VFS::Inode>> create_dir_inode(SharedPtr<VFS::Inode>, mode_t) override
{ {
return err(EROFS); return err(EROFS);
} }
Result<SharedPtr<VFS::Inode>> create_device_inode(u32, u32) override Result<SharedPtr<VFS::Inode>> create_device_inode(u32, u32, mode_t) override
{ {
return err(EROFS); return err(EROFS);
} }

View File

@ -7,19 +7,12 @@ namespace Ext2
{ {
} }
usize Inode::size() const
{
return (m_fs->m_uses_extended_size && (m_type == VFS::InodeType::RegularFile))
? ((u64)m_raw_inode.size_high << 32) | (u64)m_raw_inode.size_low
: m_raw_inode.size_low;
}
Result<usize> Inode::read(u8* buf, usize offset, usize length) const Result<usize> Inode::read(u8* buf, usize offset, usize length) const
{ {
if (length == 0) return 0; if (length == 0) return 0;
if (offset > size()) return 0; if (offset > m_metadata.size) return 0;
if (offset + length > size()) length = size() - offset; if (offset + length > m_metadata.size) length = m_metadata.size - offset;
const usize block_size = m_fs->m_block_size; const usize block_size = m_fs->m_block_size;
@ -95,7 +88,7 @@ namespace Ext2
{ {
check(m_type == VFS::InodeType::Directory); check(m_type == VFS::InodeType::Directory);
const usize inode_size = size(); const usize inode_size = m_metadata.size;
const usize block_size = m_fs->m_block_size; const usize block_size = m_fs->m_block_size;
u8* const buf = TRY(make_array<u8>(block_size)); u8* const buf = TRY(make_array<u8>(block_size));
@ -184,7 +177,7 @@ namespace Ext2
if (!m_link.is_empty()) return m_link.view(); if (!m_link.is_empty()) return m_link.view();
const usize length = size(); const usize length = m_metadata.size;
if (length < 60) if (length < 60)
{ {

View File

@ -21,33 +21,6 @@ namespace Ext2
return m_type; return m_type;
} }
usize size() const override;
mode_t mode() const override
{
return m_raw_inode.mode & 07777;
}
nlink_t nlinks() const override
{
return m_raw_inode.nlinks;
}
u32 uid() const override
{
return m_raw_inode.uid;
}
u32 gid() const override
{
return m_raw_inode.gid;
}
usize inode_number() const override
{
return m_inum;
}
VFS::FileSystem* fs() const override VFS::FileSystem* fs() const override
{ {
return m_fs; return m_fs;
@ -61,12 +34,7 @@ namespace Ext2
{ {
} }
Result<void> chmod(mode_t) override Result<void> set_metadata(const VFS::InodeMetadata&) override
{
return err(EROFS);
}
Result<void> chown(u32, u32) override
{ {
return err(EROFS); return err(EROFS);
} }
@ -87,14 +55,14 @@ namespace Ext2
Option<VFS::DirectoryEntry> get(usize) const override; Option<VFS::DirectoryEntry> get(usize) const override;
Result<SharedPtr<VFS::Inode>> create_file(const char*) override Result<SharedPtr<VFS::Inode>> create_file(const char*, mode_t) override
{ {
if (m_type != VFS::InodeType::Directory) return err(ENOTDIR); if (m_type != VFS::InodeType::Directory) return err(ENOTDIR);
return err(EROFS); return err(EROFS);
} }
Result<SharedPtr<VFS::Inode>> create_subdirectory(const char*) override Result<SharedPtr<VFS::Inode>> create_subdirectory(const char*, mode_t) override
{ {
if (m_type != VFS::InodeType::Directory) return err(ENOTDIR); if (m_type != VFS::InodeType::Directory) return err(ENOTDIR);

View File

@ -10,8 +10,7 @@ namespace TmpFS
Result<SharedPtr<VFS::FileSystem>> FileSystem::create() Result<SharedPtr<VFS::FileSystem>> FileSystem::create()
{ {
SharedPtr<FileSystem> fs = TRY(adopt_shared_if_nonnull(new (std::nothrow) FileSystem())); SharedPtr<FileSystem> fs = TRY(adopt_shared_if_nonnull(new (std::nothrow) FileSystem()));
SharedPtr<VFS::Inode> root = TRY(fs->create_dir_inode({})); SharedPtr<VFS::Inode> root = TRY(fs->create_dir_inode({}, 0755));
root->chmod(0755);
fs->set_root(root); fs->set_root(root);
return (SharedPtr<VFS::FileSystem>)fs; return (SharedPtr<VFS::FileSystem>)fs;
} }
@ -21,11 +20,12 @@ namespace TmpFS
return m_next_inode_number++; return m_next_inode_number++;
} }
Result<SharedPtr<VFS::Inode>> FileSystem::create_file_inode() Result<SharedPtr<VFS::Inode>> FileSystem::create_file_inode(mode_t mode)
{ {
SharedPtr<FileInode> inode = TRY(make_shared<FileInode>()); SharedPtr<FileInode> inode = TRY(make_shared<FileInode>());
inode->set_fs(*this, {}); inode->set_fs(*this, {});
inode->set_inode_number(m_next_inode_number++, {}); inode->set_inode_number(m_next_inode_number++, {});
inode->m_metadata.mode = mode;
return (SharedPtr<VFS::Inode>)inode; return (SharedPtr<VFS::Inode>)inode;
} }
@ -38,7 +38,7 @@ namespace TmpFS
return (SharedPtr<VFS::Inode>)inode; return (SharedPtr<VFS::Inode>)inode;
} }
Result<SharedPtr<VFS::Inode>> FileSystem::create_dir_inode(SharedPtr<VFS::Inode> parent) Result<SharedPtr<VFS::Inode>> FileSystem::create_dir_inode(SharedPtr<VFS::Inode> parent, mode_t mode)
{ {
SharedPtr<DirInode> inode = TRY(make_shared<DirInode>()); SharedPtr<DirInode> inode = TRY(make_shared<DirInode>());
@ -48,11 +48,12 @@ namespace TmpFS
inode->set_self(inode, {}); inode->set_self(inode, {});
inode->set_fs(*this, {}); inode->set_fs(*this, {});
inode->set_inode_number(m_next_inode_number++, {}); inode->set_inode_number(m_next_inode_number++, {});
inode->m_metadata.mode = mode;
return (SharedPtr<VFS::Inode>)inode; return (SharedPtr<VFS::Inode>)inode;
} }
Result<SharedPtr<VFS::Inode>> FileSystem::create_device_inode(u32 major, u32 minor) Result<SharedPtr<VFS::Inode>> FileSystem::create_device_inode(u32 major, u32 minor, mode_t mode)
{ {
SharedPtr<Device> device = TRY(DeviceRegistry::fetch_special_device(major, minor)); SharedPtr<Device> device = TRY(DeviceRegistry::fetch_special_device(major, minor));
@ -63,6 +64,7 @@ namespace TmpFS
// FIXME: This should be queried from Device directly, but Device doesn't have an API to store and retrieve its // FIXME: This should be queried from Device directly, but Device doesn't have an API to store and retrieve its
// device ID atm. // device ID atm.
inode->set_device_id(luna_dev_makedev(major, minor), {}); inode->set_device_id(luna_dev_makedev(major, minor), {});
inode->m_metadata.mode = mode;
return (SharedPtr<VFS::Inode>)inode; return (SharedPtr<VFS::Inode>)inode;
} }

View File

@ -13,9 +13,9 @@ namespace TmpFS
return m_root_inode; return m_root_inode;
} }
Result<SharedPtr<VFS::Inode>> create_file_inode() override; Result<SharedPtr<VFS::Inode>> create_file_inode(mode_t mode) override;
Result<SharedPtr<VFS::Inode>> create_dir_inode(SharedPtr<VFS::Inode> parent) override; Result<SharedPtr<VFS::Inode>> create_dir_inode(SharedPtr<VFS::Inode> parent, mode_t mode) override;
Result<SharedPtr<VFS::Inode>> create_device_inode(u32 major, u32 minor) override; Result<SharedPtr<VFS::Inode>> create_device_inode(u32 major, u32 minor, mode_t mode) override;
Result<SharedPtr<VFS::Inode>> create_symlink_inode(StringView link) override; Result<SharedPtr<VFS::Inode>> create_symlink_inode(StringView link) override;
Result<u64> allocate_inode_number() override; Result<u64> allocate_inode_number() override;

View File

@ -62,18 +62,18 @@ namespace TmpFS
return {}; return {};
} }
Result<SharedPtr<VFS::Inode>> DirInode::create_file(const char* name) Result<SharedPtr<VFS::Inode>> DirInode::create_file(const char* name, mode_t mode)
{ {
auto inode = TRY(m_fs->create_file_inode()); auto inode = TRY(m_fs->create_file_inode(mode));
TRY(add_entry(inode, name)); TRY(add_entry(inode, name));
return inode; return inode;
} }
Result<SharedPtr<VFS::Inode>> DirInode::create_subdirectory(const char* name) Result<SharedPtr<VFS::Inode>> DirInode::create_subdirectory(const char* name, mode_t mode)
{ {
auto inode = TRY(m_fs->create_dir_inode(m_self)); auto inode = TRY(m_fs->create_dir_inode(m_self, mode));
TRY(add_entry(inode, name)); TRY(add_entry(inode, name));
@ -110,6 +110,8 @@ namespace TmpFS
u8* slice = TRY(m_data_buffer.slice(offset, length)); u8* slice = TRY(m_data_buffer.slice(offset, length));
memcpy(slice, buf, length); memcpy(slice, buf, length);
m_metadata.size = m_data_buffer.size();
return length; return length;
} }
@ -121,11 +123,8 @@ namespace TmpFS
if (size > old_size) memset(m_data_buffer.data() + old_size, 0, size - old_size); if (size > old_size) memset(m_data_buffer.data() + old_size, 0, size - old_size);
m_metadata.size = m_data_buffer.size();
return {}; return {};
} }
usize FileInode::size() const
{
return m_data_buffer.size();
}
} }

View File

@ -20,68 +20,27 @@ namespace TmpFS
void set_inode_number(usize inum, Badge<FileSystem>) void set_inode_number(usize inum, Badge<FileSystem>)
{ {
m_inode_number = inum; m_metadata.inum = inum;
} }
VFS::FileSystem* fs() const override VFS::FileSystem* fs() const override
{ {
return m_fs; return m_fs;
} }
usize inode_number() const override
{
return m_inode_number;
}
Result<usize> read(u8*, usize, usize) const override; Result<usize> read(u8*, usize, usize) const override;
Result<usize> write(const u8*, usize, usize) override; Result<usize> write(const u8*, usize, usize) override;
Result<void> truncate(usize size) 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 void did_link() override
{ {
m_nlinks++; m_metadata.nlinks++;
} }
void did_unlink() override void did_unlink() override
{ {
m_nlinks--; m_metadata.nlinks--;
} }
virtual ~FileInode() = default; virtual ~FileInode() = default;
@ -89,11 +48,8 @@ namespace TmpFS
private: private:
VFS::FileSystem* m_fs; VFS::FileSystem* m_fs;
Buffer m_data_buffer; Buffer m_data_buffer;
usize m_inode_number;
mode_t m_mode; friend class FileSystem;
u32 m_uid { 0 };
u32 m_gid { 0 };
u32 m_nlinks { 0 };
}; };
class SymlinkInode : public VFS::FileInode class SymlinkInode : public VFS::FileInode
@ -113,7 +69,7 @@ namespace TmpFS
void set_inode_number(usize inum, Badge<FileSystem>) void set_inode_number(usize inum, Badge<FileSystem>)
{ {
m_inode_number = inum; m_metadata.inum = inum;
} }
Result<void> set_link(StringView link, Badge<FileSystem>) Result<void> set_link(StringView link, Badge<FileSystem>)
@ -127,11 +83,6 @@ namespace TmpFS
return m_fs; return m_fs;
} }
usize inode_number() const override
{
return m_inode_number;
}
Result<usize> read(u8*, usize, usize) const override Result<usize> read(u8*, usize, usize) const override
{ {
return err(ENOTSUP); return err(ENOTSUP);
@ -147,51 +98,14 @@ namespace TmpFS
return err(ENOTSUP); 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 void did_link() override
{ {
m_nlinks++; m_metadata.nlinks++;
} }
void did_unlink() override void did_unlink() override
{ {
m_nlinks--; m_metadata.nlinks--;
} }
Result<StringView> readlink() override Result<StringView> readlink() override
@ -204,10 +118,8 @@ namespace TmpFS
private: private:
VFS::FileSystem* m_fs; VFS::FileSystem* m_fs;
String m_link; String m_link;
usize m_inode_number;
u32 m_uid { 0 }; friend class FileSystem;
u32 m_gid { 0 };
u32 m_nlinks { 0 };
}; };
class DeviceInode : public VFS::DeviceInode class DeviceInode : public VFS::DeviceInode
@ -227,7 +139,7 @@ namespace TmpFS
void set_inode_number(usize inum, Badge<FileSystem>) void set_inode_number(usize inum, Badge<FileSystem>)
{ {
m_inode_number = inum; m_metadata.inum = inum;
} }
void set_device(SharedPtr<Device> device, Badge<FileSystem>) void set_device(SharedPtr<Device> device, Badge<FileSystem>)
@ -237,7 +149,7 @@ namespace TmpFS
void set_device_id(dev_t id, Badge<FileSystem>) void set_device_id(dev_t id, Badge<FileSystem>)
{ {
m_device_id = id; m_metadata.devid = id;
} }
VFS::FileSystem* fs() const override VFS::FileSystem* fs() const override
@ -245,16 +157,6 @@ namespace TmpFS
return m_fs; 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 Result<usize> read(u8* buf, usize offset, usize length) const override
{ {
return m_device->read(buf, offset, length); return m_device->read(buf, offset, length);
@ -286,52 +188,14 @@ namespace TmpFS
return m_device->will_block_if_read(); return m_device->will_block_if_read();
} }
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 void did_link() override
{ {
m_nlinks++; m_metadata.nlinks++;
} }
void did_unlink() override void did_unlink() override
{ {
m_nlinks--; m_metadata.nlinks--;
} }
virtual ~DeviceInode() = default; virtual ~DeviceInode() = default;
@ -339,12 +203,8 @@ namespace TmpFS
private: private:
VFS::FileSystem* m_fs; VFS::FileSystem* m_fs;
SharedPtr<Device> m_device; SharedPtr<Device> m_device;
usize m_inode_number;
mode_t m_mode; friend class FileSystem;
u32 m_uid { 0 };
u32 m_gid { 0 };
u32 m_nlinks { 0 };
dev_t m_device_id { 0 };
}; };
class DirInode : public VFS::Inode class DirInode : public VFS::Inode
@ -359,7 +219,7 @@ namespace TmpFS
void set_inode_number(usize inum, Badge<FileSystem>) void set_inode_number(usize inum, Badge<FileSystem>)
{ {
m_inode_number = inum; m_metadata.inum = inum;
} }
void set_self(SharedPtr<VFS::Inode> self, Badge<FileSystem>) void set_self(SharedPtr<VFS::Inode> self, Badge<FileSystem>)
@ -390,49 +250,11 @@ namespace TmpFS
return false; 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 VFS::FileSystem* fs() const override
{ {
return m_fs; return m_fs;
} }
usize inode_number() const override
{
return m_inode_number;
}
VFS::InodeType type() const override VFS::InodeType type() const override
{ {
return VFS::InodeType::Directory; return VFS::InodeType::Directory;
@ -455,8 +277,8 @@ namespace TmpFS
Result<void> remove_entry(const char* name) override; Result<void> remove_entry(const char* name) override;
Result<SharedPtr<VFS::Inode>> create_file(const char* name) override; Result<SharedPtr<VFS::Inode>> create_file(const char* name, mode_t mode) override;
Result<SharedPtr<VFS::Inode>> create_subdirectory(const char* name) override; Result<SharedPtr<VFS::Inode>> create_subdirectory(const char* name, mode_t mode) override;
Result<void> add_entry(SharedPtr<VFS::Inode> inode, const char* name); Result<void> add_entry(SharedPtr<VFS::Inode> inode, const char* name);
Result<void> replace_entry(SharedPtr<VFS::Inode> inode, const char* name); Result<void> replace_entry(SharedPtr<VFS::Inode> inode, const char* name);
@ -465,13 +287,9 @@ namespace TmpFS
private: private:
VFS::FileSystem* m_fs; 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; SharedPtr<VFS::Inode> m_self;
Vector<VFS::DirectoryEntry> m_entries; Vector<VFS::DirectoryEntry> m_entries;
friend class FileSystem;
}; };
} }

View File

@ -21,7 +21,7 @@ class Socket : public VFS::FileInode
void set_inode_number(usize inum) void set_inode_number(usize inum)
{ {
m_inode_number = inum; m_metadata.inum = inum;
} }
VFS::FileSystem* fs() const override VFS::FileSystem* fs() const override
@ -29,11 +29,6 @@ class Socket : public VFS::FileInode
return m_fs; return m_fs;
} }
usize inode_number() const override
{
return m_inode_number;
}
Result<usize> read(u8* buf, usize, usize length) const override Result<usize> read(u8* buf, usize, usize length) const override
{ {
return recv(buf, length, 0); return recv(buf, length, 0);
@ -48,7 +43,7 @@ class Socket : public VFS::FileInode
virtual Result<usize> recv(u8*, usize, int) const = 0; virtual Result<usize> recv(u8*, usize, int) const = 0;
virtual Result<void> bind(SharedPtr<Socket>, struct sockaddr*, socklen_t) = 0; virtual Result<void> bind(struct sockaddr*, socklen_t) = 0;
virtual Result<void> connect(Registers*, int, struct sockaddr*, socklen_t) = 0; virtual Result<void> connect(Registers*, int, struct sockaddr*, socklen_t) = 0;
virtual Result<SharedPtr<OpenFileDescription>> accept(Registers*, int, struct sockaddr**, socklen_t*) = 0; virtual Result<SharedPtr<OpenFileDescription>> accept(Registers*, int, struct sockaddr**, socklen_t*) = 0;
@ -60,61 +55,18 @@ class Socket : public VFS::FileInode
return err(EINVAL); return err(EINVAL);
} }
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;
}
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 void did_link() override
{ {
m_nlinks++; m_metadata.nlinks++;
} }
void did_unlink() override void did_unlink() override
{ {
m_nlinks--; m_metadata.nlinks--;
} }
virtual ~Socket() = default; virtual ~Socket() = default;
protected: protected:
VFS::FileSystem* m_fs { nullptr }; VFS::FileSystem* m_fs { nullptr };
usize m_inode_number { 0 };
mode_t m_mode;
u32 m_uid { 0 };
u32 m_gid { 0 };
u32 m_nlinks { 0 };
}; };

View File

@ -71,7 +71,7 @@ static Result<void> bind_socket_to_fs(const char* path, Credentials auth, Shared
return parent_inode->add_entry(socket, child_name.chars()); return parent_inode->add_entry(socket, child_name.chars());
} }
Result<void> UnixSocket::bind(SharedPtr<Socket> socket, struct sockaddr* addr, socklen_t addrlen) Result<void> UnixSocket::bind(struct sockaddr* addr, socklen_t addrlen)
{ {
if (!addr) return err(EDESTADDRREQ); if (!addr) return err(EDESTADDRREQ);
if (addr->sa_family != AF_UNIX) return err(EAFNOSUPPORT); if (addr->sa_family != AF_UNIX) return err(EAFNOSUPPORT);
@ -87,10 +87,11 @@ Result<void> UnixSocket::bind(SharedPtr<Socket> socket, struct sockaddr* addr, s
auto* current = Scheduler::current(); auto* current = Scheduler::current();
socket->chmod(0777 & ~current->umask); m_metadata.mode = 0777 & ~current->umask;
socket->chown(current->auth.euid, current->auth.egid); m_metadata.uid = current->auth.euid;
m_metadata.gid = current->auth.egid;
auto rc = bind_socket_to_fs(path.chars(), current->auth, current->current_directory, socket); auto rc = bind_socket_to_fs(path.chars(), current->auth, current->current_directory, SharedPtr<Socket> { this });
if (rc.has_error()) if (rc.has_error())
{ {
if (rc.error() == EEXIST) return err(EADDRINUSE); if (rc.error() == EEXIST) return err(EADDRINUSE);

View File

@ -20,7 +20,7 @@ class UnixSocket : public Socket
Result<usize> send(const u8*, usize, int) override; Result<usize> send(const u8*, usize, int) override;
Result<usize> recv(u8*, usize, int) const override; Result<usize> recv(u8*, usize, int) const override;
Result<void> bind(SharedPtr<Socket>, struct sockaddr*, socklen_t) override; Result<void> bind(struct sockaddr*, socklen_t) override;
Result<void> connect(Registers*, int, struct sockaddr*, socklen_t) override; Result<void> connect(Registers*, int, struct sockaddr*, socklen_t) override;
Result<SharedPtr<OpenFileDescription>> accept(Registers*, int, struct sockaddr**, socklen_t*) override; Result<SharedPtr<OpenFileDescription>> accept(Registers*, int, struct sockaddr**, socklen_t*) override;

View File

@ -103,8 +103,8 @@ Result<u64> sys_execve(Registers* regs, SyscallArgs args)
if (descriptor->description->flags & O_CLOEXEC) { descriptor = {}; } if (descriptor->description->flags & O_CLOEXEC) { descriptor = {}; }
} }
if (VFS::is_setuid(inode)) current->auth.euid = current->auth.suid = inode->uid(); if (VFS::is_setuid(inode)) current->auth.euid = current->auth.suid = inode->metadata().uid;
if (VFS::is_setgid(inode)) current->auth.egid = current->auth.sgid = inode->gid(); if (VFS::is_setgid(inode)) current->auth.egid = current->auth.sgid = inode->metadata().gid;
current->name = path.chars(); current->name = path.chars();

View File

@ -64,7 +64,7 @@ Result<u64> sys_write(Registers*, SyscallArgs args)
if (!descriptor.is_writable()) return err(EBADF); if (!descriptor.is_writable()) return err(EBADF);
if (descriptor.should_append() && VFS::is_seekable(descriptor.inode())) if (descriptor.should_append() && VFS::is_seekable(descriptor.inode()))
descriptor.offset = descriptor.inode()->size(); descriptor.offset = descriptor.inode()->metadata().size;
usize nwritten = TRY(descriptor.inode()->write(buf, descriptor.offset, size)); usize nwritten = TRY(descriptor.inode()->write(buf, descriptor.offset, size));
@ -93,7 +93,7 @@ Result<u64> sys_lseek(Registers*, SyscallArgs args)
{ {
case SEEK_SET: new_offset = offset; break; case SEEK_SET: new_offset = offset; break;
case SEEK_CUR: new_offset = TRY(safe_add((long)descriptor.offset, offset)); break; case SEEK_CUR: new_offset = TRY(safe_add((long)descriptor.offset, offset)); break;
case SEEK_END: new_offset = TRY(safe_add((long)descriptor.inode()->size(), offset)); break; case SEEK_END: new_offset = TRY(safe_add((long)descriptor.inode()->metadata().size, offset)); break;
default: return err(EINVAL); default: return err(EINVAL);
} }

View File

@ -26,7 +26,7 @@ Result<u64> sys_getdents(Registers*, SyscallArgs args)
descriptor.offset++; descriptor.offset++;
luna_dirent kent; luna_dirent kent;
kent.inode = entry.inode->inode_number(); kent.inode = entry.inode->metadata().inum;
strlcpy(kent.name, entry.name.chars(), entry.name.length() + 1); strlcpy(kent.name, entry.name.chars(), entry.name.length() + 1);
if (!MemoryManager::copy_to_user_typed(ent, &kent)) return err(EFAULT); if (!MemoryManager::copy_to_user_typed(ent, &kent)) return err(EFAULT);

View File

@ -153,9 +153,11 @@ Result<u64> sys_fchmodat(Registers*, SyscallArgs args)
auto inode = TRY(current->resolve_atfile(dirfd, path, flags & AT_EMPTY_PATH, !(flags & AT_SYMLINK_NOFOLLOW))); auto inode = TRY(current->resolve_atfile(dirfd, path, flags & AT_EMPTY_PATH, !(flags & AT_SYMLINK_NOFOLLOW)));
if (current->auth.euid != 0 && current->auth.euid != inode->uid()) return err(EPERM); if (current->auth.euid != 0 && current->auth.euid != inode->metadata().uid) return err(EPERM);
TRY(inode->chmod(mode)); auto metadata = inode->metadata();
metadata.mode = mode;
TRY(inode->set_metadata(metadata));
return 0; return 0;
} }
@ -164,8 +166,8 @@ Result<u64> sys_fchownat(Registers*, SyscallArgs args)
{ {
int dirfd = (int)args[0]; int dirfd = (int)args[0];
auto path = TRY(MemoryManager::strdup_from_user(args[1])); auto path = TRY(MemoryManager::strdup_from_user(args[1]));
u32 uid = (u32)args[2]; uid_t uid = (u32)args[2];
u32 gid = (u32)args[3]; gid_t gid = (u32)args[3];
int flags = (int)args[4]; int flags = (int)args[4];
auto* current = Scheduler::current(); auto* current = Scheduler::current();
@ -174,7 +176,10 @@ Result<u64> sys_fchownat(Registers*, SyscallArgs args)
if (current->auth.euid != 0) return err(EPERM); if (current->auth.euid != 0) return err(EPERM);
TRY(inode->chown(uid == (u32)-1 ? inode->uid() : uid, gid == (u32)-1 ? inode->gid() : gid)); auto metadata = inode->metadata();
if (uid != (uid_t)-1) metadata.uid = uid;
if (gid != (gid_t)-1) metadata.gid = gid;
TRY(inode->set_metadata(metadata));
return 0; return 0;
} }

View File

@ -26,8 +26,8 @@ Result<u64> sys_unlinkat(Registers*, SyscallArgs args)
auto child = TRY(inode->find(basename.chars())); auto child = TRY(inode->find(basename.chars()));
if (flags == AT_REMOVEDIR && child->type() != VFS::InodeType::Directory) return err(ENOTDIR); if (flags == AT_REMOVEDIR && child->type() != VFS::InodeType::Directory) return err(ENOTDIR);
if (current->auth.euid != 0 && VFS::is_sticky(inode) && current->auth.euid != inode->uid() && if (current->auth.euid != 0 && VFS::is_sticky(inode) && current->auth.euid != inode->metadata().uid &&
current->auth.euid != child->uid()) current->auth.euid != child->metadata().uid)
return err(EACCES); return err(EACCES);
TRY(inode->remove_entry(basename.chars())); TRY(inode->remove_entry(basename.chars()));
@ -56,7 +56,10 @@ Result<u64> sys_symlinkat(Registers*, SyscallArgs args)
TRY(VFS::validate_filename(child_name.view())); TRY(VFS::validate_filename(child_name.view()));
auto inode = TRY(parent_inode->fs()->create_symlink_inode(target.view())); auto inode = TRY(parent_inode->fs()->create_symlink_inode(target.view()));
TRY(inode->chown(current->auth.euid, current->auth.egid)); auto metadata = inode->metadata();
metadata.uid = current->auth.euid;
metadata.gid = current->auth.egid;
TRY(inode->set_metadata(metadata));
TRY(parent_inode->add_entry(inode, child_name.chars())); TRY(parent_inode->add_entry(inode, child_name.chars()));
return 0; return 0;

View File

@ -11,9 +11,12 @@ Result<u64> sys_mkdir(Registers*, SyscallArgs args)
Thread* current = Scheduler::current(); Thread* current = Scheduler::current();
auto inode = TRY(VFS::create_directory(path.chars(), current->auth, current->current_directory)); auto inode =
inode->chmod(mode & ~current->umask); TRY(VFS::create_directory(path.chars(), mode & ~current->umask, current->auth, current->current_directory));
inode->chown(current->auth.euid, current->auth.egid); auto metadata = inode->metadata();
metadata.uid = current->auth.euid;
metadata.gid = current->auth.egid;
TRY(inode->set_metadata(metadata));
return 0; return 0;
} }

View File

@ -17,7 +17,7 @@ Result<u64> sys_mount(Registers*, SyscallArgs args)
auto get_source = [current, &source]() -> Result<SharedPtr<Device>> { auto get_source = [current, &source]() -> Result<SharedPtr<Device>> {
auto inode = TRY(VFS::resolve_path(source.chars(), current->auth, current->current_directory)); auto inode = TRY(VFS::resolve_path(source.chars(), current->auth, current->current_directory));
if (inode->type() != VFS::InodeType::BlockDevice) return err(ENOTBLK); if (inode->type() != VFS::InodeType::BlockDevice) return err(ENOTBLK);
dev_t device_id = inode->device_id(); dev_t device_id = inode->metadata().devid;
return TRY(DeviceRegistry::fetch_special_device(luna_dev_major(device_id), luna_dev_minor(device_id))); return TRY(DeviceRegistry::fetch_special_device(luna_dev_major(device_id), luna_dev_minor(device_id)));
}; };

View File

@ -37,9 +37,12 @@ Result<u64> sys_openat(Registers*, SyscallArgs args)
{ {
if (error == ENOENT && (flags & O_CREAT) && !path.is_empty()) if (error == ENOENT && (flags & O_CREAT) && !path.is_empty())
{ {
inode = TRY(VFS::create_file(path.chars(), current->auth, parent_inode)); inode = TRY(VFS::create_file(path.chars(), mode & ~current->umask, current->auth, parent_inode));
inode->chmod(mode & ~current->umask); // FIXME: Pass these in create_file().
inode->chown(current->auth.euid, current->auth.egid); auto metadata = inode->metadata();
metadata.uid = current->auth.euid;
metadata.gid = current->auth.egid;
TRY(inode->set_metadata(metadata));
} }
else else
return err(error); return err(error);
@ -60,9 +63,11 @@ Result<u64> sys_openat(Registers*, SyscallArgs args)
if (flags & O_TMPFILE) if (flags & O_TMPFILE)
{ {
if (inode->type() != VFS::InodeType::Directory) return err(EINVAL); if (inode->type() != VFS::InodeType::Directory) return err(EINVAL);
inode = TRY(inode->fs()->create_file_inode()); inode = TRY(inode->fs()->create_file_inode(mode & current->umask));
inode->chmod(mode); auto metadata = inode->metadata();
inode->chown(current->auth.euid, current->auth.egid); metadata.uid = current->auth.euid;
metadata.gid = current->auth.egid;
TRY(inode->set_metadata(metadata));
} }
if ((flags & O_WRONLY) && inode->fs() && inode->fs()->is_readonly()) return err(EROFS); if ((flags & O_WRONLY) && inode->fs() && inode->fs()->is_readonly()) return err(EROFS);

View File

@ -43,7 +43,7 @@ Result<u64> sys_bind(Registers*, SyscallArgs args)
auto socket = (SharedPtr<Socket>)inode; auto socket = (SharedPtr<Socket>)inode;
TRY(socket->bind(socket, (struct sockaddr*)&storage, addrlen)); TRY(socket->bind((struct sockaddr*)&storage, addrlen));
return 0; return 0;
} }

View File

@ -38,14 +38,16 @@ Result<u64> sys_fstatat(Registers*, SyscallArgs args)
stat kstat; stat kstat;
kstat.st_ino = inode->inode_number(); const auto& metadata = inode->metadata();
kstat.st_mode = make_mode(inode->mode(), inode->type());
kstat.st_nlink = inode->nlinks(); kstat.st_ino = metadata.inum;
kstat.st_uid = inode->uid(); kstat.st_mode = make_mode(metadata.mode, inode->type());
kstat.st_gid = inode->gid(); kstat.st_nlink = metadata.nlinks;
kstat.st_size = inode->size(); kstat.st_uid = metadata.uid;
kstat.st_gid = metadata.gid;
kstat.st_size = metadata.size;
kstat.st_dev = inode->fs() ? inode->fs()->host_device_id() : 0; kstat.st_dev = inode->fs() ? inode->fs()->host_device_id() : 0;
kstat.st_rdev = inode->device_id(); kstat.st_rdev = metadata.devid;
if (!MemoryManager::copy_to_user_typed(st, &kstat)) return err(EFAULT); if (!MemoryManager::copy_to_user_typed(st, &kstat)) return err(EFAULT);