epoll: avoid double-inserts in case of EFAULT
commit9ce209d64d820a6d5ed6b952e2c0f917faad6031
authorDavide Libenzi <davidel@xmailserver.org>
Fri, 17 Oct 2008 23:17:40 +0000 (17 16:17 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 26 Oct 2008 19:09:49 +0000 (26 12:09 -0700)
tree817c5bd01e6666c8269d29d3d8292b5e75ea7fb3
parent4d36a9e65d4966b433b2f3424d9457468bc80e00
epoll: avoid double-inserts in case of EFAULT

In commit f337b9c58332bdecde965b436e47ea4c94d30da0 ("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 <davidel@xmailserver.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/eventpoll.c