Commit 591afa06 authored by Max Kellermann's avatar Max Kellermann

lib/nfs/Connection: detect socket hangup and unregister from epoll

Fixes race condition when epoll_ctl() gets called after the socket has been closed, which may affect a different socket created by another thread meanwhile.
parent 05eac20f
...@@ -416,7 +416,8 @@ NfsConnection::ScheduleSocket() ...@@ -416,7 +416,8 @@ NfsConnection::ScheduleSocket()
SocketMonitor::Open(_fd); SocketMonitor::Open(_fd);
} }
SocketMonitor::Schedule(libnfs_to_events(which_events)); SocketMonitor::Schedule(libnfs_to_events(which_events)
| SocketMonitor::HANGUP);
} }
inline int inline int
...@@ -453,10 +454,14 @@ NfsConnection::OnSocketReady(unsigned flags) ...@@ -453,10 +454,14 @@ NfsConnection::OnSocketReady(unsigned flags)
bool closed = false; bool closed = false;
const bool was_mounted = mount_finished; const bool was_mounted = mount_finished;
if (!mount_finished) if (!mount_finished || (flags & SocketMonitor::HANGUP) != 0)
/* until the mount is finished, the NFS client may use /* until the mount is finished, the NFS client may use
various sockets, therefore we unregister and various sockets, therefore we unregister and
re-register it each time */ re-register it each time */
/* also re-register the socket if we got a HANGUP,
which is a sure sign that libnfs will close the
socket, which can lead to a race condition if
epoll_ctl() is called later */
SocketMonitor::Steal(); SocketMonitor::Steal();
const int result = Service(flags); const int result = Service(flags);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment