mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:37:35 +00:00
Kernel+LibC: Turn errno codes into a strongly typed enum
..and allow implicit creation of KResult and KResultOr from ErrnoCode. This means that kernel functions that return those types can finally do "return EINVAL;" and it will just work. There's a handful of functions that still deal with signed integers that should be converted to return KResults.
This commit is contained in:
parent
e279b45aed
commit
19d3f8cab7
48 changed files with 591 additions and 506 deletions
|
@ -42,10 +42,10 @@ AnonymousFile::~AnonymousFile()
|
|||
KResultOr<Region*> AnonymousFile::mmap(Process& process, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared)
|
||||
{
|
||||
if (offset != 0)
|
||||
return KResult(-EINVAL);
|
||||
return EINVAL;
|
||||
|
||||
if (size != m_vmobject->size())
|
||||
return KResult(-EINVAL);
|
||||
return EINVAL;
|
||||
|
||||
return process.allocate_region_with_vmobject(preferred_vaddr, size, m_vmobject, offset, {}, prot, shared);
|
||||
}
|
||||
|
|
|
@ -46,8 +46,8 @@ private:
|
|||
virtual String absolute_path(const FileDescription&) const override { return ":anonymous-file:"; }
|
||||
virtual bool can_read(const FileDescription&, size_t) const override { return false; }
|
||||
virtual bool can_write(const FileDescription&, size_t) const override { return false; }
|
||||
virtual KResultOr<size_t> read(FileDescription&, size_t, UserOrKernelBuffer&, size_t) override { return KResult(-ENOTSUP); }
|
||||
virtual KResultOr<size_t> write(FileDescription&, size_t, const UserOrKernelBuffer&, size_t) override { return KResult(-ENOTSUP); }
|
||||
virtual KResultOr<size_t> read(FileDescription&, size_t, UserOrKernelBuffer&, size_t) override { return ENOTSUP; }
|
||||
virtual KResultOr<size_t> write(FileDescription&, size_t, const UserOrKernelBuffer&, size_t) override { return ENOTSUP; }
|
||||
|
||||
explicit AnonymousFile(NonnullRefPtr<AnonymousVMObject>);
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ KResult BlockBasedFS::write_block(unsigned index, const UserOrKernelBuffer& data
|
|||
return result;
|
||||
}
|
||||
if (!data.read(entry.data + offset, count))
|
||||
return KResult(-EFAULT);
|
||||
return EFAULT;
|
||||
|
||||
cache().mark_dirty(entry);
|
||||
entry.has_data = true;
|
||||
|
@ -261,7 +261,7 @@ KResult BlockBasedFS::read_block(unsigned index, UserOrKernelBuffer* buffer, siz
|
|||
entry.has_data = true;
|
||||
}
|
||||
if (buffer && !buffer->write(entry.data + offset, count))
|
||||
return KResult(-EFAULT);
|
||||
return EFAULT;
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
|
@ -269,7 +269,7 @@ KResult BlockBasedFS::read_blocks(unsigned index, unsigned count, UserOrKernelBu
|
|||
{
|
||||
ASSERT(m_logical_block_size);
|
||||
if (!count)
|
||||
return KResult(-EINVAL);
|
||||
return EINVAL;
|
||||
if (count == 1)
|
||||
return read_block(index, &buffer, block_size(), 0, allow_cache);
|
||||
auto out = buffer;
|
||||
|
|
|
@ -124,17 +124,17 @@ ssize_t DevFSInode::write_bytes(off_t, ssize_t, const UserOrKernelBuffer&, FileD
|
|||
|
||||
KResultOr<NonnullRefPtr<Inode>> DevFSInode::create_child(const String&, mode_t, dev_t, uid_t, gid_t)
|
||||
{
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
}
|
||||
|
||||
KResult DevFSInode::add_child(Inode&, const StringView&, mode_t)
|
||||
{
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
}
|
||||
|
||||
KResult DevFSInode::remove_child(const StringView&)
|
||||
{
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
}
|
||||
|
||||
KResultOr<size_t> DevFSInode::directory_entry_count() const
|
||||
|
@ -144,17 +144,17 @@ KResultOr<size_t> DevFSInode::directory_entry_count() const
|
|||
|
||||
KResult DevFSInode::chmod(mode_t)
|
||||
{
|
||||
return KResult(-EPERM);
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
KResult DevFSInode::chown(uid_t, gid_t)
|
||||
{
|
||||
return KResult(-EPERM);
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
KResult DevFSInode::truncate(u64)
|
||||
{
|
||||
return KResult(-EPERM);
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
String DevFSLinkInode::name() const
|
||||
|
@ -221,7 +221,7 @@ InodeMetadata DevFSDirectoryInode::metadata() const
|
|||
KResult DevFSDirectoryInode::traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const
|
||||
{
|
||||
LOCKER(m_lock);
|
||||
return KResult(-EINVAL);
|
||||
return EINVAL;
|
||||
}
|
||||
RefPtr<Inode> DevFSDirectoryInode::lookup(StringView)
|
||||
{
|
||||
|
@ -288,10 +288,10 @@ KResultOr<NonnullRefPtr<Inode>> DevFSRootDirectoryInode::create_child(const Stri
|
|||
if (metadata.is_directory()) {
|
||||
for (auto& folder : m_subfolders) {
|
||||
if (folder.name() == name)
|
||||
return KResult(-EEXIST);
|
||||
return EEXIST;
|
||||
}
|
||||
if (name != "pts")
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
auto new_directory_inode = adopt(*new DevFSPtsDirectoryInode(m_parent_fs));
|
||||
m_subfolders.append(new_directory_inode);
|
||||
m_parent_fs.m_nodes.append(new_directory_inode);
|
||||
|
@ -300,7 +300,7 @@ KResultOr<NonnullRefPtr<Inode>> DevFSRootDirectoryInode::create_child(const Stri
|
|||
if (metadata.is_symlink()) {
|
||||
for (auto& link : m_links) {
|
||||
if (link.name() == name)
|
||||
return KResult(-EEXIST);
|
||||
return EEXIST;
|
||||
}
|
||||
dbgln("DevFS: Success on create new symlink");
|
||||
auto new_link_inode = adopt(*new DevFSLinkInode(m_parent_fs, name));
|
||||
|
@ -308,7 +308,7 @@ KResultOr<NonnullRefPtr<Inode>> DevFSRootDirectoryInode::create_child(const Stri
|
|||
m_parent_fs.m_nodes.append(new_link_inode);
|
||||
return new_link_inode;
|
||||
}
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
}
|
||||
|
||||
DevFSRootDirectoryInode::~DevFSRootDirectoryInode()
|
||||
|
|
|
@ -143,7 +143,7 @@ InodeMetadata DevPtsFSInode::metadata() const
|
|||
KResult DevPtsFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)> callback) const
|
||||
{
|
||||
if (identifier().index() > 1)
|
||||
return KResult(-ENOTDIR);
|
||||
return ENOTDIR;
|
||||
|
||||
callback({ ".", identifier(), 0 });
|
||||
callback({ "..", identifier(), 0 });
|
||||
|
@ -187,27 +187,27 @@ void DevPtsFSInode::flush_metadata()
|
|||
|
||||
KResult DevPtsFSInode::add_child(Inode&, const StringView&, mode_t)
|
||||
{
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
}
|
||||
|
||||
KResultOr<NonnullRefPtr<Inode>> DevPtsFSInode::create_child(const String&, mode_t, dev_t, uid_t, gid_t)
|
||||
{
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
}
|
||||
|
||||
KResult DevPtsFSInode::remove_child(const StringView&)
|
||||
{
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
}
|
||||
|
||||
KResult DevPtsFSInode::chmod(mode_t)
|
||||
{
|
||||
return KResult(-EPERM);
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
KResult DevPtsFSInode::chown(uid_t, gid_t)
|
||||
{
|
||||
return KResult(-EPERM);
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -233,7 +233,7 @@ Ext2FS::BlockListShape Ext2FS::compute_block_list_shape(unsigned blocks) const
|
|||
return {};
|
||||
}
|
||||
|
||||
bool Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2inode, const Vector<BlockIndex>& blocks)
|
||||
KResult Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2inode, const Vector<BlockIndex>& blocks)
|
||||
{
|
||||
LOCKER(m_lock);
|
||||
|
||||
|
@ -241,7 +241,7 @@ bool Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2in
|
|||
e2inode.i_blocks = 0;
|
||||
memset(e2inode.i_block, 0, sizeof(e2inode.i_block));
|
||||
write_ext2_inode(inode_index, e2inode);
|
||||
return true;
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
// NOTE: There is a mismatch between i_blocks and blocks.size() since i_blocks includes meta blocks and blocks.size() does not.
|
||||
|
@ -279,7 +279,7 @@ bool Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2in
|
|||
}
|
||||
|
||||
if (!remaining_blocks)
|
||||
return true;
|
||||
return KSuccess;
|
||||
|
||||
const unsigned entries_per_block = EXT2_ADDR_PER_BLOCK(&super_block());
|
||||
|
||||
|
@ -315,12 +315,13 @@ bool Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2in
|
|||
stream.fill_to_end(0);
|
||||
|
||||
auto buffer = UserOrKernelBuffer::for_kernel_buffer(stream.data());
|
||||
int err = write_block(e2inode.i_block[EXT2_IND_BLOCK], buffer, stream.size());
|
||||
ASSERT(err >= 0);
|
||||
auto result = write_block(e2inode.i_block[EXT2_IND_BLOCK], buffer, stream.size());
|
||||
if (result.is_error())
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!remaining_blocks)
|
||||
return true;
|
||||
return KSuccess;
|
||||
|
||||
bool dind_block_dirty = false;
|
||||
|
||||
|
@ -356,9 +357,8 @@ bool Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2in
|
|||
auto buffer = UserOrKernelBuffer::for_kernel_buffer(dind_block_contents.data());
|
||||
auto result = read_block(e2inode.i_block[EXT2_DIND_BLOCK], &buffer, block_size());
|
||||
if (result.is_error()) {
|
||||
// FIXME: Propagate the error
|
||||
dbgln("Ext2FS: write_block_list_for_inode had error: {}", result.error());
|
||||
return false;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
auto* dind_block_as_pointers = (unsigned*)dind_block_contents.data();
|
||||
|
@ -384,9 +384,8 @@ bool Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2in
|
|||
auto buffer = UserOrKernelBuffer::for_kernel_buffer(ind_block_contents.data());
|
||||
auto result = read_block(indirect_block_index, &buffer, block_size());
|
||||
if (result.is_error()) {
|
||||
// FIXME: Propagate the error
|
||||
dbgln("Ext2FS: write_block_list_for_inode had error: {}", result.error());
|
||||
return false;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
auto* ind_block_as_pointers = (unsigned*)ind_block_contents.data();
|
||||
|
@ -432,7 +431,7 @@ bool Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2in
|
|||
}
|
||||
|
||||
if (!remaining_blocks)
|
||||
return true;
|
||||
return KSuccess;
|
||||
|
||||
// FIXME: Implement!
|
||||
dbgln("we don't know how to write tind ext2fs blocks yet!");
|
||||
|
@ -799,7 +798,7 @@ KResult Ext2FSInode::resize(u64 new_size)
|
|||
if (blocks_needed_after > blocks_needed_before) {
|
||||
u32 additional_blocks_needed = blocks_needed_after - blocks_needed_before;
|
||||
if (additional_blocks_needed > fs().super_block().s_free_blocks_count)
|
||||
return KResult(-ENOSPC);
|
||||
return ENOSPC;
|
||||
}
|
||||
|
||||
Vector<Ext2FS::BlockIndex> block_list;
|
||||
|
@ -825,9 +824,9 @@ KResult Ext2FSInode::resize(u64 new_size)
|
|||
}
|
||||
}
|
||||
|
||||
int err = fs().write_block_list_for_inode(index(), m_raw_inode, block_list);
|
||||
if (err < 0)
|
||||
return KResult(err);
|
||||
auto result = fs().write_block_list_for_inode(index(), m_raw_inode, block_list);
|
||||
if (result.is_error())
|
||||
return result;
|
||||
|
||||
m_raw_inode.i_size = new_size;
|
||||
set_metadata_dirty(true);
|
||||
|
@ -844,7 +843,7 @@ KResult Ext2FSInode::resize(u64 new_size)
|
|||
while (bytes_to_clear) {
|
||||
auto nwritten = write_bytes(clear_from, min(sizeof(zero_buffer), bytes_to_clear), UserOrKernelBuffer::for_kernel_buffer(zero_buffer), nullptr);
|
||||
if (nwritten < 0)
|
||||
return KResult(-nwritten);
|
||||
return KResult((ErrnoCode)-nwritten);
|
||||
ASSERT(nwritten != 0);
|
||||
bytes_to_clear -= nwritten;
|
||||
clear_from += nwritten;
|
||||
|
@ -1056,7 +1055,7 @@ KResult Ext2FSInode::add_child(Inode& child, const StringView& name, mode_t mode
|
|||
ASSERT(is_directory());
|
||||
|
||||
if (name.length() > EXT2_NAME_LEN)
|
||||
return KResult(-ENAMETOOLONG);
|
||||
return ENAMETOOLONG;
|
||||
|
||||
#ifdef EXT2_DEBUG
|
||||
dbgln("Ext2FSInode::add_child: Adding inode {} with name '{}' and mode {:o} to directory {}", child.index(), name, mode, index());
|
||||
|
@ -1078,7 +1077,7 @@ KResult Ext2FSInode::add_child(Inode& child, const StringView& name, mode_t mode
|
|||
|
||||
if (name_already_exists) {
|
||||
dbgln("Ext2FSInode::add_child: Name '{}' already exists in inode {}", name, index());
|
||||
return KResult(-EEXIST);
|
||||
return EEXIST;
|
||||
}
|
||||
|
||||
result = child.increment_link_count();
|
||||
|
@ -1104,7 +1103,7 @@ KResult Ext2FSInode::remove_child(const StringView& name)
|
|||
|
||||
auto it = m_lookup_cache.find(name);
|
||||
if (it == m_lookup_cache.end())
|
||||
return KResult(-ENOENT);
|
||||
return ENOENT;
|
||||
auto child_inode_index = (*it).value;
|
||||
|
||||
InodeIdentifier child_id { fsid(), child_inode_index };
|
||||
|
@ -1125,7 +1124,7 @@ KResult Ext2FSInode::remove_child(const StringView& name)
|
|||
bool success = write_directory(entries);
|
||||
if (!success) {
|
||||
// FIXME: Plumb error from write_directory().
|
||||
return KResult(-EIO);
|
||||
return EIO;
|
||||
}
|
||||
|
||||
m_lookup_cache.remove(name);
|
||||
|
@ -1487,10 +1486,10 @@ KResultOr<NonnullRefPtr<Inode>> Ext2FS::create_inode(InodeIdentifier parent_id,
|
|||
ASSERT(parent_inode);
|
||||
|
||||
if (static_cast<const Ext2FSInode&>(*parent_inode).m_raw_inode.i_links_count == 0)
|
||||
return KResult(-ENOENT);
|
||||
return ENOENT;
|
||||
|
||||
if (name.length() > EXT2_NAME_LEN)
|
||||
return KResult(-ENAMETOOLONG);
|
||||
return ENAMETOOLONG;
|
||||
|
||||
#ifdef EXT2_DEBUG
|
||||
dbgln("Ext2FS: Adding inode '{}' (mode {:o}) to parent directory {}", name, mode, parent_inode->index());
|
||||
|
@ -1499,14 +1498,14 @@ KResultOr<NonnullRefPtr<Inode>> Ext2FS::create_inode(InodeIdentifier parent_id,
|
|||
size_t needed_blocks = ceil_div(static_cast<size_t>(size), block_size());
|
||||
if ((size_t)needed_blocks > super_block().s_free_blocks_count) {
|
||||
dbgln("Ext2FS: create_inode: not enough free blocks");
|
||||
return KResult(-ENOSPC);
|
||||
return ENOSPC;
|
||||
}
|
||||
|
||||
// NOTE: This doesn't commit the inode allocation just yet!
|
||||
auto inode_id = find_a_free_inode(0, size);
|
||||
if (!inode_id) {
|
||||
klog() << "Ext2FS: create_inode: allocate_inode failed";
|
||||
return KResult(-ENOSPC);
|
||||
return ENOSPC;
|
||||
}
|
||||
|
||||
auto blocks = allocate_blocks(group_index_from_inode(inode_id), needed_blocks);
|
||||
|
@ -1537,8 +1536,9 @@ KResultOr<NonnullRefPtr<Inode>> Ext2FS::create_inode(InodeIdentifier parent_id,
|
|||
else if (is_block_device(mode))
|
||||
e2inode.i_block[1] = dev;
|
||||
|
||||
success = write_block_list_for_inode(inode_id, e2inode, blocks);
|
||||
ASSERT(success);
|
||||
auto result = write_block_list_for_inode(inode_id, e2inode, blocks);
|
||||
if (result.is_error())
|
||||
return result;
|
||||
|
||||
#ifdef EXT2_DEBUG
|
||||
dbgln("Ext2FS: writing initial metadata for inode {}", inode_id);
|
||||
|
@ -1554,8 +1554,9 @@ KResultOr<NonnullRefPtr<Inode>> Ext2FS::create_inode(InodeIdentifier parent_id,
|
|||
// If we've already computed a block list, no sense in throwing it away.
|
||||
static_cast<Ext2FSInode&>(*inode).m_block_list = move(blocks);
|
||||
|
||||
auto result = parent_inode->add_child(*inode, name, mode);
|
||||
ASSERT(result.is_success());
|
||||
result = parent_inode->add_child(*inode, name, mode);
|
||||
if (result.is_error())
|
||||
return result;
|
||||
|
||||
return inode.release_nonnull();
|
||||
}
|
||||
|
@ -1632,9 +1633,9 @@ KResult Ext2FSInode::increment_link_count()
|
|||
{
|
||||
LOCKER(m_lock);
|
||||
if (fs().is_readonly())
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
if (m_raw_inode.i_links_count == max_link_count)
|
||||
return KResult(-EMLINK);
|
||||
return EMLINK;
|
||||
++m_raw_inode.i_links_count;
|
||||
set_metadata_dirty(true);
|
||||
return KSuccess;
|
||||
|
@ -1644,7 +1645,7 @@ KResult Ext2FSInode::decrement_link_count()
|
|||
{
|
||||
LOCKER(m_lock);
|
||||
if (fs().is_readonly())
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
ASSERT(m_raw_inode.i_links_count);
|
||||
--m_raw_inode.i_links_count;
|
||||
if (ref_count() == 1 && m_raw_inode.i_links_count == 0)
|
||||
|
@ -1730,7 +1731,7 @@ KResult Ext2FS::prepare_to_unmount() const
|
|||
|
||||
for (auto& it : m_inode_cache) {
|
||||
if (it.value->ref_count() > 1)
|
||||
return KResult(-EBUSY);
|
||||
return EBUSY;
|
||||
}
|
||||
|
||||
m_inode_cache.clear();
|
||||
|
|
|
@ -148,7 +148,7 @@ private:
|
|||
|
||||
Vector<BlockIndex> block_list_for_inode_impl(const ext2_inode&, bool include_block_list_blocks = false) const;
|
||||
Vector<BlockIndex> block_list_for_inode(const ext2_inode&, bool include_block_list_blocks = false) const;
|
||||
bool write_block_list_for_inode(InodeIndex, ext2_inode&, const Vector<BlockIndex>&);
|
||||
KResult write_block_list_for_inode(InodeIndex, ext2_inode&, const Vector<BlockIndex>&);
|
||||
|
||||
bool get_inode_allocation_state(InodeIndex) const;
|
||||
bool set_inode_allocation_state(InodeIndex, bool);
|
||||
|
|
|
@ -61,7 +61,7 @@ int File::ioctl(FileDescription&, unsigned, FlatPtr)
|
|||
|
||||
KResultOr<Region*> File::mmap(Process&, FileDescription&, VirtualAddress, size_t, size_t, int, bool)
|
||||
{
|
||||
return KResult(-ENODEV);
|
||||
return ENODEV;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -115,13 +115,13 @@ public:
|
|||
virtual KResultOr<size_t> write(FileDescription&, size_t, const UserOrKernelBuffer&, size_t) = 0;
|
||||
virtual int ioctl(FileDescription&, unsigned request, FlatPtr arg);
|
||||
virtual KResultOr<Region*> mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared);
|
||||
virtual KResult stat(::stat&) const { return KResult(-EBADF); }
|
||||
virtual KResult stat(::stat&) const { return EBADF; }
|
||||
|
||||
virtual String absolute_path(const FileDescription&) const = 0;
|
||||
|
||||
virtual KResult truncate(u64) { return KResult(-EINVAL); }
|
||||
virtual KResult chown(FileDescription&, uid_t, gid_t) { return KResult(-EBADF); }
|
||||
virtual KResult chmod(FileDescription&, mode_t) { return KResult(-EBADF); }
|
||||
virtual KResult truncate(u64) { return EINVAL; }
|
||||
virtual KResult chown(FileDescription&, uid_t, gid_t) { return EBADF; }
|
||||
virtual KResult chmod(FileDescription&, mode_t) { return EBADF; }
|
||||
|
||||
virtual const char* class_name() const = 0;
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ KResultOr<NonnullOwnPtr<KBuffer>> Inode::read_entire(FileDescription* descriptio
|
|||
auto buf = UserOrKernelBuffer::for_kernel_buffer(buffer);
|
||||
nread = read_bytes(offset, sizeof(buffer), buf, description);
|
||||
if (nread < 0)
|
||||
return KResult(nread);
|
||||
return KResult((ErrnoCode)-nread);
|
||||
ASSERT(nread <= (ssize_t)sizeof(buffer));
|
||||
if (nread <= 0)
|
||||
break;
|
||||
|
@ -93,12 +93,12 @@ KResultOr<NonnullOwnPtr<KBuffer>> Inode::read_entire(FileDescription* descriptio
|
|||
}
|
||||
if (nread < 0) {
|
||||
klog() << "Inode::read_entire: ERROR: " << nread;
|
||||
return KResult(nread);
|
||||
return KResult((ErrnoCode)-nread);
|
||||
}
|
||||
|
||||
auto entire_file = builder.build();
|
||||
if (!entire_file)
|
||||
return KResult(-ENOMEM);
|
||||
return ENOMEM;
|
||||
return entire_file.release_nonnull();
|
||||
}
|
||||
|
||||
|
@ -168,12 +168,12 @@ int Inode::set_mtime(time_t)
|
|||
|
||||
KResult Inode::increment_link_count()
|
||||
{
|
||||
return KResult(-ENOTIMPL);
|
||||
return ENOTIMPL;
|
||||
}
|
||||
|
||||
KResult Inode::decrement_link_count()
|
||||
{
|
||||
return KResult(-ENOTIMPL);
|
||||
return ENOTIMPL;
|
||||
}
|
||||
|
||||
void Inode::set_shared_vmobject(SharedInodeVMObject& vmobject)
|
||||
|
@ -271,7 +271,7 @@ KResult Inode::prepare_to_write_data()
|
|||
// We should funnel everything through an interface at the VFS layer so this can happen from a single place.
|
||||
LOCKER(m_lock);
|
||||
if (fs().is_readonly())
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
auto metadata = this->metadata();
|
||||
if (metadata.is_setuid() || metadata.is_setgid()) {
|
||||
dbgln("Inode::prepare_to_write_data(): Stripping SUID/SGID bits from {}", identifier());
|
||||
|
|
|
@ -52,7 +52,7 @@ KResultOr<size_t> InodeFile::read(FileDescription& description, size_t offset, U
|
|||
evaluate_block_conditions();
|
||||
}
|
||||
if (nread < 0)
|
||||
return KResult(nread);
|
||||
return KResult((ErrnoCode)-nread);
|
||||
return nread;
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ KResultOr<size_t> InodeFile::write(FileDescription& description, size_t offset,
|
|||
evaluate_block_conditions();
|
||||
}
|
||||
if (nwritten < 0)
|
||||
return KResult(nwritten);
|
||||
return KResult((ErrnoCode)-nwritten);
|
||||
return nwritten;
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ KResultOr<Region*> InodeFile::mmap(Process& process, FileDescription& descriptio
|
|||
else
|
||||
vmobject = PrivateInodeVMObject::create_with_inode(inode());
|
||||
if (!vmobject)
|
||||
return KResult(-ENOMEM);
|
||||
return ENOMEM;
|
||||
return process.allocate_region_with_vmobject(preferred_vaddr, size, *vmobject, offset, description.absolute_path(), prot, shared);
|
||||
}
|
||||
|
||||
|
@ -95,8 +95,8 @@ KResult InodeFile::truncate(u64 size)
|
|||
if (truncate_result.is_error())
|
||||
return truncate_result;
|
||||
int mtime_result = m_inode->set_mtime(kgettimeofday().tv_sec);
|
||||
if (mtime_result != 0)
|
||||
return KResult(mtime_result);
|
||||
if (mtime_result < 0)
|
||||
return KResult((ErrnoCode)-mtime_result);
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ struct InodeMetadata {
|
|||
KResult stat(stat& buffer) const
|
||||
{
|
||||
if (!is_valid())
|
||||
return KResult(-EIO);
|
||||
return EIO;
|
||||
buffer.st_rdev = encoded_device(major_device, minor_device);
|
||||
buffer.st_ino = inode.index();
|
||||
buffer.st_mode = mode;
|
||||
|
|
|
@ -77,14 +77,14 @@ KResultOr<size_t> InodeWatcher::read(FileDescription&, size_t, UserOrKernelBuffe
|
|||
return (ssize_t)data_bytes;
|
||||
});
|
||||
if (nwritten < 0)
|
||||
return KResult(nwritten);
|
||||
return KResult((ErrnoCode)-nwritten);
|
||||
evaluate_block_conditions();
|
||||
return bytes_to_write;
|
||||
}
|
||||
|
||||
KResultOr<size_t> InodeWatcher::write(FileDescription&, size_t, const UserOrKernelBuffer&, size_t)
|
||||
{
|
||||
return KResult(-EIO);
|
||||
return EIO;
|
||||
}
|
||||
|
||||
String InodeWatcher::absolute_path(const FileDescription&) const
|
||||
|
|
|
@ -532,7 +532,7 @@ KResult Plan9FS::post_message(Message& message, RefPtr<ReceiveCompletion> comple
|
|||
if (!description.can_write()) {
|
||||
auto unblock_flags = Thread::FileBlocker::BlockFlags::None;
|
||||
if (Thread::current()->block<Thread::WriteBlocker>({}, description, unblock_flags).was_interrupted())
|
||||
return KResult(-EINTR);
|
||||
return EINTR;
|
||||
}
|
||||
auto data_buffer = UserOrKernelBuffer::for_kernel_buffer(const_cast<u8*>(data));
|
||||
auto nwritten_or_error = description.write(data_buffer, size);
|
||||
|
@ -553,7 +553,7 @@ KResult Plan9FS::do_read(u8* data, size_t size)
|
|||
if (!description.can_read()) {
|
||||
auto unblock_flags = Thread::FileBlocker::BlockFlags::None;
|
||||
if (Thread::current()->block<Thread::ReadBlocker>({}, description, unblock_flags).was_interrupted())
|
||||
return KResult(-EINTR);
|
||||
return EINTR;
|
||||
}
|
||||
auto data_buffer = UserOrKernelBuffer::for_kernel_buffer(data);
|
||||
auto nread_or_error = description.read(data_buffer, size);
|
||||
|
@ -561,7 +561,7 @@ KResult Plan9FS::do_read(u8* data, size_t size)
|
|||
return nread_or_error.error();
|
||||
auto nread = nread_or_error.value();
|
||||
if (nread == 0)
|
||||
return KResult(-EIO);
|
||||
return EIO;
|
||||
data += nread;
|
||||
size -= nread;
|
||||
}
|
||||
|
@ -582,7 +582,7 @@ KResult Plan9FS::read_and_dispatch_one_message()
|
|||
|
||||
auto buffer = KBuffer::try_create_with_size(header.size, Region::Access::Read | Region::Access::Write);
|
||||
if (!buffer)
|
||||
return KResult(-ENOMEM);
|
||||
return ENOMEM;
|
||||
// Copy the already read header into the buffer.
|
||||
memcpy(buffer->data(), &header, sizeof(header));
|
||||
result = do_read(buffer->data() + sizeof(header), header.size - sizeof(header));
|
||||
|
@ -622,11 +622,11 @@ KResult Plan9FS::post_message_and_wait_for_a_reply(Message& message)
|
|||
if (result.is_error())
|
||||
return result;
|
||||
if (Thread::current()->block<Plan9FS::Blocker>({}, *this, message, completion).was_interrupted())
|
||||
return KResult(-EINTR);
|
||||
return EINTR;
|
||||
|
||||
if (completion->result.is_error()) {
|
||||
dbgln("Plan9FS: Message was aborted with error {}", completion->result.error());
|
||||
return KResult(-EIO);
|
||||
return EIO;
|
||||
}
|
||||
|
||||
auto reply_type = message.type();
|
||||
|
@ -635,7 +635,7 @@ KResult Plan9FS::post_message_and_wait_for_a_reply(Message& message)
|
|||
// Contains a numerical Linux errno; hopefully our errno numbers match.
|
||||
u32 error_code;
|
||||
message >> error_code;
|
||||
return KResult(-error_code);
|
||||
return KResult((ErrnoCode)error_code);
|
||||
} else if (reply_type == Message::Type::Rerror) {
|
||||
// Contains an error message. We could attempt to parse it, but for now
|
||||
// we simply return -EIO instead. In 9P200.u, it can also contain a
|
||||
|
@ -643,12 +643,12 @@ KResult Plan9FS::post_message_and_wait_for_a_reply(Message& message)
|
|||
StringView error_name;
|
||||
message >> error_name;
|
||||
dbgln("Plan9FS: Received error name {}", error_name);
|
||||
return KResult(-EIO);
|
||||
return EIO;
|
||||
} else if ((u8)reply_type != (u8)request_type + 1) {
|
||||
// Other than those error messages. we only expect the matching reply
|
||||
// message type.
|
||||
dbgln("Plan9FS: Received unexpected message type {} in response to {}", (u8)reply_type, (u8)request_type);
|
||||
return KResult(-EIO);
|
||||
return EIO;
|
||||
} else {
|
||||
return KSuccess;
|
||||
}
|
||||
|
@ -944,7 +944,7 @@ KResult Plan9FSInode::traverse_as_directory(Function<bool(const FS::DirectoryEnt
|
|||
return result;
|
||||
} else {
|
||||
// TODO
|
||||
return KResult(-ENOTIMPL);
|
||||
return ENOTIMPL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -964,31 +964,31 @@ RefPtr<Inode> Plan9FSInode::lookup(StringView name)
|
|||
KResultOr<NonnullRefPtr<Inode>> Plan9FSInode::create_child(const String&, mode_t, dev_t, uid_t, gid_t)
|
||||
{
|
||||
// TODO
|
||||
return KResult(-ENOTIMPL);
|
||||
return ENOTIMPL;
|
||||
}
|
||||
|
||||
KResult Plan9FSInode::add_child(Inode&, const StringView&, mode_t)
|
||||
{
|
||||
// TODO
|
||||
return KResult(-ENOTIMPL);
|
||||
return ENOTIMPL;
|
||||
}
|
||||
|
||||
KResult Plan9FSInode::remove_child(const StringView&)
|
||||
{
|
||||
// TODO
|
||||
return KResult(-ENOTIMPL);
|
||||
return ENOTIMPL;
|
||||
}
|
||||
|
||||
KResult Plan9FSInode::chmod(mode_t)
|
||||
{
|
||||
// TODO
|
||||
return KResult(-ENOTIMPL);
|
||||
return ENOTIMPL;
|
||||
}
|
||||
|
||||
KResult Plan9FSInode::chown(uid_t, gid_t)
|
||||
{
|
||||
// TODO
|
||||
return KResult(-ENOTIMPL);
|
||||
return ENOTIMPL;
|
||||
}
|
||||
|
||||
KResult Plan9FSInode::truncate(u64 new_size)
|
||||
|
|
|
@ -1073,14 +1073,14 @@ KResult ProcFSInode::refresh_data(FileDescription& description) const
|
|||
}
|
||||
KBufferBuilder builder(buffer, true);
|
||||
if (!read_callback(identifier(), builder))
|
||||
return KResult(-ENOENT);
|
||||
return ENOENT;
|
||||
// We don't use builder.build() here, which would steal our buffer
|
||||
// and turn it into an OwnPtr. Instead, just flush to the buffer so
|
||||
// that we can read all the data that was written.
|
||||
if (!builder.flush())
|
||||
return KResult(-ENOMEM);
|
||||
return ENOMEM;
|
||||
if (!buffer)
|
||||
return KResult(-ENOMEM);
|
||||
return ENOMEM;
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
|
@ -1220,7 +1220,7 @@ KResult ProcFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntr
|
|||
#endif
|
||||
|
||||
if (!Kernel::is_directory(identifier()))
|
||||
return KResult(-ENOTDIR);
|
||||
return ENOTDIR;
|
||||
|
||||
auto proc_file_type = to_proc_file_type(identifier());
|
||||
auto parent_id = to_parent_id(identifier());
|
||||
|
@ -1263,7 +1263,7 @@ KResult ProcFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntr
|
|||
auto pid = to_pid(identifier());
|
||||
auto process = Process::from_pid(pid);
|
||||
if (!process)
|
||||
return KResult(-ENOENT);
|
||||
return ENOENT;
|
||||
for (auto& entry : fs().m_entries) {
|
||||
if (entry.proc_file_type > __FI_PID_Start && entry.proc_file_type < __FI_PID_End) {
|
||||
if (entry.proc_file_type == FI_PID_exe && !process->executable())
|
||||
|
@ -1278,7 +1278,7 @@ KResult ProcFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntr
|
|||
auto pid = to_pid(identifier());
|
||||
auto process = Process::from_pid(pid);
|
||||
if (!process)
|
||||
return KResult(-ENOENT);
|
||||
return ENOENT;
|
||||
for (int i = 0; i < process->max_open_file_descriptors(); ++i) {
|
||||
auto description = process->file_description(i);
|
||||
if (!description)
|
||||
|
@ -1293,7 +1293,7 @@ KResult ProcFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntr
|
|||
auto pid = to_pid(identifier());
|
||||
auto process = Process::from_pid(pid);
|
||||
if (!process)
|
||||
return KResult(-ENOENT);
|
||||
return ENOENT;
|
||||
process->for_each_thread([&](Thread& thread) -> IterationDecision {
|
||||
int tid = thread.tid().value();
|
||||
char name[16];
|
||||
|
@ -1478,7 +1478,7 @@ KResultOr<NonnullRefPtr<Custody>> ProcFSInode::resolve_as_link(Custody& base, Re
|
|||
auto proc_file_type = to_proc_file_type(identifier());
|
||||
auto process = Process::from_pid(pid);
|
||||
if (!process)
|
||||
return KResult(-ENOENT);
|
||||
return ENOENT;
|
||||
|
||||
if (to_proc_parent_directory(identifier()) == PDI_PID_fd) {
|
||||
if (out_parent)
|
||||
|
@ -1486,7 +1486,7 @@ KResultOr<NonnullRefPtr<Custody>> ProcFSInode::resolve_as_link(Custody& base, Re
|
|||
int fd = to_fd(identifier());
|
||||
auto description = process->file_description(fd);
|
||||
if (!description)
|
||||
return KResult(-ENOENT);
|
||||
return ENOENT;
|
||||
auto proxy_inode = ProcFSProxyInode::create(const_cast<ProcFS&>(fs()), *description);
|
||||
return Custody::create(&base, "", proxy_inode, base.mount_flags());
|
||||
}
|
||||
|
@ -1511,7 +1511,7 @@ KResultOr<NonnullRefPtr<Custody>> ProcFSInode::resolve_as_link(Custody& base, Re
|
|||
}
|
||||
|
||||
if (!res)
|
||||
return KResult(-ENOENT);
|
||||
return ENOENT;
|
||||
|
||||
return *res;
|
||||
}
|
||||
|
@ -1559,21 +1559,21 @@ InodeMetadata ProcFSProxyInode::metadata() const
|
|||
KResultOr<NonnullRefPtr<Inode>> ProcFSProxyInode::create_child(const String& name, mode_t mode, dev_t dev, uid_t uid, gid_t gid)
|
||||
{
|
||||
if (!m_fd->inode())
|
||||
return KResult(-EINVAL);
|
||||
return EINVAL;
|
||||
return m_fd->inode()->create_child(name, mode, dev, uid, gid);
|
||||
}
|
||||
|
||||
KResult ProcFSProxyInode::add_child(Inode& child, const StringView& name, mode_t mode)
|
||||
{
|
||||
if (!m_fd->inode())
|
||||
return KResult(-EINVAL);
|
||||
return EINVAL;
|
||||
return m_fd->inode()->add_child(child, name, mode);
|
||||
}
|
||||
|
||||
KResult ProcFSProxyInode::remove_child(const StringView& name)
|
||||
{
|
||||
if (!m_fd->inode())
|
||||
return KResult(-EINVAL);
|
||||
return EINVAL;
|
||||
return m_fd->inode()->remove_child(name);
|
||||
}
|
||||
|
||||
|
@ -1587,23 +1587,23 @@ RefPtr<Inode> ProcFSProxyInode::lookup(StringView name)
|
|||
KResultOr<size_t> ProcFSProxyInode::directory_entry_count() const
|
||||
{
|
||||
if (!m_fd->inode())
|
||||
return KResult(-EINVAL);
|
||||
return EINVAL;
|
||||
return m_fd->inode()->directory_entry_count();
|
||||
}
|
||||
|
||||
KResultOr<NonnullRefPtr<Inode>> ProcFSInode::create_child(const String&, mode_t, dev_t, uid_t, gid_t)
|
||||
{
|
||||
return KResult(-EPERM);
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
KResult ProcFSInode::add_child(Inode&, const StringView&, mode_t)
|
||||
{
|
||||
return KResult(-EPERM);
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
KResult ProcFSInode::remove_child([[maybe_unused]] const StringView& name)
|
||||
{
|
||||
return KResult(-EPERM);
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
KResultOr<size_t> ProcFSInode::directory_entry_count() const
|
||||
|
@ -1623,7 +1623,7 @@ KResultOr<size_t> ProcFSInode::directory_entry_count() const
|
|||
|
||||
KResult ProcFSInode::chmod(mode_t)
|
||||
{
|
||||
return KResult(-EPERM);
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
ProcFS::ProcFS()
|
||||
|
@ -1673,6 +1673,6 @@ ProcFS::ProcFSDirectoryEntry* ProcFS::get_directory_entry(InodeIdentifier identi
|
|||
|
||||
KResult ProcFSInode::chown(uid_t, gid_t)
|
||||
{
|
||||
return KResult(-EPERM);
|
||||
return EPERM;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,8 +139,8 @@ private:
|
|||
virtual KResult add_child(Inode&, const StringView& name, mode_t) override;
|
||||
virtual KResult remove_child(const StringView& name) override;
|
||||
virtual KResultOr<size_t> directory_entry_count() const override;
|
||||
virtual KResult chmod(mode_t) override { return KResult(-EINVAL); }
|
||||
virtual KResult chown(uid_t, gid_t) override { return KResult(-EINVAL); }
|
||||
virtual KResult chmod(mode_t) override { return EINVAL; }
|
||||
virtual KResult chown(uid_t, gid_t) override { return EINVAL; }
|
||||
virtual KResultOr<NonnullRefPtr<Custody>> resolve_as_link(Custody&, RefPtr<Custody>*, int, int) const override { ASSERT_NOT_REACHED(); }
|
||||
virtual FileDescription* preopen_fd() override { return m_fd; }
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ KResult TmpFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntry
|
|||
LOCKER(m_lock, Lock::Mode::Shared);
|
||||
|
||||
if (!is_directory())
|
||||
return KResult(-ENOTDIR);
|
||||
return ENOTDIR;
|
||||
|
||||
callback({ ".", identifier(), 0 });
|
||||
callback({ "..", m_parent, 0 });
|
||||
|
@ -278,7 +278,7 @@ KResultOr<NonnullRefPtr<Inode>> TmpFSInode::create_child(const String& name, mod
|
|||
|
||||
// TODO: Support creating devices on TmpFS.
|
||||
if (dev != 0)
|
||||
return KResult(-ENOTSUP);
|
||||
return ENOTSUP;
|
||||
|
||||
struct timeval now;
|
||||
kgettimeofday(now);
|
||||
|
@ -305,7 +305,7 @@ KResult TmpFSInode::add_child(Inode& child, const StringView& name, mode_t)
|
|||
ASSERT(child.fsid() == fsid());
|
||||
|
||||
if (name.length() > NAME_MAX)
|
||||
return KResult(-ENAMETOOLONG);
|
||||
return ENAMETOOLONG;
|
||||
|
||||
m_children.set(name, { name, static_cast<TmpFSInode&>(child) });
|
||||
did_add_child(child.identifier());
|
||||
|
@ -322,7 +322,7 @@ KResult TmpFSInode::remove_child(const StringView& name)
|
|||
|
||||
auto it = m_children.find(name);
|
||||
if (it == m_children.end())
|
||||
return KResult(-ENOENT);
|
||||
return ENOENT;
|
||||
auto child_id = it->value.inode->identifier();
|
||||
m_children.remove(it);
|
||||
did_remove_child(child_id);
|
||||
|
@ -339,7 +339,7 @@ KResult TmpFSInode::truncate(u64 size)
|
|||
else if (!m_content) {
|
||||
m_content = KBuffer::try_create_with_size(size);
|
||||
if (!m_content)
|
||||
return KResult(-ENOMEM);
|
||||
return ENOMEM;
|
||||
} else if (static_cast<size_t>(size) < m_content->capacity()) {
|
||||
size_t prev_size = m_metadata.size;
|
||||
m_content->set_size(size);
|
||||
|
@ -349,7 +349,7 @@ KResult TmpFSInode::truncate(u64 size)
|
|||
size_t prev_size = m_metadata.size;
|
||||
auto tmp = KBuffer::try_create_with_size(size);
|
||||
if (!tmp)
|
||||
return KResult(-ENOMEM);
|
||||
return ENOMEM;
|
||||
memcpy(tmp->data(), m_content->data(), prev_size);
|
||||
m_content = move(tmp);
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ KResult VFS::remount(Custody& mount_point, int new_flags)
|
|||
|
||||
Mount* mount = find_mount_for_guest(mount_point.inode());
|
||||
if (!mount)
|
||||
return KResult(-ENODEV);
|
||||
return ENODEV;
|
||||
|
||||
mount->set_flags(new_flags);
|
||||
return KSuccess;
|
||||
|
@ -133,7 +133,7 @@ KResult VFS::unmount(Inode& guest_inode)
|
|||
}
|
||||
|
||||
dbg() << "VFS: Nothing mounted on inode " << guest_inode.identifier();
|
||||
return KResult(-ENODEV);
|
||||
return ENODEV;
|
||||
}
|
||||
|
||||
bool VFS::mount_root(FS& file_system)
|
||||
|
@ -230,16 +230,16 @@ KResult VFS::utime(StringView path, Custody& base, time_t atime, time_t mtime)
|
|||
auto& inode = custody.inode();
|
||||
auto current_process = Process::current();
|
||||
if (!current_process->is_superuser() && inode.metadata().uid != current_process->euid())
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
if (custody.is_readonly())
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
|
||||
int error = inode.set_atime(atime);
|
||||
if (error)
|
||||
return KResult(error);
|
||||
if (error < 0)
|
||||
return KResult((ErrnoCode)-error);
|
||||
error = inode.set_mtime(mtime);
|
||||
if (error)
|
||||
return KResult(error);
|
||||
if (error < 0)
|
||||
return KResult((ErrnoCode)-error);
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
|
@ -254,20 +254,20 @@ KResultOr<InodeMetadata> VFS::lookup_metadata(StringView path, Custody& base, in
|
|||
KResultOr<NonnullRefPtr<FileDescription>> VFS::open(StringView path, int options, mode_t mode, Custody& base, Optional<UidAndGid> owner)
|
||||
{
|
||||
if ((options & O_CREAT) && (options & O_DIRECTORY))
|
||||
return KResult(-EINVAL);
|
||||
return EINVAL;
|
||||
|
||||
RefPtr<Custody> parent_custody;
|
||||
auto custody_or_error = resolve_path(path, base, &parent_custody, options);
|
||||
if (options & O_CREAT) {
|
||||
if (!parent_custody)
|
||||
return KResult(-ENOENT);
|
||||
return ENOENT;
|
||||
if (custody_or_error.is_error()) {
|
||||
if (custody_or_error.error() != -ENOENT)
|
||||
return custody_or_error.error();
|
||||
return create(path, options, mode, *parent_custody, move(owner));
|
||||
}
|
||||
if (options & O_EXCL)
|
||||
return KResult(-EEXIST);
|
||||
return EEXIST;
|
||||
}
|
||||
if (custody_or_error.is_error())
|
||||
return custody_or_error.error();
|
||||
|
@ -277,24 +277,24 @@ KResultOr<NonnullRefPtr<FileDescription>> VFS::open(StringView path, int options
|
|||
auto metadata = inode.metadata();
|
||||
|
||||
if ((options & O_DIRECTORY) && !metadata.is_directory())
|
||||
return KResult(-ENOTDIR);
|
||||
return ENOTDIR;
|
||||
|
||||
bool should_truncate_file = false;
|
||||
|
||||
auto current_process = Process::current();
|
||||
if ((options & O_RDONLY) && !metadata.may_read(*current_process))
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
|
||||
if (options & O_WRONLY) {
|
||||
if (!metadata.may_write(*current_process))
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
if (metadata.is_directory())
|
||||
return KResult(-EISDIR);
|
||||
return EISDIR;
|
||||
should_truncate_file = options & O_TRUNC;
|
||||
}
|
||||
if (options & O_EXEC) {
|
||||
if (!metadata.may_execute(*current_process) || (custody.mount_flags() & MS_NOEXEC))
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
}
|
||||
|
||||
if (auto preopen_fd = inode.preopen_fd())
|
||||
|
@ -321,15 +321,15 @@ KResultOr<NonnullRefPtr<FileDescription>> VFS::open(StringView path, int options
|
|||
description->set_original_inode({}, inode);
|
||||
return description;
|
||||
}
|
||||
return KResult(-EINVAL);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (metadata.is_device()) {
|
||||
if (custody.mount_flags() & MS_NODEV)
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
auto device = Device::get_device(metadata.major_device, metadata.minor_device);
|
||||
if (device == nullptr) {
|
||||
return KResult(-ENODEV);
|
||||
return ENODEV;
|
||||
}
|
||||
auto descriptor_or_error = device->open(options);
|
||||
if (descriptor_or_error.is_error())
|
||||
|
@ -341,7 +341,7 @@ KResultOr<NonnullRefPtr<FileDescription>> VFS::open(StringView path, int options
|
|||
// Check for read-only FS. Do this after handling preopen FD and devices,
|
||||
// but before modifying the inode in any way.
|
||||
if ((options & O_WRONLY) && custody.is_readonly())
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
|
||||
if (should_truncate_file) {
|
||||
KResult result = inode.truncate(0);
|
||||
|
@ -360,22 +360,22 @@ KResultOr<NonnullRefPtr<FileDescription>> VFS::open(StringView path, int options
|
|||
KResult VFS::mknod(StringView path, mode_t mode, dev_t dev, Custody& base)
|
||||
{
|
||||
if (!is_regular_file(mode) && !is_block_device(mode) && !is_character_device(mode) && !is_fifo(mode) && !is_socket(mode))
|
||||
return KResult(-EINVAL);
|
||||
return EINVAL;
|
||||
|
||||
RefPtr<Custody> parent_custody;
|
||||
auto existing_file_or_error = resolve_path(path, base, &parent_custody);
|
||||
if (!existing_file_or_error.is_error())
|
||||
return KResult(-EEXIST);
|
||||
return EEXIST;
|
||||
if (!parent_custody)
|
||||
return KResult(-ENOENT);
|
||||
return ENOENT;
|
||||
if (existing_file_or_error.error() != -ENOENT)
|
||||
return existing_file_or_error.error();
|
||||
auto& parent_inode = parent_custody->inode();
|
||||
auto current_process = Process::current();
|
||||
if (!parent_inode.metadata().may_write(*current_process))
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
if (parent_custody->is_readonly())
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
|
||||
LexicalPath p(path);
|
||||
dbgln("VFS::mknod: '{}' mode={} dev={} in {}", p.basename(), mode, dev, parent_inode.identifier());
|
||||
|
@ -396,9 +396,9 @@ KResultOr<NonnullRefPtr<FileDescription>> VFS::create(StringView path, int optio
|
|||
auto& parent_inode = parent_custody.inode();
|
||||
auto current_process = Process::current();
|
||||
if (!parent_inode.metadata().may_write(*current_process))
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
if (parent_custody.is_readonly())
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
|
||||
LexicalPath p(path);
|
||||
#ifdef VFS_DEBUG
|
||||
|
@ -431,18 +431,18 @@ KResult VFS::mkdir(StringView path, mode_t mode, Custody& base)
|
|||
RefPtr<Custody> parent_custody;
|
||||
auto result = resolve_path(path, base, &parent_custody);
|
||||
if (!result.is_error())
|
||||
return KResult(-EEXIST);
|
||||
return EEXIST;
|
||||
if (!parent_custody)
|
||||
return KResult(-ENOENT);
|
||||
return ENOENT;
|
||||
if (result.error() != -ENOENT)
|
||||
return result.error();
|
||||
|
||||
auto& parent_inode = parent_custody->inode();
|
||||
auto current_process = Process::current();
|
||||
if (!parent_inode.metadata().may_write(*current_process))
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
if (parent_custody->is_readonly())
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
|
||||
LexicalPath p(path);
|
||||
#ifdef VFS_DEBUG
|
||||
|
@ -462,17 +462,17 @@ KResult VFS::access(StringView path, int mode, Custody& base)
|
|||
auto current_process = Process::current();
|
||||
if (mode & R_OK) {
|
||||
if (!metadata.may_read(*current_process))
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
}
|
||||
if (mode & W_OK) {
|
||||
if (!metadata.may_write(*current_process))
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
if (custody.is_readonly())
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
}
|
||||
if (mode & X_OK) {
|
||||
if (!metadata.may_execute(*current_process))
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
}
|
||||
return KSuccess;
|
||||
}
|
||||
|
@ -485,9 +485,9 @@ KResultOr<NonnullRefPtr<Custody>> VFS::open_directory(StringView path, Custody&
|
|||
auto& custody = *inode_or_error.value();
|
||||
auto& inode = custody.inode();
|
||||
if (!inode.is_directory())
|
||||
return KResult(-ENOTDIR);
|
||||
return ENOTDIR;
|
||||
if (!inode.metadata().may_execute(*Process::current()))
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
return custody;
|
||||
}
|
||||
|
||||
|
@ -497,9 +497,9 @@ KResult VFS::chmod(Custody& custody, mode_t mode)
|
|||
|
||||
auto current_process = Process::current();
|
||||
if (current_process->euid() != inode.metadata().uid && !current_process->is_superuser())
|
||||
return KResult(-EPERM);
|
||||
return EPERM;
|
||||
if (custody.is_readonly())
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
|
||||
// Only change the permission bits.
|
||||
mode = (inode.mode() & ~07777u) | (mode & 07777u);
|
||||
|
@ -535,27 +535,27 @@ KResult VFS::rename(StringView old_path, StringView new_path, Custody& base)
|
|||
auto& new_parent_inode = new_parent_custody->inode();
|
||||
|
||||
if (&old_parent_inode.fs() != &new_parent_inode.fs())
|
||||
return KResult(-EXDEV);
|
||||
return EXDEV;
|
||||
|
||||
for (auto* new_ancestor = new_parent_custody.ptr(); new_ancestor; new_ancestor = new_ancestor->parent()) {
|
||||
if (&old_inode == &new_ancestor->inode())
|
||||
return KResult(-EDIRINTOSELF);
|
||||
return EDIRINTOSELF;
|
||||
}
|
||||
|
||||
auto current_process = Process::current();
|
||||
if (!new_parent_inode.metadata().may_write(*current_process))
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
|
||||
if (!old_parent_inode.metadata().may_write(*current_process))
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
|
||||
if (old_parent_inode.metadata().is_sticky()) {
|
||||
if (!current_process->is_superuser() && old_inode.metadata().uid != current_process->euid())
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
}
|
||||
|
||||
if (old_parent_custody->is_readonly() || new_parent_custody->is_readonly())
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
|
||||
auto new_basename = LexicalPath(new_path).basename();
|
||||
|
||||
|
@ -567,10 +567,10 @@ KResult VFS::rename(StringView old_path, StringView new_path, Custody& base)
|
|||
return KSuccess;
|
||||
if (new_parent_inode.metadata().is_sticky()) {
|
||||
if (!current_process->is_superuser() && new_inode.metadata().uid != current_process->euid())
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
}
|
||||
if (new_inode.is_directory() && !old_inode.is_directory())
|
||||
return KResult(-EISDIR);
|
||||
return EISDIR;
|
||||
auto result = new_parent_inode.remove_child(new_basename);
|
||||
if (result.is_error())
|
||||
return result;
|
||||
|
@ -594,24 +594,24 @@ KResult VFS::chown(Custody& custody, uid_t a_uid, gid_t a_gid)
|
|||
|
||||
auto current_process = Process::current();
|
||||
if (current_process->euid() != metadata.uid && !current_process->is_superuser())
|
||||
return KResult(-EPERM);
|
||||
return EPERM;
|
||||
|
||||
uid_t new_uid = metadata.uid;
|
||||
gid_t new_gid = metadata.gid;
|
||||
|
||||
if (a_uid != (uid_t)-1) {
|
||||
if (current_process->euid() != a_uid && !current_process->is_superuser())
|
||||
return KResult(-EPERM);
|
||||
return EPERM;
|
||||
new_uid = a_uid;
|
||||
}
|
||||
if (a_gid != (gid_t)-1) {
|
||||
if (!current_process->in_group(a_gid) && !current_process->is_superuser())
|
||||
return KResult(-EPERM);
|
||||
return EPERM;
|
||||
new_gid = a_gid;
|
||||
}
|
||||
|
||||
if (custody.is_readonly())
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
|
||||
dbgln("VFS::chown(): inode {} <- uid={} gid={}", inode.identifier(), new_uid, new_gid);
|
||||
|
||||
|
@ -662,27 +662,27 @@ KResult VFS::link(StringView old_path, StringView new_path, Custody& base)
|
|||
RefPtr<Custody> parent_custody;
|
||||
auto new_custody_or_error = resolve_path(new_path, base, &parent_custody);
|
||||
if (!new_custody_or_error.is_error())
|
||||
return KResult(-EEXIST);
|
||||
return EEXIST;
|
||||
|
||||
if (!parent_custody)
|
||||
return KResult(-ENOENT);
|
||||
return ENOENT;
|
||||
|
||||
auto& parent_inode = parent_custody->inode();
|
||||
|
||||
if (parent_inode.fsid() != old_inode.fsid())
|
||||
return KResult(-EXDEV);
|
||||
return EXDEV;
|
||||
|
||||
if (!parent_inode.metadata().may_write(*Process::current()))
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
|
||||
if (old_inode.is_directory())
|
||||
return KResult(-EPERM);
|
||||
return EPERM;
|
||||
|
||||
if (parent_custody->is_readonly())
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
|
||||
if (!hard_link_allowed(old_inode))
|
||||
return KResult(-EPERM);
|
||||
return EPERM;
|
||||
|
||||
return parent_inode.add_child(old_inode, LexicalPath(new_path).basename(), old_inode.mode());
|
||||
}
|
||||
|
@ -697,7 +697,7 @@ KResult VFS::unlink(StringView path, Custody& base)
|
|||
auto& inode = custody.inode();
|
||||
|
||||
if (inode.is_directory())
|
||||
return KResult(-EISDIR);
|
||||
return EISDIR;
|
||||
|
||||
// We have just checked that the inode is not a directory, and thus it's not
|
||||
// the root. So it should have a parent. Note that this would be invalidated
|
||||
|
@ -707,15 +707,15 @@ KResult VFS::unlink(StringView path, Custody& base)
|
|||
auto& parent_inode = parent_custody->inode();
|
||||
auto current_process = Process::current();
|
||||
if (!parent_inode.metadata().may_write(*current_process))
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
|
||||
if (parent_inode.metadata().is_sticky()) {
|
||||
if (!current_process->is_superuser() && inode.metadata().uid != current_process->euid())
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
}
|
||||
|
||||
if (parent_custody->is_readonly())
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
|
||||
auto result = parent_inode.remove_child(LexicalPath(path).basename());
|
||||
if (result.is_error())
|
||||
|
@ -729,17 +729,17 @@ KResult VFS::symlink(StringView target, StringView linkpath, Custody& base)
|
|||
RefPtr<Custody> parent_custody;
|
||||
auto existing_custody_or_error = resolve_path(linkpath, base, &parent_custody);
|
||||
if (!existing_custody_or_error.is_error())
|
||||
return KResult(-EEXIST);
|
||||
return EEXIST;
|
||||
if (!parent_custody)
|
||||
return KResult(-ENOENT);
|
||||
return ENOENT;
|
||||
if (existing_custody_or_error.error() != -ENOENT)
|
||||
return existing_custody_or_error.error();
|
||||
auto& parent_inode = parent_custody->inode();
|
||||
auto current_process = Process::current();
|
||||
if (!parent_inode.metadata().may_write(*current_process))
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
if (parent_custody->is_readonly())
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
|
||||
LexicalPath p(linkpath);
|
||||
dbgln("VFS::symlink: '{}' (-> '{}') in {}", p.basename(), target, parent_inode.identifier());
|
||||
|
@ -750,7 +750,7 @@ KResult VFS::symlink(StringView target, StringView linkpath, Custody& base)
|
|||
auto target_buffer = UserOrKernelBuffer::for_kernel_buffer(const_cast<u8*>((const u8*)target.characters_without_null_termination()));
|
||||
ssize_t nwritten = inode->write_bytes(0, target.length(), target_buffer, nullptr);
|
||||
if (nwritten < 0)
|
||||
return KResult(nwritten);
|
||||
return KResult((ErrnoCode)-nwritten);
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
|
@ -768,20 +768,20 @@ KResult VFS::rmdir(StringView path, Custody& base)
|
|||
// FIXME: We should return ENOTEMPTY if the last component of the path is ".."
|
||||
|
||||
if (!inode.is_directory())
|
||||
return KResult(-ENOTDIR);
|
||||
return ENOTDIR;
|
||||
|
||||
if (!parent_custody)
|
||||
return KResult(-EBUSY);
|
||||
return EBUSY;
|
||||
|
||||
auto& parent_inode = parent_custody->inode();
|
||||
auto parent_metadata = parent_inode.metadata();
|
||||
|
||||
if (!parent_metadata.may_write(*Process::current()))
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
|
||||
if (parent_metadata.is_sticky()) {
|
||||
if (!Process::current()->is_superuser() && inode.metadata().uid != Process::current()->euid())
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
}
|
||||
|
||||
KResultOr<size_t> dir_count_result = inode.directory_entry_count();
|
||||
|
@ -789,10 +789,10 @@ KResult VFS::rmdir(StringView path, Custody& base)
|
|||
return dir_count_result.result();
|
||||
|
||||
if (dir_count_result.value() != 2)
|
||||
return KResult(-ENOTEMPTY);
|
||||
return ENOTEMPTY;
|
||||
|
||||
if (custody.is_readonly())
|
||||
return KResult(-EROFS);
|
||||
return EROFS;
|
||||
|
||||
auto result = inode.remove_child(".");
|
||||
if (result.is_error())
|
||||
|
@ -882,27 +882,27 @@ KResult VFS::validate_path_against_process_veil(StringView path, int options)
|
|||
|
||||
// FIXME: Figure out a nicer way to do this.
|
||||
if (String(path).contains("/.."))
|
||||
return KResult(-EINVAL);
|
||||
return EINVAL;
|
||||
|
||||
auto* unveiled_path = find_matching_unveiled_path(path);
|
||||
if (!unveiled_path) {
|
||||
dbgln("Rejecting path '{}' since it hasn't been unveiled.", path);
|
||||
dump_backtrace();
|
||||
return KResult(-ENOENT);
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
if (options & O_CREAT) {
|
||||
if (!(unveiled_path->permissions() & UnveilAccess::CreateOrRemove)) {
|
||||
dbgln("Rejecting path '{}' since it hasn't been unveiled with 'c' permission.", path);
|
||||
dump_backtrace();
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
}
|
||||
}
|
||||
if (options & O_UNLINK_INTERNAL) {
|
||||
if (!(unveiled_path->permissions() & UnveilAccess::CreateOrRemove)) {
|
||||
dbgln("Rejecting path '{}' for unlink since it hasn't been unveiled with 'c' permission.", path);
|
||||
dump_backtrace();
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
}
|
||||
return KSuccess;
|
||||
}
|
||||
|
@ -911,13 +911,13 @@ KResult VFS::validate_path_against_process_veil(StringView path, int options)
|
|||
if (!(unveiled_path->permissions() & (UnveilAccess::Read | UnveilAccess::Browse))) {
|
||||
dbgln("Rejecting path '{}' since it hasn't been unveiled with 'r' or 'b' permissions.", path);
|
||||
dump_backtrace();
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
}
|
||||
} else {
|
||||
if (!(unveiled_path->permissions() & UnveilAccess::Read)) {
|
||||
dbgln("Rejecting path '{}' since it hasn't been unveiled with 'r' permission.", path);
|
||||
dump_backtrace();
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -925,14 +925,14 @@ KResult VFS::validate_path_against_process_veil(StringView path, int options)
|
|||
if (!(unveiled_path->permissions() & UnveilAccess::Write)) {
|
||||
dbgln("Rejecting path '{}' since it hasn't been unveiled with 'w' permission.", path);
|
||||
dump_backtrace();
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
}
|
||||
}
|
||||
if (options & O_EXEC) {
|
||||
if (!(unveiled_path->permissions() & UnveilAccess::Execute)) {
|
||||
dbgln("Rejecting path '{}' since it hasn't been unveiled with 'x' permission.", path);
|
||||
dump_backtrace();
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
}
|
||||
}
|
||||
return KSuccess;
|
||||
|
@ -970,10 +970,10 @@ static bool safe_to_follow_symlink(const Inode& inode, const InodeMetadata& pare
|
|||
KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path_without_veil(StringView path, Custody& base, RefPtr<Custody>* out_parent, int options, int symlink_recursion_level)
|
||||
{
|
||||
if (symlink_recursion_level >= symlink_recursion_limit)
|
||||
return KResult(-ELOOP);
|
||||
return ELOOP;
|
||||
|
||||
if (path.is_empty())
|
||||
return KResult(-EINVAL);
|
||||
return EINVAL;
|
||||
|
||||
auto parts = path.split_view('/', true);
|
||||
auto current_process = Process::current();
|
||||
|
@ -985,10 +985,10 @@ KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path_without_veil(StringView path
|
|||
Custody& parent = custody;
|
||||
auto parent_metadata = parent.inode().metadata();
|
||||
if (!parent_metadata.is_directory())
|
||||
return KResult(-ENOTDIR);
|
||||
return ENOTDIR;
|
||||
// Ensure the current user is allowed to resolve paths inside this directory.
|
||||
if (!parent_metadata.may_execute(*current_process))
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
|
||||
auto& part = parts[i];
|
||||
bool have_more_parts = i + 1 < parts.size();
|
||||
|
@ -1011,7 +1011,7 @@ KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path_without_veil(StringView path
|
|||
// does not exist yet.
|
||||
*out_parent = have_more_parts ? nullptr : &parent;
|
||||
}
|
||||
return KResult(-ENOENT);
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
int mount_flags_for_child = parent.mount_flags();
|
||||
|
@ -1028,13 +1028,13 @@ KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path_without_veil(StringView path
|
|||
if (child_inode->metadata().is_symlink()) {
|
||||
if (!have_more_parts) {
|
||||
if (options & O_NOFOLLOW)
|
||||
return KResult(-ELOOP);
|
||||
return ELOOP;
|
||||
if (options & O_NOFOLLOW_NOERROR)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!safe_to_follow_symlink(*child_inode, parent_metadata))
|
||||
return KResult(-EACCES);
|
||||
return EACCES;
|
||||
|
||||
auto symlink_target = child_inode->resolve_as_link(parent, out_parent, options, symlink_recursion_level + 1);
|
||||
if (symlink_target.is_error() || !have_more_parts)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue