kernel: Make file system reference counting work for current directories
All checks were successful
continuous-integration/drone/push Build is passing

Also, make pipes usable again.
This commit is contained in:
apio 2023-05-17 20:37:01 +02:00
parent 1f4c4928cc
commit 8f6bd29da3
Signed by: apio
GPG Key ID: B8A7D06E42258954
5 changed files with 57 additions and 40 deletions

View File

@ -15,9 +15,42 @@ namespace VFS
Device
};
class FileSystem;
class Inode;
class FileSystem
{
public:
virtual SharedPtr<Inode> root_inode() const = 0;
virtual Result<SharedPtr<Inode>> create_file_inode() = 0;
virtual Result<SharedPtr<Inode>> create_dir_inode(SharedPtr<Inode> parent) = 0;
virtual Result<SharedPtr<Inode>> create_device_inode(u32 major, u32 minor) = 0;
virtual Result<void> set_mount_dir(SharedPtr<Inode> 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<Inode> root_inode() const = 0;
virtual Result<SharedPtr<Inode>> create_file_inode() = 0;
virtual Result<SharedPtr<Inode>> create_dir_inode(SharedPtr<Inode> parent) = 0;
virtual Result<SharedPtr<Inode>> create_device_inode(u32 major, u32 minor) = 0;
virtual Result<void> set_mount_dir(SharedPtr<Inode> 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<SharedPtr<Inode>> resolve_path(const char* path, Credentials auth,
SharedPtr<VFS::Inode> working_directory = {});

View File

@ -15,6 +15,9 @@ Result<u64> 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<u64> 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);

View File

@ -90,7 +90,7 @@ Result<u64> 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<u64> 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);

View File

@ -72,7 +72,7 @@ Result<u64> 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<u64> sys_close(Registers*, SyscallArgs args)
if (!descriptor.has_value()) return err(EBADF);
descriptor->inode->fs()->remove_handle();
descriptor->inode->remove_handle();
descriptor = {};

View File

@ -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();
}
}