aboutsummaryrefslogtreecommitdiffstats
path: root/fs/select.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/select.c')
-rw-r--r--fs/select.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/fs/select.c b/fs/select.c
index 0fe0e1469df..8084834e123 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -110,6 +110,7 @@ void poll_initwait(struct poll_wqueues *pwq)
110{ 110{
111 init_poll_funcptr(&pwq->pt, __pollwait); 111 init_poll_funcptr(&pwq->pt, __pollwait);
112 pwq->polling_task = current; 112 pwq->polling_task = current;
113 pwq->triggered = 0;
113 pwq->error = 0; 114 pwq->error = 0;
114 pwq->table = NULL; 115 pwq->table = NULL;
115 pwq->inline_index = 0; 116 pwq->inline_index = 0;
@@ -168,7 +169,7 @@ static struct poll_table_entry *poll_get_entry(struct poll_wqueues *p)
168 return table->entry++; 169 return table->entry++;
169} 170}
170 171
171static int pollwake(wait_queue_t *wait, unsigned mode, int sync, void *key) 172static int __pollwake(wait_queue_t *wait, unsigned mode, int sync, void *key)
172{ 173{
173 struct poll_wqueues *pwq = wait->private; 174 struct poll_wqueues *pwq = wait->private;
174 DECLARE_WAITQUEUE(dummy_wait, pwq->polling_task); 175 DECLARE_WAITQUEUE(dummy_wait, pwq->polling_task);
@@ -194,6 +195,16 @@ static int pollwake(wait_queue_t *wait, unsigned mode, int sync, void *key)
194 return default_wake_function(&dummy_wait, mode, sync, key); 195 return default_wake_function(&dummy_wait, mode, sync, key);
195} 196}
196 197
198static int pollwake(wait_queue_t *wait, unsigned mode, int sync, void *key)
199{
200 struct poll_table_entry *entry;
201
202 entry = container_of(wait, struct poll_table_entry, wait);
203 if (key && !((unsigned long)key & entry->key))
204 return 0;
205 return __pollwake(wait, mode, sync, key);
206}
207
197/* Add a new entry */ 208/* Add a new entry */
198static void __pollwait(struct file *filp, wait_queue_head_t *wait_address, 209static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,
199 poll_table *p) 210 poll_table *p)
@@ -205,6 +216,7 @@ static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,
205 get_file(filp); 216 get_file(filp);
206 entry->filp = filp; 217 entry->filp = filp;
207 entry->wait_address = wait_address; 218 entry->wait_address = wait_address;
219 entry->key = p->key;
208 init_waitqueue_func_entry(&entry->wait, pollwake); 220 init_waitqueue_func_entry(&entry->wait, pollwake);
209 entry->wait.private = pwq; 221 entry->wait.private = pwq;
210 add_wait_queue(wait_address, &entry->wait); 222 add_wait_queue(wait_address, &entry->wait);
@@ -362,6 +374,18 @@ get_max:
362#define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR) 374#define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR)
363#define POLLEX_SET (POLLPRI) 375#define POLLEX_SET (POLLPRI)
364 376
377static inline void wait_key_set(poll_table *wait, unsigned long in,
378 unsigned long out, unsigned long bit)
379{
380 if (wait) {
381 wait->key = POLLEX_SET;
382 if (in & bit)
383 wait->key |= POLLIN_SET;
384 if (out & bit)
385 wait->key |= POLLOUT_SET;
386 }
387}
388
365int do_select(int n, fd_set_bits *fds, struct timespec *end_time) 389int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
366{ 390{
367 ktime_t expire, *to = NULL; 391 ktime_t expire, *to = NULL;
@@ -418,20 +442,25 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
418 if (file) { 442 if (file) {
419 f_op = file->f_op; 443 f_op = file->f_op;
420 mask = DEFAULT_POLLMASK; 444 mask = DEFAULT_POLLMASK;
421 if (f_op && f_op->poll) 445 if (f_op && f_op->poll) {
422 mask = (*f_op->poll)(file, retval ? NULL : wait); 446 wait_key_set(wait, in, out, bit);
447 mask = (*f_op->poll)(file, wait);
448 }
423 fput_light(file, fput_needed); 449 fput_light(file, fput_needed);
424 if ((mask & POLLIN_SET) && (in & bit)) { 450 if ((mask & POLLIN_SET) && (in & bit)) {
425 res_in |= bit; 451 res_in |= bit;
426 retval++; 452 retval++;
453 wait = NULL;
427 } 454 }
428 if ((mask & POLLOUT_SET) && (out & bit)) { 455 if ((mask & POLLOUT_SET) && (out & bit)) {
429 res_out |= bit; 456 res_out |= bit;
430 retval++; 457 retval++;
458 wait = NULL;
431 } 459 }
432 if ((mask & POLLEX_SET) && (ex & bit)) { 460 if ((mask & POLLEX_SET) && (ex & bit)) {
433 res_ex |= bit; 461 res_ex |= bit;
434 retval++; 462 retval++;
463 wait = NULL;
435 } 464 }
436 } 465 }
437 } 466 }
@@ -685,8 +714,12 @@ static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait)
685 mask = POLLNVAL; 714 mask = POLLNVAL;
686 if (file != NULL) { 715 if (file != NULL) {
687 mask = DEFAULT_POLLMASK; 716 mask = DEFAULT_POLLMASK;
688 if (file->f_op && file->f_op->poll) 717 if (file->f_op && file->f_op->poll) {
718 if (pwait)
719 pwait->key = pollfd->events |
720 POLLERR | POLLHUP;
689 mask = file->f_op->poll(file, pwait); 721 mask = file->f_op->poll(file, pwait);
722 }
690 /* Mask out unneeded events. */ 723 /* Mask out unneeded events. */
691 mask &= pollfd->events | POLLERR | POLLHUP; 724 mask &= pollfd->events | POLLERR | POLLHUP;
692 fput_light(file, fput_needed); 725 fput_light(file, fput_needed);