1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 05:48:12 +00:00

Kernel: Use KResult in unlink() and rmdir().

This commit is contained in:
Andreas Kling 2019-02-27 14:11:25 +01:00
parent ce53b6fd0f
commit 5b27f11b97
11 changed files with 54 additions and 92 deletions

View file

@ -649,7 +649,7 @@ bool Ext2FSInode::add_child(InodeIdentifier child_id, const String& name, byte f
return success; return success;
} }
bool Ext2FSInode::remove_child(const String& name, int& error) KResult Ext2FSInode::remove_child(const String& name)
{ {
LOCKER(m_lock); LOCKER(m_lock);
#ifdef EXT2_DEBUG #ifdef EXT2_DEBUG
@ -658,15 +658,11 @@ bool Ext2FSInode::remove_child(const String& name, int& error)
ASSERT(is_directory()); ASSERT(is_directory());
unsigned child_inode_index; unsigned child_inode_index;
{ auto it = m_lookup_cache.find(name);
LOCKER(m_lock); if (it == m_lookup_cache.end())
auto it = m_lookup_cache.find(name); return KResult(-ENOENT);
if (it == m_lookup_cache.end()) { child_inode_index = (*it).value;
error = -ENOENT;
return false;
}
child_inode_index = (*it).value;
}
InodeIdentifier child_id { fsid(), child_inode_index }; InodeIdentifier child_id { fsid(), child_inode_index };
//#ifdef EXT2_DEBUG //#ifdef EXT2_DEBUG
@ -683,18 +679,14 @@ bool Ext2FSInode::remove_child(const String& name, int& error)
bool success = fs().write_directory_inode(index(), move(entries)); bool success = fs().write_directory_inode(index(), move(entries));
if (!success) { if (!success) {
// FIXME: Plumb error from write_directory_inode(). // FIXME: Plumb error from write_directory_inode().
error = -EIO; return KResult(-EIO);
return false;
} }
{ m_lookup_cache.remove(name);
LOCKER(m_lock);
m_lookup_cache.remove(name);
}
auto child_inode = fs().get_inode(child_id); auto child_inode = fs().get_inode(child_id);
child_inode->decrement_link_count(); child_inode->decrement_link_count();
return success; return KSuccess;
} }
bool Ext2FS::write_directory_inode(unsigned directoryInode, Vector<DirectoryEntry>&& entries) bool Ext2FS::write_directory_inode(unsigned directoryInode, Vector<DirectoryEntry>&& entries)

View file

@ -33,7 +33,7 @@ private:
virtual void flush_metadata() override; virtual void flush_metadata() override;
virtual ssize_t write_bytes(off_t, ssize_t, const byte* data, FileDescriptor*) override; virtual ssize_t write_bytes(off_t, ssize_t, const byte* data, FileDescriptor*) override;
virtual bool add_child(InodeIdentifier child_id, const String& name, byte file_type, int& error) override; virtual bool add_child(InodeIdentifier child_id, const String& name, byte file_type, int& error) override;
virtual bool remove_child(const String& name, int& error) override; virtual KResult remove_child(const String& name) override;
virtual RetainPtr<Inode> parent() const override; virtual RetainPtr<Inode> parent() const override;
virtual int set_atime(time_t) override; virtual int set_atime(time_t) override;
virtual int set_ctime(time_t) override; virtual int set_ctime(time_t) override;

View file

@ -94,7 +94,7 @@ public:
virtual String reverse_lookup(InodeIdentifier) = 0; virtual String reverse_lookup(InodeIdentifier) = 0;
virtual ssize_t write_bytes(off_t, ssize_t, const byte* data, FileDescriptor*) = 0; virtual ssize_t write_bytes(off_t, ssize_t, const byte* data, FileDescriptor*) = 0;
virtual bool add_child(InodeIdentifier child_id, const String& name, byte file_type, int& error) = 0; virtual bool add_child(InodeIdentifier child_id, const String& name, byte file_type, int& error) = 0;
virtual bool remove_child(const String& name, int& error) = 0; virtual KResult remove_child(const String& name) = 0;
virtual RetainPtr<Inode> parent() const = 0; virtual RetainPtr<Inode> parent() const = 0;
virtual size_t directory_entry_count() const = 0; virtual size_t directory_entry_count() const = 0;
virtual KResult chmod(mode_t) = 0; virtual KResult chmod(mode_t) = 0;

View file

@ -11,6 +11,9 @@ public:
KResult(KSuccessTag) : m_error(0) { } KResult(KSuccessTag) : m_error(0) { }
operator int() const { return m_error; } operator int() const { return m_error; }
bool is_success() const { return m_error == ESUCCESS; }
bool is_error() const { return !is_success(); }
private: private:
template<typename T> friend class KResultOr; template<typename T> friend class KResultOr;
KResult() { } KResult() { }

View file

@ -1056,11 +1056,10 @@ bool ProcFSInode::add_child(InodeIdentifier child_id, const String& name, byte f
return false; return false;
} }
bool ProcFSInode::remove_child(const String& name, int& error) KResult ProcFSInode::remove_child(const String& name)
{ {
(void)name; (void)name;
error = -EPERM; return KResult(-EPERM);
return false;
} }
ProcFSInodeCustomData::~ProcFSInodeCustomData() ProcFSInodeCustomData::~ProcFSInodeCustomData()

View file

@ -84,7 +84,7 @@ private:
virtual void flush_metadata() override; virtual void flush_metadata() override;
virtual ssize_t write_bytes(off_t, ssize_t, const byte* buffer, FileDescriptor*) override; virtual ssize_t write_bytes(off_t, ssize_t, const byte* buffer, FileDescriptor*) override;
virtual bool add_child(InodeIdentifier child_id, const String& name, byte file_type, int& error) override; virtual bool add_child(InodeIdentifier child_id, const String& name, byte file_type, int& error) override;
virtual bool remove_child(const String& name, int& error) override; virtual KResult remove_child(const String& name) override;
virtual RetainPtr<Inode> parent() const override; virtual RetainPtr<Inode> parent() const override;
virtual size_t directory_entry_count() const override; virtual size_t directory_entry_count() const override;
virtual KResult chmod(mode_t) override; virtual KResult chmod(mode_t) override;

View file

@ -2129,20 +2129,14 @@ int Process::sys$unlink(const char* pathname)
{ {
if (!validate_read_str(pathname)) if (!validate_read_str(pathname))
return -EFAULT; return -EFAULT;
int error; return VFS::the().unlink(String(pathname), cwd_inode());
if (!VFS::the().unlink(String(pathname), cwd_inode(), error))
return error;
return 0;
} }
int Process::sys$rmdir(const char* pathname) int Process::sys$rmdir(const char* pathname)
{ {
if (!validate_read_str(pathname)) if (!validate_read_str(pathname))
return -EFAULT; return -EFAULT;
int error; return VFS::the().rmdir(String(pathname), cwd_inode());
if (!VFS::the().rmdir(String(pathname), cwd_inode(), error))
return error;
return 0;
} }
int Process::sys$read_tsc(dword* lsw, dword* msw) int Process::sys$read_tsc(dword* lsw, dword* msw)

View file

@ -290,12 +290,10 @@ bool SynthFSInode::add_child(InodeIdentifier child_id, const String& name, byte
return false; return false;
} }
bool SynthFSInode::remove_child(const String& name, int& error) KResult SynthFSInode::remove_child(const String& name)
{ {
(void) name; (void)name;
(void) error;
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
return false;
} }
SynthFSInodeCustomData::~SynthFSInodeCustomData() SynthFSInodeCustomData::~SynthFSInodeCustomData()

View file

@ -64,7 +64,7 @@ private:
virtual void flush_metadata() override; virtual void flush_metadata() override;
virtual ssize_t write_bytes(off_t, ssize_t, const byte* buffer, FileDescriptor*) override; virtual ssize_t write_bytes(off_t, ssize_t, const byte* buffer, FileDescriptor*) override;
virtual bool add_child(InodeIdentifier child_id, const String& name, byte file_type, int& error) override; virtual bool add_child(InodeIdentifier child_id, const String& name, byte file_type, int& error) override;
virtual bool remove_child(const String& name, int& error) override; virtual KResult remove_child(const String& name) override;
virtual RetainPtr<Inode> parent() const override; virtual RetainPtr<Inode> parent() const override;
virtual size_t directory_entry_count() const override; virtual size_t directory_entry_count() const override;
virtual KResult chmod(mode_t) override; virtual KResult chmod(mode_t) override;

View file

@ -410,80 +410,56 @@ bool VFS::link(const String& old_path, const String& new_path, Inode& base, int&
return true; return true;
} }
bool VFS::unlink(const String& path, Inode& base, int& error) KResult VFS::unlink(const String& path, Inode& base)
{ {
RetainPtr<Inode> parent_inode; RetainPtr<Inode> parent_inode;
auto inode = resolve_path_to_inode(path, base, error, &parent_inode); auto inode_or_error = resolve_path_to_inode(path, base, &parent_inode);
if (!inode) if (inode_or_error.is_error())
return false; return inode_or_error.error();
auto inode = inode_or_error.value();
if (inode->is_directory()) { if (inode->is_directory())
error = -EISDIR; return KResult(-EISDIR);
return false;
}
if (!parent_inode->metadata().may_write(*current)) { if (!parent_inode->metadata().may_write(*current))
error = -EACCES; return KResult(-EACCES);
return false;
}
if (!parent_inode->remove_child(FileSystemPath(path).basename(), error)) return parent_inode->remove_child(FileSystemPath(path).basename());
return false;
error = 0;
return true;
} }
bool VFS::rmdir(const String& path, Inode& base, int& error) KResult VFS::rmdir(const String& path, Inode& base)
{ {
error = -EWHYTHO;
RetainPtr<Inode> parent_inode; RetainPtr<Inode> parent_inode;
auto inode = resolve_path_to_inode(path, base, error, &parent_inode); auto inode_or_error = resolve_path_to_inode(path, base, &parent_inode);
if (!inode) if (inode_or_error.is_error())
return false; return KResult(inode_or_error.error());
if (inode->fs().is_readonly()) { auto inode = inode_or_error.value();
error = -EROFS; if (inode->fs().is_readonly())
return false; return KResult(-EROFS);
}
// FIXME: We should return EINVAL if the last component of the path is "." // FIXME: We should return EINVAL if the last component of the path is "."
// FIXME: We should return ENOTEMPTY if the last component of the path is ".." // FIXME: We should return ENOTEMPTY if the last component of the path is ".."
if (!inode->is_directory()) { if (!inode->is_directory())
error = -ENOTDIR; return KResult(-ENOTDIR);
return false;
}
if (!parent_inode->metadata().may_write(*current)) { if (!parent_inode->metadata().may_write(*current))
error = -EACCES; return KResult(-EACCES);
return false;
}
if (inode->directory_entry_count() != 2) { if (inode->directory_entry_count() != 2)
error = -ENOTEMPTY; return KResult(-ENOTEMPTY);
return false;
}
dbgprintf("VFS::rmdir: Removing inode %u:%u from parent %u:%u\n", inode->fsid(), inode->index(), parent_inode->fsid(), parent_inode->index()); auto result = inode->remove_child(".");
if (result.is_error())
return result;
// To do: result = inode->remove_child("..");
// - Remove '.' in target (--child.link_count) if (result.is_error())
// - Remove '..' in target (--parent.link_count) return result;
// - Remove target from its parent (--parent.link_count)
if (!inode->remove_child(".", error))
return false;
if (!inode->remove_child("..", error))
return false;
// FIXME: The reverse_lookup here can definitely be avoided. // FIXME: The reverse_lookup here can definitely be avoided.
if (!parent_inode->remove_child(parent_inode->reverse_lookup(inode->identifier()), error)) return parent_inode->remove_child(parent_inode->reverse_lookup(inode->identifier()));
return false;
error = 0;
return true;
} }
KResultOr<InodeIdentifier> VFS::resolve_symbolic_link(InodeIdentifier base, Inode& symlink_inode) KResultOr<InodeIdentifier> VFS::resolve_symbolic_link(InodeIdentifier base, Inode& symlink_inode)

View file

@ -67,8 +67,8 @@ public:
RetainPtr<FileDescriptor> create(const String& path, int& error, int options, mode_t mode, Inode& base); RetainPtr<FileDescriptor> create(const String& path, int& error, int options, mode_t mode, Inode& base);
KResult mkdir(const String& path, mode_t mode, Inode& base); KResult mkdir(const String& path, mode_t mode, Inode& base);
bool link(const String& old_path, const String& new_path, Inode& base, int& error); bool link(const String& old_path, const String& new_path, Inode& base, int& error);
bool unlink(const String& path, Inode& base, int& error); KResult unlink(const String& path, Inode& base);
bool rmdir(const String& path, Inode& base, int& error); KResult rmdir(const String& path, Inode& base);
KResult chmod(const String& path, mode_t, Inode& base); KResult chmod(const String& path, mode_t, Inode& base);
KResult chown(const String& path, uid_t, gid_t, Inode& base); KResult chown(const String& path, uid_t, gid_t, Inode& base);
KResult access(const String& path, int mode, Inode& base); KResult access(const String& path, int mode, Inode& base);