diff --git a/kernel/src/fs/VFS.h b/kernel/src/fs/VFS.h index 8d57a43e..ea0188ce 100644 --- a/kernel/src/fs/VFS.h +++ b/kernel/src/fs/VFS.h @@ -15,9 +15,42 @@ namespace VFS Device }; - class FileSystem; class Inode; + class FileSystem + { + public: + virtual SharedPtr root_inode() const = 0; + + virtual Result> create_file_inode() = 0; + + virtual Result> create_dir_inode(SharedPtr parent) = 0; + + virtual Result> create_device_inode(u32 major, u32 minor) = 0; + + virtual Result set_mount_dir(SharedPtr parent) = 0; + + virtual u64 handles() const + { + return m_handles; + } + + virtual void add_handle() + { + m_handles++; + } + + virtual void remove_handle() + { + m_handles--; + } + + virtual ~FileSystem() = default; + + protected: + u64 m_handles { 0 }; + }; + struct DirectoryEntry { public: @@ -95,6 +128,18 @@ namespace VFS virtual InodeType type() const = 0; virtual usize inode_number() const = 0; + + virtual void add_handle() + { + auto* f = fs(); + if (f) f->add_handle(); + } + + virtual void remove_handle() + { + auto* f = fs(); + if (f) f->remove_handle(); + } }; class FileInode : Inode @@ -204,40 +249,6 @@ namespace VFS virtual ~DeviceInode() = default; }; - class FileSystem - { - public: - virtual SharedPtr root_inode() const = 0; - - virtual Result> create_file_inode() = 0; - - virtual Result> create_dir_inode(SharedPtr parent) = 0; - - virtual Result> create_device_inode(u32 major, u32 minor) = 0; - - virtual Result set_mount_dir(SharedPtr parent) = 0; - - virtual u64 handles() const - { - return m_handles; - } - - virtual void add_handle() - { - m_handles++; - } - - virtual void remove_handle() - { - m_handles--; - } - - virtual ~FileSystem() = default; - - protected: - u64 m_handles { 0 }; - }; - Result> resolve_path(const char* path, Credentials auth, SharedPtr working_directory = {}); diff --git a/kernel/src/sys/chdir.cpp b/kernel/src/sys/chdir.cpp index 7b32e575..9bf67389 100644 --- a/kernel/src/sys/chdir.cpp +++ b/kernel/src/sys/chdir.cpp @@ -15,6 +15,9 @@ Result sys_chdir(Registers*, SyscallArgs args) if (inode->type() != VFS::InodeType::Directory) return err(ENOTDIR); + inode->add_handle(); + if (current->current_directory) current->current_directory->remove_handle(); + current->current_directory = inode; current->current_directory_path = move(path); @@ -30,6 +33,9 @@ Result sys_chdir(Registers*, SyscallArgs args) String new_path = TRY(PathParser::join(old_wdir.is_empty() ? "/"_sv : old_wdir, path.view())); + inode->add_handle(); + if (current->current_directory) current->current_directory->remove_handle(); + current->current_directory = inode; current->current_directory_path = move(new_path); diff --git a/kernel/src/sys/exec.cpp b/kernel/src/sys/exec.cpp index 27f1359c..9ab10568 100644 --- a/kernel/src/sys/exec.cpp +++ b/kernel/src/sys/exec.cpp @@ -90,7 +90,7 @@ Result sys_execve(Registers* regs, SyscallArgs args) if (!descriptor.has_value()) continue; if (descriptor->flags & O_CLOEXEC) { - descriptor->inode->fs()->remove_handle(); + descriptor->inode->remove_handle(); descriptor = {}; } } @@ -139,7 +139,7 @@ Result sys_fork(Registers* regs, SyscallArgs) for (int i = 0; i < FD_MAX; i++) { thread->fd_table[i] = current->fd_table[i]; - if (current->fd_table[i].has_value()) current->fd_table[i]->inode->fs()->add_handle(); + if (current->fd_table[i].has_value()) current->fd_table[i]->inode->add_handle(); } image->apply(thread); diff --git a/kernel/src/sys/open.cpp b/kernel/src/sys/open.cpp index f8d11bc5..9d3a2d9a 100644 --- a/kernel/src/sys/open.cpp +++ b/kernel/src/sys/open.cpp @@ -72,7 +72,7 @@ Result sys_openat(Registers*, SyscallArgs args) kinfoln("openat: opening file %s from dirfd %d, flags %d, mode %#o = fd %d", path.chars(), dirfd, flags, mode, fd); - inode->fs()->add_handle(); + inode->add_handle(); current->fd_table[fd] = FileDescriptor { inode, 0, flags & FLAGS_TO_KEEP }; @@ -90,7 +90,7 @@ Result sys_close(Registers*, SyscallArgs args) if (!descriptor.has_value()) return err(EBADF); - descriptor->inode->fs()->remove_handle(); + descriptor->inode->remove_handle(); descriptor = {}; diff --git a/kernel/src/thread/Scheduler.cpp b/kernel/src/thread/Scheduler.cpp index 824a13a5..52645626 100644 --- a/kernel/src/thread/Scheduler.cpp +++ b/kernel/src/thread/Scheduler.cpp @@ -185,7 +185,7 @@ namespace Scheduler for (int i = 0; i < FD_MAX; i++) { - if (thread->fd_table[i].has_value()) thread->fd_table[i]->inode->fs()->remove_handle(); + if (thread->fd_table[i].has_value()) thread->fd_table[i]->inode->remove_handle(); } }