Skip to content

Commit

Permalink
epoll: avoid double-inserts in case of EFAULT
Browse files Browse the repository at this point in the history
In commit f337b9c ("epoll: drop
unnecessary test") Thomas found that there is an unnecessary (always
true) test in ep_send_events().  The callback never inserts into
->rdllink while the send loop is performed, and also does the
~EP_PRIVATE_BITS test.  Given we're holding the mutex during this time,
the conditions tested inside the loop are always true.

HOWEVER.

The test "!ep_is_linked(&epi->rdllink)" wasn't there because we insert
into ->rdllink, but because the send-events loop might terminate before
the whole list is scanned (-EFAULT).

In such cases, when the loop terminates early, and when a (leftover)
file received an event while we're performing the lockless loop, we need
such test to avoid to double insert the epoll items.  The list_splice()
done a few steps below, will correctly re-insert the ones that were left
on "txlist".

This should fix the kenrel.org bugzilla entry 11831.

Signed-off-by: Davide Libenzi <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
davidel authored and torvalds committed Oct 26, 2008
1 parent 4d36a9e commit 9ce209d
Showing 1 changed file with 9 additions and 2 deletions.
11 changes: 9 additions & 2 deletions fs/eventpoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -930,8 +930,15 @@ static int ep_send_events(struct eventpoll *ep, struct epoll_event __user *event
* inside the main ready-list here.
*/
for (nepi = ep->ovflist; (epi = nepi) != NULL;
nepi = epi->next, epi->next = EP_UNACTIVE_PTR)
list_add_tail(&epi->rdllink, &ep->rdllist);
nepi = epi->next, epi->next = EP_UNACTIVE_PTR) {
/*
* If the above loop quit with errors, the epoll item might still
* be linked to "txlist", and the list_splice() done below will
* take care of those cases.
*/
if (!ep_is_linked(&epi->rdllink))
list_add_tail(&epi->rdllink, &ep->rdllist);
}
/*
* We need to set back ep->ovflist to EP_UNACTIVE_PTR, so that after
* releasing the lock, events will be queued in the normal way inside
Expand Down

0 comments on commit 9ce209d

Please sign in to comment.