diff options
Diffstat (limited to 'fs/eventpoll.c')
-rw-r--r-- | fs/eventpoll.c | 57 |
1 files changed, 14 insertions, 43 deletions
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index a415f42d32cf..990c01d2d66b 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -257,25 +257,6 @@ static inline int ep_cmp_ffd(struct epoll_filefd *p1, | |||
257 | (p1->file < p2->file ? -1 : p1->fd - p2->fd)); | 257 | (p1->file < p2->file ? -1 : p1->fd - p2->fd)); |
258 | } | 258 | } |
259 | 259 | ||
260 | /* Special initialization for the RB tree node to detect linkage */ | ||
261 | static inline void ep_rb_initnode(struct rb_node *n) | ||
262 | { | ||
263 | rb_set_parent(n, n); | ||
264 | } | ||
265 | |||
266 | /* Removes a node from the RB tree and marks it for a fast is-linked check */ | ||
267 | static inline void ep_rb_erase(struct rb_node *n, struct rb_root *r) | ||
268 | { | ||
269 | rb_erase(n, r); | ||
270 | rb_set_parent(n, n); | ||
271 | } | ||
272 | |||
273 | /* Fast check to verify that the item is linked to the main RB tree */ | ||
274 | static inline int ep_rb_linked(struct rb_node *n) | ||
275 | { | ||
276 | return rb_parent(n) != n; | ||
277 | } | ||
278 | |||
279 | /* Tells us if the item is currently linked */ | 260 | /* Tells us if the item is currently linked */ |
280 | static inline int ep_is_linked(struct list_head *p) | 261 | static inline int ep_is_linked(struct list_head *p) |
281 | { | 262 | { |
@@ -283,13 +264,13 @@ static inline int ep_is_linked(struct list_head *p) | |||
283 | } | 264 | } |
284 | 265 | ||
285 | /* Get the "struct epitem" from a wait queue pointer */ | 266 | /* Get the "struct epitem" from a wait queue pointer */ |
286 | static inline struct epitem * ep_item_from_wait(wait_queue_t *p) | 267 | static inline struct epitem *ep_item_from_wait(wait_queue_t *p) |
287 | { | 268 | { |
288 | return container_of(p, struct eppoll_entry, wait)->base; | 269 | return container_of(p, struct eppoll_entry, wait)->base; |
289 | } | 270 | } |
290 | 271 | ||
291 | /* Get the "struct epitem" from an epoll queue wrapper */ | 272 | /* Get the "struct epitem" from an epoll queue wrapper */ |
292 | static inline struct epitem * ep_item_from_epqueue(poll_table *p) | 273 | static inline struct epitem *ep_item_from_epqueue(poll_table *p) |
293 | { | 274 | { |
294 | return container_of(p, struct ep_pqueue, pt)->epi; | 275 | return container_of(p, struct ep_pqueue, pt)->epi; |
295 | } | 276 | } |
@@ -411,8 +392,7 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi) | |||
411 | list_del_init(&epi->fllink); | 392 | list_del_init(&epi->fllink); |
412 | spin_unlock(&file->f_ep_lock); | 393 | spin_unlock(&file->f_ep_lock); |
413 | 394 | ||
414 | if (ep_rb_linked(&epi->rbn)) | 395 | rb_erase(&epi->rbn, &ep->rbr); |
415 | ep_rb_erase(&epi->rbn, &ep->rbr); | ||
416 | 396 | ||
417 | spin_lock_irqsave(&ep->lock, flags); | 397 | spin_lock_irqsave(&ep->lock, flags); |
418 | if (ep_is_linked(&epi->rdllink)) | 398 | if (ep_is_linked(&epi->rdllink)) |
@@ -728,7 +708,6 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, | |||
728 | goto error_return; | 708 | goto error_return; |
729 | 709 | ||
730 | /* Item initialization follow here ... */ | 710 | /* Item initialization follow here ... */ |
731 | ep_rb_initnode(&epi->rbn); | ||
732 | INIT_LIST_HEAD(&epi->rdllink); | 711 | INIT_LIST_HEAD(&epi->rdllink); |
733 | INIT_LIST_HEAD(&epi->fllink); | 712 | INIT_LIST_HEAD(&epi->fllink); |
734 | INIT_LIST_HEAD(&epi->pwqlist); | 713 | INIT_LIST_HEAD(&epi->pwqlist); |
@@ -1071,8 +1050,6 @@ asmlinkage long sys_epoll_create(int size) | |||
1071 | { | 1050 | { |
1072 | int error, fd = -1; | 1051 | int error, fd = -1; |
1073 | struct eventpoll *ep; | 1052 | struct eventpoll *ep; |
1074 | struct inode *inode; | ||
1075 | struct file *file; | ||
1076 | 1053 | ||
1077 | DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n", | 1054 | DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n", |
1078 | current, size)); | 1055 | current, size)); |
@@ -1082,29 +1059,24 @@ asmlinkage long sys_epoll_create(int size) | |||
1082 | * structure ( "struct eventpoll" ). | 1059 | * structure ( "struct eventpoll" ). |
1083 | */ | 1060 | */ |
1084 | error = -EINVAL; | 1061 | error = -EINVAL; |
1085 | if (size <= 0 || (error = ep_alloc(&ep)) != 0) | 1062 | if (size <= 0 || (error = ep_alloc(&ep)) < 0) { |
1063 | fd = error; | ||
1086 | goto error_return; | 1064 | goto error_return; |
1065 | } | ||
1087 | 1066 | ||
1088 | /* | 1067 | /* |
1089 | * Creates all the items needed to setup an eventpoll file. That is, | 1068 | * Creates all the items needed to setup an eventpoll file. That is, |
1090 | * a file structure, and inode and a free file descriptor. | 1069 | * a file structure and a free file descriptor. |
1091 | */ | 1070 | */ |
1092 | error = anon_inode_getfd(&fd, &inode, &file, "[eventpoll]", | 1071 | fd = anon_inode_getfd("[eventpoll]", &eventpoll_fops, ep); |
1093 | &eventpoll_fops, ep); | 1072 | if (fd < 0) |
1094 | if (error) | 1073 | ep_free(ep); |
1095 | goto error_free; | ||
1096 | 1074 | ||
1075 | error_return: | ||
1097 | DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n", | 1076 | DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n", |
1098 | current, size, fd)); | 1077 | current, size, fd)); |
1099 | 1078 | ||
1100 | return fd; | 1079 | return fd; |
1101 | |||
1102 | error_free: | ||
1103 | ep_free(ep); | ||
1104 | error_return: | ||
1105 | DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n", | ||
1106 | current, size, error)); | ||
1107 | return error; | ||
1108 | } | 1080 | } |
1109 | 1081 | ||
1110 | /* | 1082 | /* |
@@ -1262,7 +1234,7 @@ error_return: | |||
1262 | return error; | 1234 | return error; |
1263 | } | 1235 | } |
1264 | 1236 | ||
1265 | #ifdef TIF_RESTORE_SIGMASK | 1237 | #ifdef HAVE_SET_RESTORE_SIGMASK |
1266 | 1238 | ||
1267 | /* | 1239 | /* |
1268 | * Implement the event wait interface for the eventpoll file. It is the kernel | 1240 | * Implement the event wait interface for the eventpoll file. It is the kernel |
@@ -1300,7 +1272,7 @@ asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events, | |||
1300 | if (error == -EINTR) { | 1272 | if (error == -EINTR) { |
1301 | memcpy(¤t->saved_sigmask, &sigsaved, | 1273 | memcpy(¤t->saved_sigmask, &sigsaved, |
1302 | sizeof(sigsaved)); | 1274 | sizeof(sigsaved)); |
1303 | set_thread_flag(TIF_RESTORE_SIGMASK); | 1275 | set_restore_sigmask(); |
1304 | } else | 1276 | } else |
1305 | sigprocmask(SIG_SETMASK, &sigsaved, NULL); | 1277 | sigprocmask(SIG_SETMASK, &sigsaved, NULL); |
1306 | } | 1278 | } |
@@ -1308,7 +1280,7 @@ asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events, | |||
1308 | return error; | 1280 | return error; |
1309 | } | 1281 | } |
1310 | 1282 | ||
1311 | #endif /* #ifdef TIF_RESTORE_SIGMASK */ | 1283 | #endif /* HAVE_SET_RESTORE_SIGMASK */ |
1312 | 1284 | ||
1313 | static int __init eventpoll_init(void) | 1285 | static int __init eventpoll_init(void) |
1314 | { | 1286 | { |
@@ -1330,4 +1302,3 @@ static int __init eventpoll_init(void) | |||
1330 | return 0; | 1302 | return 0; |
1331 | } | 1303 | } |
1332 | fs_initcall(eventpoll_init); | 1304 | fs_initcall(eventpoll_init); |
1333 | |||