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
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
4c87d72b44
commit
dc35c42371
@ -18,17 +18,15 @@ void InitRD::initialize()
|
||||
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.error() == EEXIST) return {};
|
||||
return rc.release_error();
|
||||
}
|
||||
auto dir = rc.value();
|
||||
dir->chmod(mode & (mode_t)~S_IFMT);
|
||||
dir->chown(uid, gid);
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -39,14 +37,12 @@ Result<void> InitRD::populate_vfs()
|
||||
{
|
||||
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->chmod(entry.mode & (mode_t)~S_IFMT);
|
||||
file->chown(entry.uid, entry.gid);
|
||||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,39 +42,14 @@ class MountInode : public VFS::Inode, public LinkedListNode<MountInode>
|
||||
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();
|
||||
}
|
||||
|
||||
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);
|
||||
return m_mount_root_inode->set_metadata(metadata);
|
||||
}
|
||||
|
||||
VFS::FileSystem* fs() const override
|
||||
@ -82,11 +57,6 @@ class MountInode : public VFS::Inode, public LinkedListNode<MountInode>
|
||||
return m_mountee.ptr();
|
||||
}
|
||||
|
||||
usize inode_number() const override
|
||||
{
|
||||
return m_mount_root_inode->inode_number();
|
||||
}
|
||||
|
||||
VFS::InodeType type() const override
|
||||
{
|
||||
return VFS::InodeType::Directory;
|
||||
@ -122,14 +92,14 @@ class MountInode : public VFS::Inode, public LinkedListNode<MountInode>
|
||||
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
|
||||
|
@ -14,8 +14,14 @@ Result<void> Pipe::create(SharedPtr<VFS::Inode>& rpipe, SharedPtr<VFS::Inode>& w
|
||||
pipe->m_reader = reader.ptr();
|
||||
|
||||
writer->m_pipe = reader->m_pipe = pipe;
|
||||
writer->chown(auth.euid, auth.egid);
|
||||
reader->chown(auth.euid, auth.egid);
|
||||
writer->m_metadata.inum = 0;
|
||||
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;
|
||||
wpipe = writer;
|
||||
|
@ -45,9 +45,10 @@ class PipeInodeBase : public VFS::FileInode
|
||||
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
|
||||
@ -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
|
||||
{
|
||||
return nullptr;
|
||||
@ -86,8 +70,6 @@ class PipeInodeBase : public VFS::FileInode
|
||||
|
||||
protected:
|
||||
SharedPtr<Pipe> m_pipe;
|
||||
u32 m_uid { 0 };
|
||||
u32 m_gid { 0 };
|
||||
};
|
||||
|
||||
class PipeWriter : public PipeInodeBase
|
||||
@ -104,11 +86,6 @@ class PipeWriter : public PipeInodeBase
|
||||
return m_pipe->write(buf, offset, length);
|
||||
}
|
||||
|
||||
mode_t mode() const override
|
||||
{
|
||||
return 0200;
|
||||
}
|
||||
|
||||
~PipeWriter();
|
||||
|
||||
friend class Pipe;
|
||||
@ -128,11 +105,6 @@ class PipeReader : public PipeInodeBase
|
||||
check(false);
|
||||
}
|
||||
|
||||
mode_t mode() const override
|
||||
{
|
||||
return 0400;
|
||||
}
|
||||
|
||||
~PipeReader();
|
||||
|
||||
friend class Pipe;
|
||||
|
@ -69,7 +69,8 @@ namespace VFS
|
||||
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));
|
||||
|
||||
@ -81,10 +82,11 @@ namespace VFS
|
||||
|
||||
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));
|
||||
|
||||
@ -96,7 +98,7 @@ namespace VFS
|
||||
|
||||
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)
|
||||
@ -135,45 +137,51 @@ namespace VFS
|
||||
{
|
||||
if (auth.euid == 0) return true;
|
||||
|
||||
if (inode->uid() == auth.euid) { return inode->mode() & S_IXUSR; }
|
||||
if (inode->gid() == auth.egid) { return inode->mode() & S_IXGRP; }
|
||||
const auto& metadata = inode->metadata();
|
||||
|
||||
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)
|
||||
{
|
||||
if (auth.euid == 0) return true;
|
||||
|
||||
if (inode->uid() == auth.euid) { return inode->mode() & S_IWUSR; }
|
||||
if (inode->gid() == auth.egid) { return inode->mode() & S_IWGRP; }
|
||||
const auto& metadata = inode->metadata();
|
||||
|
||||
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)
|
||||
{
|
||||
if (auth.euid == 0) return true;
|
||||
|
||||
if (inode->uid() == auth.euid) { return inode->mode() & S_IRUSR; }
|
||||
if (inode->gid() == auth.egid) { return inode->mode() & S_IRGRP; }
|
||||
const auto& metadata = inode->metadata();
|
||||
|
||||
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)
|
||||
{
|
||||
return inode->mode() & S_ISUID;
|
||||
return inode->metadata().mode & S_ISUID;
|
||||
}
|
||||
|
||||
bool is_setgid(SharedPtr<Inode> inode)
|
||||
{
|
||||
return inode->mode() & S_ISGID;
|
||||
return inode->metadata().mode & S_ISGID;
|
||||
}
|
||||
|
||||
bool is_sticky(SharedPtr<Inode> inode)
|
||||
{
|
||||
return inode->mode() & S_ISVTX;
|
||||
return inode->metadata().mode & S_ISVTX;
|
||||
}
|
||||
|
||||
bool is_seekable(SharedPtr<Inode> inode)
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
#include "arch/Timer.h"
|
||||
#include <bits/makedev.h>
|
||||
#include <bits/timespec.h>
|
||||
#include <luna/SharedPtr.h>
|
||||
#include <luna/StaticString.h>
|
||||
#include <luna/StringView.h>
|
||||
@ -20,6 +22,21 @@ namespace VFS
|
||||
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 FileSystem : public Shareable
|
||||
@ -27,11 +44,11 @@ namespace VFS
|
||||
public:
|
||||
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;
|
||||
|
||||
@ -101,9 +118,9 @@ namespace VFS
|
||||
|
||||
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;
|
||||
|
||||
@ -128,29 +145,16 @@ namespace VFS
|
||||
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 usize size() const = 0;
|
||||
|
||||
virtual mode_t mode() const = 0;
|
||||
|
||||
virtual nlink_t nlinks() const
|
||||
virtual Result<void> set_metadata(const InodeMetadata& metadata)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual u32 uid() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual u32 gid() const
|
||||
{
|
||||
return 0;
|
||||
m_metadata = metadata;
|
||||
m_metadata.ctime = *Timer::realtime_clock();
|
||||
return {};
|
||||
}
|
||||
|
||||
virtual bool is_mountpoint() const
|
||||
@ -161,11 +165,6 @@ namespace VFS
|
||||
virtual void did_link() = 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
|
||||
virtual FileSystem* fs() const = 0;
|
||||
|
||||
@ -173,8 +172,6 @@ namespace VFS
|
||||
|
||||
virtual InodeType type() const = 0;
|
||||
|
||||
virtual usize inode_number() const = 0;
|
||||
|
||||
virtual void add_handle()
|
||||
{
|
||||
auto* f = fs();
|
||||
@ -186,9 +183,12 @@ namespace VFS
|
||||
auto* f = fs();
|
||||
if (f) f->remove_handle();
|
||||
}
|
||||
|
||||
protected:
|
||||
mutable InodeMetadata m_metadata;
|
||||
};
|
||||
|
||||
class FileInode : Inode
|
||||
class FileInode : public Inode
|
||||
{
|
||||
public:
|
||||
Result<SharedPtr<Inode>> find(const char*) const override
|
||||
@ -201,12 +201,12 @@ namespace VFS
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<SharedPtr<Inode>> create_file(const char*) override
|
||||
Result<SharedPtr<Inode>> create_file(const char*, mode_t) override
|
||||
{
|
||||
return err(ENOTDIR);
|
||||
}
|
||||
|
||||
Result<SharedPtr<Inode>> create_subdirectory(const char*) override
|
||||
Result<SharedPtr<Inode>> create_subdirectory(const char*, mode_t) override
|
||||
{
|
||||
return err(ENOTDIR);
|
||||
}
|
||||
@ -244,7 +244,7 @@ namespace VFS
|
||||
virtual ~FileInode() = default;
|
||||
};
|
||||
|
||||
class DeviceInode : Inode
|
||||
class DeviceInode : public Inode
|
||||
{
|
||||
public:
|
||||
Result<SharedPtr<Inode>> find(const char*) const override
|
||||
@ -257,12 +257,12 @@ namespace VFS
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<SharedPtr<Inode>> create_file(const char*) override
|
||||
Result<SharedPtr<Inode>> create_file(const char*, mode_t) override
|
||||
{
|
||||
return err(ENOTDIR);
|
||||
}
|
||||
|
||||
Result<SharedPtr<Inode>> create_subdirectory(const char*) override
|
||||
Result<SharedPtr<Inode>> create_subdirectory(const char*, mode_t) override
|
||||
{
|
||||
return err(ENOTDIR);
|
||||
}
|
||||
@ -299,10 +299,10 @@ namespace VFS
|
||||
SharedPtr<VFS::Inode> working_directory = {},
|
||||
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 = {});
|
||||
|
||||
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 = {});
|
||||
|
||||
Result<void> validate_filename(StringView name);
|
||||
|
@ -36,8 +36,7 @@ namespace DeviceRegistry
|
||||
|
||||
Result<void> create_special_device_inode(SharedPtr<VFS::FileSystem> fs, const DeviceDescriptor& descriptor)
|
||||
{
|
||||
auto inode = TRY(fs->create_device_inode(descriptor.major, descriptor.minor));
|
||||
inode->chmod(descriptor.mode);
|
||||
auto inode = TRY(fs->create_device_inode(descriptor.major, descriptor.minor, descriptor.mode));
|
||||
TRY(fs->root_inode()->add_entry(inode, descriptor.name));
|
||||
|
||||
return {};
|
||||
|
@ -49,7 +49,14 @@ namespace Ext2
|
||||
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));
|
||||
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
|
||||
kdbgln("ext2: Read inode %lu with mode %#x (%#x + %#o), size %lu", inum, inode->m_raw_inode.mode,
|
||||
|
@ -127,17 +127,17 @@ namespace Ext2
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
if (length == 0) return 0;
|
||||
|
||||
if (offset > size()) return 0;
|
||||
if (offset + length > size()) length = size() - offset;
|
||||
if (offset > m_metadata.size) return 0;
|
||||
if (offset + length > m_metadata.size) length = m_metadata.size - offset;
|
||||
|
||||
const usize block_size = m_fs->m_block_size;
|
||||
|
||||
@ -95,7 +88,7 @@ namespace Ext2
|
||||
{
|
||||
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;
|
||||
|
||||
u8* const buf = TRY(make_array<u8>(block_size));
|
||||
@ -184,7 +177,7 @@ namespace Ext2
|
||||
|
||||
if (!m_link.is_empty()) return m_link.view();
|
||||
|
||||
const usize length = size();
|
||||
const usize length = m_metadata.size;
|
||||
|
||||
if (length < 60)
|
||||
{
|
||||
|
@ -21,33 +21,6 @@ namespace Ext2
|
||||
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
|
||||
{
|
||||
return m_fs;
|
||||
@ -61,12 +34,7 @@ namespace Ext2
|
||||
{
|
||||
}
|
||||
|
||||
Result<void> chmod(mode_t) override
|
||||
{
|
||||
return err(EROFS);
|
||||
}
|
||||
|
||||
Result<void> chown(u32, u32) override
|
||||
Result<void> set_metadata(const VFS::InodeMetadata&) override
|
||||
{
|
||||
return err(EROFS);
|
||||
}
|
||||
@ -87,14 +55,14 @@ namespace Ext2
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -10,8 +10,7 @@ namespace TmpFS
|
||||
Result<SharedPtr<VFS::FileSystem>> FileSystem::create()
|
||||
{
|
||||
SharedPtr<FileSystem> fs = TRY(adopt_shared_if_nonnull(new (std::nothrow) FileSystem()));
|
||||
SharedPtr<VFS::Inode> root = TRY(fs->create_dir_inode({}));
|
||||
root->chmod(0755);
|
||||
SharedPtr<VFS::Inode> root = TRY(fs->create_dir_inode({}, 0755));
|
||||
fs->set_root(root);
|
||||
return (SharedPtr<VFS::FileSystem>)fs;
|
||||
}
|
||||
@ -21,11 +20,12 @@ namespace TmpFS
|
||||
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>());
|
||||
inode->set_fs(*this, {});
|
||||
inode->set_inode_number(m_next_inode_number++, {});
|
||||
inode->m_metadata.mode = mode;
|
||||
return (SharedPtr<VFS::Inode>)inode;
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ namespace TmpFS
|
||||
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>());
|
||||
|
||||
@ -48,11 +48,12 @@ namespace TmpFS
|
||||
inode->set_self(inode, {});
|
||||
inode->set_fs(*this, {});
|
||||
inode->set_inode_number(m_next_inode_number++, {});
|
||||
inode->m_metadata.mode = mode;
|
||||
|
||||
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));
|
||||
|
||||
@ -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
|
||||
// device ID atm.
|
||||
inode->set_device_id(luna_dev_makedev(major, minor), {});
|
||||
inode->m_metadata.mode = mode;
|
||||
|
||||
return (SharedPtr<VFS::Inode>)inode;
|
||||
}
|
||||
|
@ -13,9 +13,9 @@ namespace TmpFS
|
||||
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<SharedPtr<VFS::Inode>> create_file_inode(mode_t mode) 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, mode_t mode) override;
|
||||
Result<SharedPtr<VFS::Inode>> create_symlink_inode(StringView link) override;
|
||||
|
||||
Result<u64> allocate_inode_number() override;
|
||||
|
@ -62,18 +62,18 @@ namespace TmpFS
|
||||
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));
|
||||
|
||||
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));
|
||||
|
||||
@ -110,6 +110,8 @@ namespace TmpFS
|
||||
u8* slice = TRY(m_data_buffer.slice(offset, length));
|
||||
memcpy(slice, buf, length);
|
||||
|
||||
m_metadata.size = m_data_buffer.size();
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
@ -121,11 +123,8 @@ namespace TmpFS
|
||||
|
||||
if (size > old_size) memset(m_data_buffer.data() + old_size, 0, size - old_size);
|
||||
|
||||
m_metadata.size = m_data_buffer.size();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
usize FileInode::size() const
|
||||
{
|
||||
return m_data_buffer.size();
|
||||
}
|
||||
}
|
||||
|
@ -20,68 +20,27 @@ namespace TmpFS
|
||||
|
||||
void set_inode_number(usize inum, Badge<FileSystem>)
|
||||
{
|
||||
m_inode_number = inum;
|
||||
m_metadata.inum = 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++;
|
||||
m_metadata.nlinks++;
|
||||
}
|
||||
|
||||
void did_unlink() override
|
||||
{
|
||||
m_nlinks--;
|
||||
m_metadata.nlinks--;
|
||||
}
|
||||
|
||||
virtual ~FileInode() = default;
|
||||
@ -89,11 +48,8 @@ namespace TmpFS
|
||||
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 };
|
||||
|
||||
friend class FileSystem;
|
||||
};
|
||||
|
||||
class SymlinkInode : public VFS::FileInode
|
||||
@ -113,7 +69,7 @@ namespace TmpFS
|
||||
|
||||
void set_inode_number(usize inum, Badge<FileSystem>)
|
||||
{
|
||||
m_inode_number = inum;
|
||||
m_metadata.inum = inum;
|
||||
}
|
||||
|
||||
Result<void> set_link(StringView link, Badge<FileSystem>)
|
||||
@ -127,11 +83,6 @@ namespace TmpFS
|
||||
return m_fs;
|
||||
}
|
||||
|
||||
usize inode_number() const override
|
||||
{
|
||||
return m_inode_number;
|
||||
}
|
||||
|
||||
Result<usize> read(u8*, usize, usize) const override
|
||||
{
|
||||
return err(ENOTSUP);
|
||||
@ -147,51 +98,14 @@ namespace TmpFS
|
||||
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++;
|
||||
m_metadata.nlinks++;
|
||||
}
|
||||
|
||||
void did_unlink() override
|
||||
{
|
||||
m_nlinks--;
|
||||
m_metadata.nlinks--;
|
||||
}
|
||||
|
||||
Result<StringView> readlink() override
|
||||
@ -204,10 +118,8 @@ namespace TmpFS
|
||||
private:
|
||||
VFS::FileSystem* m_fs;
|
||||
String m_link;
|
||||
usize m_inode_number;
|
||||
u32 m_uid { 0 };
|
||||
u32 m_gid { 0 };
|
||||
u32 m_nlinks { 0 };
|
||||
|
||||
friend class FileSystem;
|
||||
};
|
||||
|
||||
class DeviceInode : public VFS::DeviceInode
|
||||
@ -227,7 +139,7 @@ namespace TmpFS
|
||||
|
||||
void set_inode_number(usize inum, Badge<FileSystem>)
|
||||
{
|
||||
m_inode_number = inum;
|
||||
m_metadata.inum = inum;
|
||||
}
|
||||
|
||||
void set_device(SharedPtr<Device> device, Badge<FileSystem>)
|
||||
@ -237,7 +149,7 @@ namespace TmpFS
|
||||
|
||||
void set_device_id(dev_t id, Badge<FileSystem>)
|
||||
{
|
||||
m_device_id = id;
|
||||
m_metadata.devid = id;
|
||||
}
|
||||
|
||||
VFS::FileSystem* fs() const override
|
||||
@ -245,16 +157,6 @@ namespace TmpFS
|
||||
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);
|
||||
@ -286,52 +188,14 @@ namespace TmpFS
|
||||
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
|
||||
{
|
||||
m_nlinks++;
|
||||
m_metadata.nlinks++;
|
||||
}
|
||||
|
||||
void did_unlink() override
|
||||
{
|
||||
m_nlinks--;
|
||||
m_metadata.nlinks--;
|
||||
}
|
||||
|
||||
virtual ~DeviceInode() = default;
|
||||
@ -339,12 +203,8 @@ namespace TmpFS
|
||||
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 };
|
||||
|
||||
friend class FileSystem;
|
||||
};
|
||||
|
||||
class DirInode : public VFS::Inode
|
||||
@ -359,7 +219,7 @@ namespace TmpFS
|
||||
|
||||
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>)
|
||||
@ -390,49 +250,11 @@ namespace TmpFS
|
||||
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;
|
||||
@ -455,8 +277,8 @@ namespace TmpFS
|
||||
|
||||
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<SharedPtr<VFS::Inode>> create_file(const char* name, mode_t mode) 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> replace_entry(SharedPtr<VFS::Inode> inode, const char* name);
|
||||
@ -465,13 +287,9 @@ namespace TmpFS
|
||||
|
||||
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;
|
||||
|
||||
friend class FileSystem;
|
||||
};
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ class Socket : public VFS::FileInode
|
||||
|
||||
void set_inode_number(usize inum)
|
||||
{
|
||||
m_inode_number = inum;
|
||||
m_metadata.inum = inum;
|
||||
}
|
||||
|
||||
VFS::FileSystem* fs() const override
|
||||
@ -29,11 +29,6 @@ class Socket : public VFS::FileInode
|
||||
return m_fs;
|
||||
}
|
||||
|
||||
usize inode_number() const override
|
||||
{
|
||||
return m_inode_number;
|
||||
}
|
||||
|
||||
Result<usize> read(u8* buf, usize, usize length) const override
|
||||
{
|
||||
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<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<SharedPtr<OpenFileDescription>> accept(Registers*, int, struct sockaddr**, socklen_t*) = 0;
|
||||
@ -60,61 +55,18 @@ class Socket : public VFS::FileInode
|
||||
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
|
||||
{
|
||||
m_nlinks++;
|
||||
m_metadata.nlinks++;
|
||||
}
|
||||
|
||||
void did_unlink() override
|
||||
{
|
||||
m_nlinks--;
|
||||
m_metadata.nlinks--;
|
||||
}
|
||||
|
||||
virtual ~Socket() = default;
|
||||
|
||||
protected:
|
||||
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 };
|
||||
};
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
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->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();
|
||||
|
||||
socket->chmod(0777 & ~current->umask);
|
||||
socket->chown(current->auth.euid, current->auth.egid);
|
||||
m_metadata.mode = 0777 & ~current->umask;
|
||||
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.error() == EEXIST) return err(EADDRINUSE);
|
||||
|
@ -20,7 +20,7 @@ class UnixSocket : public Socket
|
||||
Result<usize> send(const u8*, usize, int) 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<SharedPtr<OpenFileDescription>> accept(Registers*, int, struct sockaddr**, socklen_t*) override;
|
||||
|
||||
|
@ -103,8 +103,8 @@ Result<u64> sys_execve(Registers* regs, SyscallArgs args)
|
||||
if (descriptor->description->flags & O_CLOEXEC) { descriptor = {}; }
|
||||
}
|
||||
|
||||
if (VFS::is_setuid(inode)) current->auth.euid = current->auth.suid = inode->uid();
|
||||
if (VFS::is_setgid(inode)) current->auth.egid = current->auth.sgid = inode->gid();
|
||||
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->metadata().gid;
|
||||
|
||||
current->name = path.chars();
|
||||
|
||||
|
@ -64,7 +64,7 @@ Result<u64> sys_write(Registers*, SyscallArgs args)
|
||||
if (!descriptor.is_writable()) return err(EBADF);
|
||||
|
||||
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));
|
||||
|
||||
@ -93,7 +93,7 @@ Result<u64> sys_lseek(Registers*, SyscallArgs args)
|
||||
{
|
||||
case SEEK_SET: new_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);
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ Result<u64> sys_getdents(Registers*, SyscallArgs args)
|
||||
descriptor.offset++;
|
||||
|
||||
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);
|
||||
|
||||
if (!MemoryManager::copy_to_user_typed(ent, &kent)) return err(EFAULT);
|
||||
|
@ -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)));
|
||||
|
||||
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;
|
||||
}
|
||||
@ -164,8 +166,8 @@ Result<u64> sys_fchownat(Registers*, SyscallArgs args)
|
||||
{
|
||||
int dirfd = (int)args[0];
|
||||
auto path = TRY(MemoryManager::strdup_from_user(args[1]));
|
||||
u32 uid = (u32)args[2];
|
||||
u32 gid = (u32)args[3];
|
||||
uid_t uid = (u32)args[2];
|
||||
gid_t gid = (u32)args[3];
|
||||
int flags = (int)args[4];
|
||||
|
||||
auto* current = Scheduler::current();
|
||||
@ -174,7 +176,10 @@ Result<u64> sys_fchownat(Registers*, SyscallArgs args)
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -26,8 +26,8 @@ Result<u64> sys_unlinkat(Registers*, SyscallArgs args)
|
||||
auto child = TRY(inode->find(basename.chars()));
|
||||
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() &&
|
||||
current->auth.euid != child->uid())
|
||||
if (current->auth.euid != 0 && VFS::is_sticky(inode) && current->auth.euid != inode->metadata().uid &&
|
||||
current->auth.euid != child->metadata().uid)
|
||||
return err(EACCES);
|
||||
|
||||
TRY(inode->remove_entry(basename.chars()));
|
||||
@ -56,7 +56,10 @@ Result<u64> sys_symlinkat(Registers*, SyscallArgs args)
|
||||
TRY(VFS::validate_filename(child_name.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()));
|
||||
|
||||
return 0;
|
||||
|
@ -11,9 +11,12 @@ Result<u64> sys_mkdir(Registers*, SyscallArgs args)
|
||||
|
||||
Thread* current = Scheduler::current();
|
||||
|
||||
auto inode = TRY(VFS::create_directory(path.chars(), current->auth, current->current_directory));
|
||||
inode->chmod(mode & ~current->umask);
|
||||
inode->chown(current->auth.euid, current->auth.egid);
|
||||
auto inode =
|
||||
TRY(VFS::create_directory(path.chars(), mode & ~current->umask, current->auth, current->current_directory));
|
||||
auto metadata = inode->metadata();
|
||||
metadata.uid = current->auth.euid;
|
||||
metadata.gid = current->auth.egid;
|
||||
TRY(inode->set_metadata(metadata));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ Result<u64> sys_mount(Registers*, SyscallArgs args)
|
||||
auto get_source = [current, &source]() -> Result<SharedPtr<Device>> {
|
||||
auto inode = TRY(VFS::resolve_path(source.chars(), current->auth, current->current_directory));
|
||||
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)));
|
||||
};
|
||||
|
||||
|
@ -37,9 +37,12 @@ Result<u64> sys_openat(Registers*, SyscallArgs args)
|
||||
{
|
||||
if (error == ENOENT && (flags & O_CREAT) && !path.is_empty())
|
||||
{
|
||||
inode = TRY(VFS::create_file(path.chars(), current->auth, parent_inode));
|
||||
inode->chmod(mode & ~current->umask);
|
||||
inode->chown(current->auth.euid, current->auth.egid);
|
||||
inode = TRY(VFS::create_file(path.chars(), mode & ~current->umask, current->auth, parent_inode));
|
||||
// FIXME: Pass these in create_file().
|
||||
auto metadata = inode->metadata();
|
||||
metadata.uid = current->auth.euid;
|
||||
metadata.gid = current->auth.egid;
|
||||
TRY(inode->set_metadata(metadata));
|
||||
}
|
||||
else
|
||||
return err(error);
|
||||
@ -60,9 +63,11 @@ Result<u64> sys_openat(Registers*, SyscallArgs args)
|
||||
if (flags & O_TMPFILE)
|
||||
{
|
||||
if (inode->type() != VFS::InodeType::Directory) return err(EINVAL);
|
||||
inode = TRY(inode->fs()->create_file_inode());
|
||||
inode->chmod(mode);
|
||||
inode->chown(current->auth.euid, current->auth.egid);
|
||||
inode = TRY(inode->fs()->create_file_inode(mode & current->umask));
|
||||
auto metadata = inode->metadata();
|
||||
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);
|
||||
|
@ -43,7 +43,7 @@ Result<u64> sys_bind(Registers*, SyscallArgs args)
|
||||
|
||||
auto socket = (SharedPtr<Socket>)inode;
|
||||
|
||||
TRY(socket->bind(socket, (struct sockaddr*)&storage, addrlen));
|
||||
TRY(socket->bind((struct sockaddr*)&storage, addrlen));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -38,14 +38,16 @@ Result<u64> sys_fstatat(Registers*, SyscallArgs args)
|
||||
|
||||
stat kstat;
|
||||
|
||||
kstat.st_ino = inode->inode_number();
|
||||
kstat.st_mode = make_mode(inode->mode(), inode->type());
|
||||
kstat.st_nlink = inode->nlinks();
|
||||
kstat.st_uid = inode->uid();
|
||||
kstat.st_gid = inode->gid();
|
||||
kstat.st_size = inode->size();
|
||||
const auto& metadata = inode->metadata();
|
||||
|
||||
kstat.st_ino = metadata.inum;
|
||||
kstat.st_mode = make_mode(metadata.mode, inode->type());
|
||||
kstat.st_nlink = metadata.nlinks;
|
||||
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_rdev = inode->device_id();
|
||||
kstat.st_rdev = metadata.devid;
|
||||
|
||||
if (!MemoryManager::copy_to_user_typed(st, &kstat)) return err(EFAULT);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user