Kernel: Make OpenFileDescrptor store VFS::File instead of inode+path

This commit is contained in:
Bananymous 2024-09-14 20:10:21 +03:00
parent 3a352078de
commit ea4ec2eafc
2 changed files with 45 additions and 33 deletions

View File

@ -52,6 +52,7 @@ namespace Kernel
BAN::ErrorOr<size_t> read_dir_entries(int fd, struct dirent* list, size_t list_len); BAN::ErrorOr<size_t> read_dir_entries(int fd, struct dirent* list, size_t list_len);
BAN::ErrorOr<const VirtualFileSystem::File&> file_of(int) const;
BAN::ErrorOr<BAN::StringView> path_of(int) const; BAN::ErrorOr<BAN::StringView> path_of(int) const;
BAN::ErrorOr<BAN::RefPtr<Inode>> inode_of(int); BAN::ErrorOr<BAN::RefPtr<Inode>> inode_of(int);
BAN::ErrorOr<int> flags_of(int) const; BAN::ErrorOr<int> flags_of(int) const;
@ -59,15 +60,16 @@ namespace Kernel
private: private:
struct OpenFileDescription : public BAN::RefCounted<OpenFileDescription> struct OpenFileDescription : public BAN::RefCounted<OpenFileDescription>
{ {
OpenFileDescription(BAN::RefPtr<Inode> inode, BAN::String path, off_t offset, int flags) OpenFileDescription(VirtualFileSystem::File file, off_t offset, int flags)
: inode(inode) : file(BAN::move(file))
, path(BAN::move(path))
, offset(offset) , offset(offset)
, flags(flags) , flags(flags)
{ } { }
BAN::RefPtr<Inode> inode; BAN::RefPtr<Inode> inode() const { return file.inode; }
BAN::String path; BAN::StringView path() const { return file.canonical_path.sv(); }
VirtualFileSystem::File file;
off_t offset { 0 }; off_t offset { 0 };
int flags { 0 }; int flags { 0 };

View File

@ -38,7 +38,11 @@ namespace Kernel
auto& open_file = other.m_open_files[fd]; auto& open_file = other.m_open_files[fd];
auto result = BAN::RefPtr<OpenFileDescription>::create(open_file->inode, open_file->path, open_file->offset, open_file->flags); VirtualFileSystem::File temp_file;
temp_file.inode = open_file->inode();
TRY(temp_file.canonical_path.append(open_file->path()));
auto result = BAN::RefPtr<OpenFileDescription>::create(BAN::move(temp_file), open_file->offset, open_file->flags);
if (result.is_error()) if (result.is_error())
{ {
@ -48,10 +52,10 @@ namespace Kernel
m_open_files[fd] = result.release_value(); m_open_files[fd] = result.release_value();
if (m_open_files[fd]->path == "<pipe wr>"_sv) if (m_open_files[fd]->path() == "<pipe wr>"_sv)
{ {
ASSERT(m_open_files[fd]->inode->is_pipe()); ASSERT(m_open_files[fd]->inode()->is_pipe());
static_cast<Pipe*>(m_open_files[fd]->inode.ptr())->clone_writing(); static_cast<Pipe*>(m_open_files[fd]->inode().ptr())->clone_writing();
} }
} }
@ -75,7 +79,7 @@ namespace Kernel
TRY(file.inode->truncate(0)); TRY(file.inode->truncate(0));
int fd = TRY(get_free_fd()); int fd = TRY(get_free_fd());
m_open_files[fd] = TRY(BAN::RefPtr<OpenFileDescription>::create(file.inode, BAN::move(file.canonical_path), 0, flags)); m_open_files[fd] = TRY(BAN::RefPtr<OpenFileDescription>::create(BAN::move(file), 0, flags));
return fd; return fd;
} }
@ -140,7 +144,7 @@ namespace Kernel
auto socket = TRY(NetworkManager::get().create_socket(sock_domain, sock_type, 0777, m_credentials.euid(), m_credentials.egid())); auto socket = TRY(NetworkManager::get().create_socket(sock_domain, sock_type, 0777, m_credentials.euid(), m_credentials.egid()));
int fd = TRY(get_free_fd()); int fd = TRY(get_free_fd());
m_open_files[fd] = TRY(BAN::RefPtr<OpenFileDescription>::create(socket, "<socket>"_sv, 0, O_RDWR | extra_flags)); m_open_files[fd] = TRY(BAN::RefPtr<OpenFileDescription>::create(VirtualFileSystem::File(socket, "<socket>"_sv), 0, O_RDWR | extra_flags));
return fd; return fd;
} }
@ -149,8 +153,8 @@ namespace Kernel
TRY(get_free_fd_pair(fds)); TRY(get_free_fd_pair(fds));
auto pipe = TRY(Pipe::create(m_credentials)); auto pipe = TRY(Pipe::create(m_credentials));
m_open_files[fds[0]] = TRY(BAN::RefPtr<OpenFileDescription>::create(pipe, "<pipe rd>"_sv, 0, O_RDONLY)); m_open_files[fds[0]] = TRY(BAN::RefPtr<OpenFileDescription>::create(VirtualFileSystem::File(pipe, "<pipe rd>"_sv), 0, O_RDONLY));
m_open_files[fds[1]] = TRY(BAN::RefPtr<OpenFileDescription>::create(pipe, "<pipe wr>"_sv, 0, O_WRONLY)); m_open_files[fds[1]] = TRY(BAN::RefPtr<OpenFileDescription>::create(VirtualFileSystem::File(pipe, "<pipe wr>"_sv), 0, O_WRONLY));
return {}; return {};
} }
@ -162,10 +166,10 @@ namespace Kernel
int result = TRY(get_free_fd()); int result = TRY(get_free_fd());
m_open_files[result] = m_open_files[fildes]; m_open_files[result] = m_open_files[fildes];
if (m_open_files[result]->path == "<pipe wr>"_sv) if (m_open_files[result]->path() == "<pipe wr>"_sv)
{ {
ASSERT(m_open_files[result]->inode->is_pipe()); ASSERT(m_open_files[result]->inode()->is_pipe());
static_cast<Pipe*>(m_open_files[result]->inode.ptr())->clone_writing(); static_cast<Pipe*>(m_open_files[result]->inode().ptr())->clone_writing();
} }
return result; return result;
@ -185,10 +189,10 @@ namespace Kernel
m_open_files[fildes2] = m_open_files[fildes]; m_open_files[fildes2] = m_open_files[fildes];
m_open_files[fildes2]->flags &= ~O_CLOEXEC; m_open_files[fildes2]->flags &= ~O_CLOEXEC;
if (m_open_files[fildes2]->path == "<pipe wr>"_sv) if (m_open_files[fildes2]->path() == "<pipe wr>"_sv)
{ {
ASSERT(m_open_files[fildes2]->inode->is_pipe()); ASSERT(m_open_files[fildes2]->inode()->is_pipe());
static_cast<Pipe*>(m_open_files[fildes2]->inode.ptr())->clone_writing(); static_cast<Pipe*>(m_open_files[fildes2]->inode().ptr())->clone_writing();
} }
return fildes; return fildes;
@ -234,7 +238,7 @@ namespace Kernel
base_offset = m_open_files[fd]->offset; base_offset = m_open_files[fd]->offset;
break; break;
case SEEK_END: case SEEK_END:
base_offset = m_open_files[fd]->inode->size(); base_offset = m_open_files[fd]->inode()->size();
break; break;
default: default:
return BAN::Error::from_errno(EINVAL); return BAN::Error::from_errno(EINVAL);
@ -258,7 +262,7 @@ namespace Kernel
BAN::ErrorOr<void> OpenFileDescriptorSet::truncate(int fd, off_t length) BAN::ErrorOr<void> OpenFileDescriptorSet::truncate(int fd, off_t length)
{ {
TRY(validate_fd(fd)); TRY(validate_fd(fd));
return m_open_files[fd]->inode->truncate(length); return m_open_files[fd]->inode()->truncate(length);
} }
static void read_stat_from_inode(BAN::RefPtr<Inode> inode, struct stat* out) static void read_stat_from_inode(BAN::RefPtr<Inode> inode, struct stat* out)
@ -281,7 +285,7 @@ namespace Kernel
BAN::ErrorOr<void> OpenFileDescriptorSet::fstat(int fd, struct stat* out) const BAN::ErrorOr<void> OpenFileDescriptorSet::fstat(int fd, struct stat* out) const
{ {
TRY(validate_fd(fd)); TRY(validate_fd(fd));
read_stat_from_inode(m_open_files[fd]->inode, out); read_stat_from_inode(m_open_files[fd]->inode(), out);
return {}; return {};
} }
@ -319,10 +323,10 @@ namespace Kernel
{ {
TRY(validate_fd(fd)); TRY(validate_fd(fd));
if (m_open_files[fd]->path == "<pipe wr>"_sv) if (m_open_files[fd]->path() == "<pipe wr>"_sv)
{ {
ASSERT(m_open_files[fd]->inode->is_pipe()); ASSERT(m_open_files[fd]->inode()->is_pipe());
static_cast<Pipe*>(m_open_files[fd]->inode.ptr())->close_writing(); static_cast<Pipe*>(m_open_files[fd]->inode().ptr())->close_writing();
} }
m_open_files[fd].clear(); m_open_files[fd].clear();
@ -351,9 +355,9 @@ namespace Kernel
{ {
TRY(validate_fd(fd)); TRY(validate_fd(fd));
auto& open_file = m_open_files[fd]; auto& open_file = m_open_files[fd];
if ((open_file->flags & O_NONBLOCK) && !open_file->inode->can_read()) if ((open_file->flags & O_NONBLOCK) && !open_file->inode()->can_read())
return 0; return 0;
size_t nread = TRY(open_file->inode->read(open_file->offset, buffer)); size_t nread = TRY(open_file->inode()->read(open_file->offset, buffer));
open_file->offset += nread; open_file->offset += nread;
return nread; return nread;
} }
@ -362,11 +366,11 @@ namespace Kernel
{ {
TRY(validate_fd(fd)); TRY(validate_fd(fd));
auto& open_file = m_open_files[fd]; auto& open_file = m_open_files[fd];
if ((open_file->flags & O_NONBLOCK) && !open_file->inode->can_write()) if ((open_file->flags & O_NONBLOCK) && !open_file->inode()->can_write())
return 0; return 0;
if (open_file->flags & O_APPEND) if (open_file->flags & O_APPEND)
open_file->offset = open_file->inode->size(); open_file->offset = open_file->inode()->size();
size_t nwrite = TRY(open_file->inode->write(open_file->offset, buffer)); size_t nwrite = TRY(open_file->inode()->write(open_file->offset, buffer));
open_file->offset += nwrite; open_file->offset += nwrite;
return nwrite; return nwrite;
} }
@ -377,19 +381,25 @@ namespace Kernel
auto& open_file = m_open_files[fd]; auto& open_file = m_open_files[fd];
if (!(open_file->flags & O_RDONLY)) if (!(open_file->flags & O_RDONLY))
return BAN::Error::from_errno(EACCES); return BAN::Error::from_errno(EACCES);
return TRY(open_file->inode->list_next_inodes(open_file->offset++, list, list_len)); return TRY(open_file->inode()->list_next_inodes(open_file->offset++, list, list_len));
}
BAN::ErrorOr<const VirtualFileSystem::File&> OpenFileDescriptorSet::file_of(int fd) const
{
TRY(validate_fd(fd));
return m_open_files[fd]->file;
} }
BAN::ErrorOr<BAN::StringView> OpenFileDescriptorSet::path_of(int fd) const BAN::ErrorOr<BAN::StringView> OpenFileDescriptorSet::path_of(int fd) const
{ {
TRY(validate_fd(fd)); TRY(validate_fd(fd));
return m_open_files[fd]->path.sv(); return m_open_files[fd]->path();
} }
BAN::ErrorOr<BAN::RefPtr<Inode>> OpenFileDescriptorSet::inode_of(int fd) BAN::ErrorOr<BAN::RefPtr<Inode>> OpenFileDescriptorSet::inode_of(int fd)
{ {
TRY(validate_fd(fd)); TRY(validate_fd(fd));
return m_open_files[fd]->inode; return m_open_files[fd]->inode();
} }
BAN::ErrorOr<int> OpenFileDescriptorSet::flags_of(int fd) const BAN::ErrorOr<int> OpenFileDescriptorSet::flags_of(int fd) const