summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorPeter Elliott <pelliott@ualberta.ca>2023-02-12 00:49:15 -0700
committerLinus Groh <mail@linusgroh.de>2023-02-19 00:37:37 +0100
commitae5d7f542c256f3f1b4c5003d666e8ef850516e9 (patch)
treea4485fc133eb5e5c977ec9ea580f5ac8653ed9c4 /Kernel
parent2808b0376406a40e31293bb3bcb9170374e90506 (diff)
downloadserenity-ae5d7f542c256f3f1b4c5003d666e8ef850516e9.zip
Kernel: Change polarity of weak ownership between Inode and LocalSocket
There was a bug in which bound Inodes would lose all their references (because localsocket does not reference them), and they would be deallocated, and clients would get ECONNREFUSED as a result. now LocalSocket has a strong reference to inode so that the inode will live as long as the socket, and Inode has a weak reference to the socket, because if the socket stops being referenced anywhere it should not be bound. This still prevents the reference loop that 220b7dd77905b7d573ded093cf88d2dc51f57c69 was trying to fix.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/FileSystem/Inode.cpp2
-rw-r--r--Kernel/FileSystem/Inode.h2
-rw-r--r--Kernel/Net/LocalSocket.cpp5
-rw-r--r--Kernel/Net/LocalSocket.h2
4 files changed, 5 insertions, 6 deletions
diff --git a/Kernel/FileSystem/Inode.cpp b/Kernel/FileSystem/Inode.cpp
index e6b8f1ef14..1eea0c0b82 100644
--- a/Kernel/FileSystem/Inode.cpp
+++ b/Kernel/FileSystem/Inode.cpp
@@ -143,7 +143,7 @@ ErrorOr<void> Inode::set_shared_vmobject(Memory::SharedInodeVMObject& vmobject)
LockRefPtr<LocalSocket> Inode::bound_socket() const
{
- return m_bound_socket;
+ return m_bound_socket.strong_ref();
}
bool Inode::bind_socket(LocalSocket& socket)
diff --git a/Kernel/FileSystem/Inode.h b/Kernel/FileSystem/Inode.h
index c954de927a..8a327ff266 100644
--- a/Kernel/FileSystem/Inode.h
+++ b/Kernel/FileSystem/Inode.h
@@ -131,7 +131,7 @@ private:
FileSystem& m_file_system;
InodeIndex m_index { 0 };
LockWeakPtr<Memory::SharedInodeVMObject> m_shared_vmobject;
- LockRefPtr<LocalSocket> m_bound_socket;
+ LockWeakPtr<LocalSocket> m_bound_socket;
SpinlockProtected<HashTable<InodeWatcher*>, LockRank::None> m_watchers {};
bool m_metadata_dirty { false };
LockRefPtr<FIFO> m_fifo;
diff --git a/Kernel/Net/LocalSocket.cpp b/Kernel/Net/LocalSocket.cpp
index bc4afc01e3..4b55e8bea2 100644
--- a/Kernel/Net/LocalSocket.cpp
+++ b/Kernel/Net/LocalSocket.cpp
@@ -260,9 +260,8 @@ void LocalSocket::detach(OpenFileDescription& description)
m_accept_side_fd_open = false;
if (m_bound) {
- auto inode = m_inode.strong_ref();
- if (inode)
- inode->unbind_socket();
+ if (m_inode)
+ m_inode->unbind_socket();
}
}
diff --git a/Kernel/Net/LocalSocket.h b/Kernel/Net/LocalSocket.h
index 91722d72cd..5416bd5373 100644
--- a/Kernel/Net/LocalSocket.h
+++ b/Kernel/Net/LocalSocket.h
@@ -73,7 +73,7 @@ private:
ErrorOr<void> try_set_path(StringView);
// The inode this socket is bound to.
- LockWeakPtr<Inode> m_inode;
+ LockRefPtr<Inode> m_inode;
UserID m_prebind_uid { 0 };
GroupID m_prebind_gid { 0 };