aboutsummaryrefslogtreecommitdiffstats
path: root/fs/eventpoll.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/eventpoll.c')
-rw-r--r--fs/eventpoll.c38
1 files changed, 32 insertions, 6 deletions
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index ae1dbcf47e97..cde60741cad2 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -94,6 +94,11 @@
94/* Epoll private bits inside the event mask */ 94/* Epoll private bits inside the event mask */
95#define EP_PRIVATE_BITS (EPOLLWAKEUP | EPOLLONESHOT | EPOLLET | EPOLLEXCLUSIVE) 95#define EP_PRIVATE_BITS (EPOLLWAKEUP | EPOLLONESHOT | EPOLLET | EPOLLEXCLUSIVE)
96 96
97#define EPOLLINOUT_BITS (POLLIN | POLLOUT)
98
99#define EPOLLEXCLUSIVE_OK_BITS (EPOLLINOUT_BITS | POLLERR | POLLHUP | \
100 EPOLLWAKEUP | EPOLLET | EPOLLEXCLUSIVE)
101
97/* Maximum number of nesting allowed inside epoll sets */ 102/* Maximum number of nesting allowed inside epoll sets */
98#define EP_MAX_NESTS 4 103#define EP_MAX_NESTS 4
99 104
@@ -1068,7 +1073,22 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *k
1068 * wait list. 1073 * wait list.
1069 */ 1074 */
1070 if (waitqueue_active(&ep->wq)) { 1075 if (waitqueue_active(&ep->wq)) {
1071 ewake = 1; 1076 if ((epi->event.events & EPOLLEXCLUSIVE) &&
1077 !((unsigned long)key & POLLFREE)) {
1078 switch ((unsigned long)key & EPOLLINOUT_BITS) {
1079 case POLLIN:
1080 if (epi->event.events & POLLIN)
1081 ewake = 1;
1082 break;
1083 case POLLOUT:
1084 if (epi->event.events & POLLOUT)
1085 ewake = 1;
1086 break;
1087 case 0:
1088 ewake = 1;
1089 break;
1090 }
1091 }
1072 wake_up_locked(&ep->wq); 1092 wake_up_locked(&ep->wq);
1073 } 1093 }
1074 if (waitqueue_active(&ep->poll_wait)) 1094 if (waitqueue_active(&ep->poll_wait))
@@ -1875,9 +1895,13 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
1875 * so EPOLLEXCLUSIVE is not allowed for a EPOLL_CTL_MOD operation. 1895 * so EPOLLEXCLUSIVE is not allowed for a EPOLL_CTL_MOD operation.
1876 * Also, we do not currently supported nested exclusive wakeups. 1896 * Also, we do not currently supported nested exclusive wakeups.
1877 */ 1897 */
1878 if ((epds.events & EPOLLEXCLUSIVE) && (op == EPOLL_CTL_MOD || 1898 if (epds.events & EPOLLEXCLUSIVE) {
1879 (op == EPOLL_CTL_ADD && is_file_epoll(tf.file)))) 1899 if (op == EPOLL_CTL_MOD)
1880 goto error_tgt_fput; 1900 goto error_tgt_fput;
1901 if (op == EPOLL_CTL_ADD && (is_file_epoll(tf.file) ||
1902 (epds.events & ~EPOLLEXCLUSIVE_OK_BITS)))
1903 goto error_tgt_fput;
1904 }
1881 1905
1882 /* 1906 /*
1883 * At this point it is safe to assume that the "private_data" contains 1907 * At this point it is safe to assume that the "private_data" contains
@@ -1950,8 +1974,10 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
1950 break; 1974 break;
1951 case EPOLL_CTL_MOD: 1975 case EPOLL_CTL_MOD:
1952 if (epi) { 1976 if (epi) {
1953 epds.events |= POLLERR | POLLHUP; 1977 if (!(epi->event.events & EPOLLEXCLUSIVE)) {
1954 error = ep_modify(ep, epi, &epds); 1978 epds.events |= POLLERR | POLLHUP;
1979 error = ep_modify(ep, epi, &epds);
1980 }
1955 } else 1981 } else
1956 error = -ENOENT; 1982 error = -ENOENT;
1957 break; 1983 break;