diff --git a/Kernel/FileSystem/DevPtsFS.cpp b/Kernel/FileSystem/DevPtsFS.cpp index 8aef2c8960..d3da6eb5c5 100644 --- a/Kernel/FileSystem/DevPtsFS.cpp +++ b/Kernel/FileSystem/DevPtsFS.cpp @@ -77,10 +77,9 @@ InodeIdentifier DevPtsFS::root_inode() const return { fsid(), 1 }; } -RefPtr DevPtsFS::create_inode(InodeIdentifier, const String&, mode_t, off_t, dev_t, uid_t, gid_t, int& error) +KResultOr> DevPtsFS::create_inode(InodeIdentifier, const String&, mode_t, off_t, dev_t, uid_t, gid_t) { - error = -EROFS; - return nullptr; + return KResult(-EROFS); } KResult DevPtsFS::create_directory(InodeIdentifier, const String&, mode_t, uid_t, gid_t) diff --git a/Kernel/FileSystem/DevPtsFS.h b/Kernel/FileSystem/DevPtsFS.h index a8ddc6cc58..725f45a267 100644 --- a/Kernel/FileSystem/DevPtsFS.h +++ b/Kernel/FileSystem/DevPtsFS.h @@ -42,7 +42,7 @@ public: virtual const char* class_name() const override { return "DevPtsFS"; } virtual InodeIdentifier root_inode() const override; - virtual RefPtr create_inode(InodeIdentifier parent_inode, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t, int& error) override; + virtual KResultOr> create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t) override; virtual KResult create_directory(InodeIdentifier parent_inode, const String& name, mode_t, uid_t, gid_t) override; virtual RefPtr get_inode(InodeIdentifier) const override; diff --git a/Kernel/FileSystem/Ext2FileSystem.cpp b/Kernel/FileSystem/Ext2FileSystem.cpp index 309ff7167a..3c9a83c2eb 100644 --- a/Kernel/FileSystem/Ext2FileSystem.cpp +++ b/Kernel/FileSystem/Ext2FileSystem.cpp @@ -1359,10 +1359,11 @@ KResult Ext2FS::create_directory(InodeIdentifier parent_id, const String& name, // NOTE: When creating a new directory, make the size 1 block. // There's probably a better strategy here, but this works for now. - int error; - auto inode = create_inode(parent_id, name, mode, block_size(), 0, uid, gid, error); - if (!inode) - return KResult(error); + auto inode_or_error = create_inode(parent_id, name, mode, block_size(), 0, uid, gid); + if (inode_or_error.is_error()) + return inode_or_error.error(); + + auto& inode = inode_or_error.value(); #ifdef EXT2_DEBUG dbgprintf("Ext2FS: create_directory: created new directory named '%s' with inode %u\n", name.characters(), inode->identifier().index()); @@ -1391,17 +1392,15 @@ KResult Ext2FS::create_directory(InodeIdentifier parent_id, const String& name, return KSuccess; } -RefPtr Ext2FS::create_inode(InodeIdentifier parent_id, const String& name, mode_t mode, off_t size, dev_t dev, uid_t uid, gid_t gid, int& error) +KResultOr> Ext2FS::create_inode(InodeIdentifier parent_id, const String& name, mode_t mode, off_t size, dev_t dev, uid_t uid, gid_t gid) { LOCKER(m_lock); ASSERT(parent_id.fsid() == fsid()); auto parent_inode = get_inode(parent_id); ASSERT(parent_inode); - if (static_cast(*parent_inode).m_raw_inode.i_links_count == 0) { - error = -ENOENT; - return nullptr; - } + if (static_cast(*parent_inode).m_raw_inode.i_links_count == 0) + return KResult(-ENOENT); #ifdef EXT2_DEBUG dbgprintf("Ext2FS: Adding inode '%s' (mode %o) to parent directory %u:\n", name.characters(), mode, parent_inode->identifier().index()); @@ -1410,24 +1409,20 @@ RefPtr Ext2FS::create_inode(InodeIdentifier parent_id, const String& name auto needed_blocks = ceil_div(size, block_size()); if ((size_t)needed_blocks > super_block().s_free_blocks_count) { dbg() << "Ext2FS: create_inode: not enough free blocks"; - error = -ENOSPC; - return {}; + return KResult(-ENOSPC); } // NOTE: This doesn't commit the inode allocation just yet! auto inode_id = find_a_free_inode(0, size); if (!inode_id) { kprintf("Ext2FS: create_inode: allocate_inode failed\n"); - error = -ENOSPC; - return {}; + return KResult(-ENOSPC); } // Try adding it to the directory first, in case the name is already in use. auto result = parent_inode->add_child({ fsid(), inode_id }, name, mode); - if (result.is_error()) { - error = result; - return {}; - } + if (result.is_error()) + return result; auto blocks = allocate_blocks(group_index_from_inode(inode_id), needed_blocks); ASSERT(blocks.size() == needed_blocks); @@ -1477,7 +1472,7 @@ RefPtr Ext2FS::create_inode(InodeIdentifier parent_id, const String& name auto inode = get_inode({ fsid(), inode_id }); // If we've already computed a block list, no sense in throwing it away. static_cast(*inode).m_block_list = move(blocks); - return inode; + return inode.release_nonnull(); } void Ext2FSInode::populate_lookup_cache() const diff --git a/Kernel/FileSystem/Ext2FileSystem.h b/Kernel/FileSystem/Ext2FileSystem.h index dcc0c4de32..4446dd64cf 100644 --- a/Kernel/FileSystem/Ext2FileSystem.h +++ b/Kernel/FileSystem/Ext2FileSystem.h @@ -125,7 +125,7 @@ private: virtual const char* class_name() const override; virtual InodeIdentifier root_inode() const override; - virtual RefPtr create_inode(InodeIdentifier parent_inode, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t, int& error) override; + virtual KResultOr> create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t) override; virtual KResult create_directory(InodeIdentifier parent_inode, const String& name, mode_t, uid_t, gid_t) override; virtual RefPtr get_inode(InodeIdentifier) const override; virtual void flush_writes() override; diff --git a/Kernel/FileSystem/FileSystem.h b/Kernel/FileSystem/FileSystem.h index 7f9f6628d4..76ba9ea737 100644 --- a/Kernel/FileSystem/FileSystem.h +++ b/Kernel/FileSystem/FileSystem.h @@ -84,7 +84,7 @@ public: u8 file_type { 0 }; }; - virtual RefPtr create_inode(InodeIdentifier parent_inode, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t, int& error) = 0; + virtual KResultOr> create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t) = 0; virtual KResult create_directory(InodeIdentifier parent_inode, const String& name, mode_t, uid_t, gid_t) = 0; virtual RefPtr get_inode(InodeIdentifier) const = 0; diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp index 201d0782e9..8c7ded1ab2 100644 --- a/Kernel/FileSystem/ProcFS.cpp +++ b/Kernel/FileSystem/ProcFS.cpp @@ -1035,10 +1035,9 @@ const char* ProcFS::class_name() const return "ProcFS"; } -RefPtr ProcFS::create_inode(InodeIdentifier, const String&, mode_t, off_t, dev_t, uid_t, gid_t, int&) +KResultOr> ProcFS::create_inode(InodeIdentifier, const String&, mode_t, off_t, dev_t, uid_t, gid_t) { - kprintf("FIXME: Implement ProcFS::create_inode()?\n"); - return {}; + return KResult(-EROFS); } KResult ProcFS::create_directory(InodeIdentifier, const String&, mode_t, uid_t, gid_t) diff --git a/Kernel/FileSystem/ProcFS.h b/Kernel/FileSystem/ProcFS.h index 956d8a5133..316c4288f6 100644 --- a/Kernel/FileSystem/ProcFS.h +++ b/Kernel/FileSystem/ProcFS.h @@ -49,7 +49,7 @@ public: virtual InodeIdentifier root_inode() const override; virtual RefPtr get_inode(InodeIdentifier) const override; - virtual RefPtr create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t, int& error) override; + virtual KResultOr> create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t) override; virtual KResult create_directory(InodeIdentifier parent_id, const String& name, mode_t, uid_t, gid_t) override; static void add_sys_bool(String&&, Lockable&, Function&& notify_callback = nullptr); diff --git a/Kernel/FileSystem/TmpFS.cpp b/Kernel/FileSystem/TmpFS.cpp index ce401aaef6..64a84c0820 100644 --- a/Kernel/FileSystem/TmpFS.cpp +++ b/Kernel/FileSystem/TmpFS.cpp @@ -88,7 +88,7 @@ RefPtr TmpFS::get_inode(InodeIdentifier identifier) const return it->value; } -RefPtr TmpFS::create_inode(InodeIdentifier parent_id, const String& name, mode_t mode, off_t size, dev_t dev, uid_t uid, gid_t gid, int& error) +KResultOr> TmpFS::create_inode(InodeIdentifier parent_id, const String& name, mode_t mode, off_t size, dev_t dev, uid_t uid, gid_t gid) { LOCKER(m_lock); ASSERT(parent_id.fsid() == fsid()); @@ -112,7 +112,10 @@ RefPtr TmpFS::create_inode(InodeIdentifier parent_id, const String& name, auto it = m_inodes.find(parent_id.index()); ASSERT(it != m_inodes.end()); auto parent_inode = it->value; - error = parent_inode->add_child(inode->identifier(), name, mode); + + auto result = parent_inode->add_child(inode->identifier(), name, mode); + if (result.is_error()) + return result; return inode; } @@ -122,9 +125,9 @@ KResult TmpFS::create_directory(InodeIdentifier parent_id, const String& name, m // Ensure it's a directory. mode &= ~0170000; mode |= 0040000; - int error; - if (!create_inode(parent_id, name, mode, 0, 0, uid, gid, error)) - return KResult(error); + auto result = create_inode(parent_id, name, mode, 0, 0, uid, gid); + if (result.is_error()) + return result.error(); return KSuccess; } diff --git a/Kernel/FileSystem/TmpFS.h b/Kernel/FileSystem/TmpFS.h index fe6620ed1d..d2067504c9 100644 --- a/Kernel/FileSystem/TmpFS.h +++ b/Kernel/FileSystem/TmpFS.h @@ -48,7 +48,7 @@ public: virtual InodeIdentifier root_inode() const override; virtual RefPtr get_inode(InodeIdentifier) const override; - virtual RefPtr create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t, int& error) override; + virtual KResultOr> create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t) override; virtual KResult create_directory(InodeIdentifier parent_id, const String& name, mode_t, uid_t, gid_t) override; private: diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp index 02e8930ddb..75277388d6 100644 --- a/Kernel/FileSystem/VirtualFileSystem.cpp +++ b/Kernel/FileSystem/VirtualFileSystem.cpp @@ -299,12 +299,7 @@ KResult VFS::mknod(StringView path, mode_t mode, dev_t dev, Custody& base) FileSystemPath p(path); dbg() << "VFS::mknod: '" << p.basename() << "' mode=" << mode << " dev=" << dev << " in " << parent_inode.identifier(); - int error; - auto new_file = parent_inode.fs().create_inode(parent_inode.identifier(), p.basename(), mode, 0, dev, current->process().uid(), current->process().gid(), error); - if (!new_file) - return KResult(error); - - return KSuccess; + return parent_inode.fs().create_inode(parent_inode.identifier(), p.basename(), mode, 0, dev, current->process().uid(), current->process().gid()).result(); } KResultOr> VFS::create(StringView path, int options, mode_t mode, Custody& parent_custody, Optional owner) @@ -321,15 +316,13 @@ KResultOr> VFS::create(StringView path, int optio #ifdef VFS_DEBUG dbg() << "VFS::create: '" << p.basename() << "' in " << parent_inode.identifier(); #endif - int error; - uid_t uid = owner.has_value() ? owner.value().uid : current->process().uid(); gid_t gid = owner.has_value() ? owner.value().gid : current->process().gid(); - auto new_file = parent_inode.fs().create_inode(parent_inode.identifier(), p.basename(), mode, 0, 0, uid, gid, error); - if (!new_file) - return KResult(error); + auto inode_or_error = parent_inode.fs().create_inode(parent_inode.identifier(), p.basename(), mode, 0, 0, uid, gid); + if (inode_or_error.is_error()) + return inode_or_error.error(); - auto new_custody = Custody::create(&parent_custody, p.basename(), *new_file, parent_custody.mount_flags()); + auto new_custody = Custody::create(&parent_custody, p.basename(), inode_or_error.value(), parent_custody.mount_flags()); auto description = FileDescription::create(*new_custody); description->set_rw_mode(options); description->set_file_flags(options); @@ -599,11 +592,11 @@ KResult VFS::symlink(StringView target, StringView linkpath, Custody& base) FileSystemPath p(linkpath); dbg() << "VFS::symlink: '" << p.basename() << "' (-> '" << target << "') in " << parent_inode.identifier(); - int error; - auto new_file = parent_inode.fs().create_inode(parent_inode.identifier(), p.basename(), 0120644, 0, 0, current->process().uid(), current->process().gid(), error); - if (!new_file) - return KResult(error); - ssize_t nwritten = new_file->write_bytes(0, target.length(), (const u8*)target.characters_without_null_termination(), nullptr); + auto inode_or_error = parent_inode.fs().create_inode(parent_inode.identifier(), p.basename(), 0120644, 0, 0, current->process().uid(), current->process().gid()); + if (inode_or_error.is_error()) + return inode_or_error.error(); + auto& inode = inode_or_error.value(); + ssize_t nwritten = inode->write_bytes(0, target.length(), (const u8*)target.characters_without_null_termination(), nullptr); if (nwritten < 0) return KResult(nwritten); return KSuccess;