summaryrefslogtreecommitdiff
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
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.
-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 };