aboutsummaryrefslogtreecommitdiffstats
path: root/fs/select.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /fs/select.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'fs/select.c')
-rw-r--r--fs/select.c91
1 files changed, 52 insertions, 39 deletions
diff --git a/fs/select.c b/fs/select.c
index 2ef72d96503..d33418fdc85 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -17,7 +17,7 @@
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/sched.h> 18#include <linux/sched.h>
19#include <linux/syscalls.h> 19#include <linux/syscalls.h>
20#include <linux/export.h> 20#include <linux/module.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/poll.h> 22#include <linux/poll.h>
23#include <linux/personality.h> /* for STICKY_TIMEOUTS */ 23#include <linux/personality.h> /* for STICKY_TIMEOUTS */
@@ -220,9 +220,10 @@ static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,
220 struct poll_table_entry *entry = poll_get_entry(pwq); 220 struct poll_table_entry *entry = poll_get_entry(pwq);
221 if (!entry) 221 if (!entry)
222 return; 222 return;
223 entry->filp = get_file(filp); 223 get_file(filp);
224 entry->filp = filp;
224 entry->wait_address = wait_address; 225 entry->wait_address = wait_address;
225 entry->key = p->_key; 226 entry->key = p->key;
226 init_waitqueue_func_entry(&entry->wait, pollwake); 227 init_waitqueue_func_entry(&entry->wait, pollwake);
227 entry->wait.private = pwq; 228 entry->wait.private = pwq;
228 add_wait_queue(wait_address, &entry->wait); 229 add_wait_queue(wait_address, &entry->wait);
@@ -344,10 +345,10 @@ static int max_select_fd(unsigned long n, fd_set_bits *fds)
344 struct fdtable *fdt; 345 struct fdtable *fdt;
345 346
346 /* handle last in-complete long-word first */ 347 /* handle last in-complete long-word first */
347 set = ~(~0UL << (n & (BITS_PER_LONG-1))); 348 set = ~(~0UL << (n & (__NFDBITS-1)));
348 n /= BITS_PER_LONG; 349 n /= __NFDBITS;
349 fdt = files_fdtable(current->files); 350 fdt = files_fdtable(current->files);
350 open_fds = fdt->open_fds + n; 351 open_fds = fdt->open_fds->fds_bits+n;
351 max = 0; 352 max = 0;
352 if (set) { 353 if (set) {
353 set &= BITS(fds, n); 354 set &= BITS(fds, n);
@@ -372,7 +373,7 @@ get_max:
372 max++; 373 max++;
373 set >>= 1; 374 set >>= 1;
374 } while (set); 375 } while (set);
375 max += n * BITS_PER_LONG; 376 max += n * __NFDBITS;
376 } 377 }
377 378
378 return max; 379 return max;
@@ -385,11 +386,13 @@ get_max:
385static inline void wait_key_set(poll_table *wait, unsigned long in, 386static inline void wait_key_set(poll_table *wait, unsigned long in,
386 unsigned long out, unsigned long bit) 387 unsigned long out, unsigned long bit)
387{ 388{
388 wait->_key = POLLEX_SET; 389 if (wait) {
389 if (in & bit) 390 wait->key = POLLEX_SET;
390 wait->_key |= POLLIN_SET; 391 if (in & bit)
391 if (out & bit) 392 wait->key |= POLLIN_SET;
392 wait->_key |= POLLOUT_SET; 393 if (out & bit)
394 wait->key |= POLLOUT_SET;
395 }
393} 396}
394 397
395int do_select(int n, fd_set_bits *fds, struct timespec *end_time) 398int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
@@ -411,7 +414,7 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
411 poll_initwait(&table); 414 poll_initwait(&table);
412 wait = &table.pt; 415 wait = &table.pt;
413 if (end_time && !end_time->tv_sec && !end_time->tv_nsec) { 416 if (end_time && !end_time->tv_sec && !end_time->tv_nsec) {
414 wait->_qproc = NULL; 417 wait = NULL;
415 timed_out = 1; 418 timed_out = 1;
416 } 419 }
417 420
@@ -428,44 +431,45 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
428 for (i = 0; i < n; ++rinp, ++routp, ++rexp) { 431 for (i = 0; i < n; ++rinp, ++routp, ++rexp) {
429 unsigned long in, out, ex, all_bits, bit = 1, mask, j; 432 unsigned long in, out, ex, all_bits, bit = 1, mask, j;
430 unsigned long res_in = 0, res_out = 0, res_ex = 0; 433 unsigned long res_in = 0, res_out = 0, res_ex = 0;
434 const struct file_operations *f_op = NULL;
435 struct file *file = NULL;
431 436
432 in = *inp++; out = *outp++; ex = *exp++; 437 in = *inp++; out = *outp++; ex = *exp++;
433 all_bits = in | out | ex; 438 all_bits = in | out | ex;
434 if (all_bits == 0) { 439 if (all_bits == 0) {
435 i += BITS_PER_LONG; 440 i += __NFDBITS;
436 continue; 441 continue;
437 } 442 }
438 443
439 for (j = 0; j < BITS_PER_LONG; ++j, ++i, bit <<= 1) { 444 for (j = 0; j < __NFDBITS; ++j, ++i, bit <<= 1) {
440 struct fd f; 445 int fput_needed;
441 if (i >= n) 446 if (i >= n)
442 break; 447 break;
443 if (!(bit & all_bits)) 448 if (!(bit & all_bits))
444 continue; 449 continue;
445 f = fdget(i); 450 file = fget_light(i, &fput_needed);
446 if (f.file) { 451 if (file) {
447 const struct file_operations *f_op; 452 f_op = file->f_op;
448 f_op = f.file->f_op;
449 mask = DEFAULT_POLLMASK; 453 mask = DEFAULT_POLLMASK;
450 if (f_op && f_op->poll) { 454 if (f_op && f_op->poll) {
451 wait_key_set(wait, in, out, bit); 455 wait_key_set(wait, in, out, bit);
452 mask = (*f_op->poll)(f.file, wait); 456 mask = (*f_op->poll)(file, wait);
453 } 457 }
454 fdput(f); 458 fput_light(file, fput_needed);
455 if ((mask & POLLIN_SET) && (in & bit)) { 459 if ((mask & POLLIN_SET) && (in & bit)) {
456 res_in |= bit; 460 res_in |= bit;
457 retval++; 461 retval++;
458 wait->_qproc = NULL; 462 wait = NULL;
459 } 463 }
460 if ((mask & POLLOUT_SET) && (out & bit)) { 464 if ((mask & POLLOUT_SET) && (out & bit)) {
461 res_out |= bit; 465 res_out |= bit;
462 retval++; 466 retval++;
463 wait->_qproc = NULL; 467 wait = NULL;
464 } 468 }
465 if ((mask & POLLEX_SET) && (ex & bit)) { 469 if ((mask & POLLEX_SET) && (ex & bit)) {
466 res_ex |= bit; 470 res_ex |= bit;
467 retval++; 471 retval++;
468 wait->_qproc = NULL; 472 wait = NULL;
469 } 473 }
470 } 474 }
471 } 475 }
@@ -477,7 +481,7 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
477 *rexp = res_ex; 481 *rexp = res_ex;
478 cond_resched(); 482 cond_resched();
479 } 483 }
480 wait->_qproc = NULL; 484 wait = NULL;
481 if (retval || timed_out || signal_pending(current)) 485 if (retval || timed_out || signal_pending(current))
482 break; 486 break;
483 if (table.error) { 487 if (table.error) {
@@ -612,6 +616,7 @@ SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp,
612 return ret; 616 return ret;
613} 617}
614 618
619#ifdef HAVE_SET_RESTORE_SIGMASK
615static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp, 620static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp,
616 fd_set __user *exp, struct timespec __user *tsp, 621 fd_set __user *exp, struct timespec __user *tsp,
617 const sigset_t __user *sigmask, size_t sigsetsize) 622 const sigset_t __user *sigmask, size_t sigsetsize)
@@ -683,6 +688,7 @@ SYSCALL_DEFINE6(pselect6, int, n, fd_set __user *, inp, fd_set __user *, outp,
683 688
684 return do_pselect(n, inp, outp, exp, tsp, up, sigsetsize); 689 return do_pselect(n, inp, outp, exp, tsp, up, sigsetsize);
685} 690}
691#endif /* HAVE_SET_RESTORE_SIGMASK */
686 692
687#ifdef __ARCH_WANT_SYS_OLD_SELECT 693#ifdef __ARCH_WANT_SYS_OLD_SELECT
688struct sel_arg_struct { 694struct sel_arg_struct {
@@ -714,7 +720,7 @@ struct poll_list {
714 * interested in events matching the pollfd->events mask, and the result 720 * interested in events matching the pollfd->events mask, and the result
715 * matching that mask is both recorded in pollfd->revents and returned. The 721 * matching that mask is both recorded in pollfd->revents and returned. The
716 * pwait poll_table will be used by the fd-provided poll handler for waiting, 722 * pwait poll_table will be used by the fd-provided poll handler for waiting,
717 * if pwait->_qproc is non-NULL. 723 * if non-NULL.
718 */ 724 */
719static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait) 725static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait)
720{ 726{
@@ -724,17 +730,22 @@ static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait)
724 mask = 0; 730 mask = 0;
725 fd = pollfd->fd; 731 fd = pollfd->fd;
726 if (fd >= 0) { 732 if (fd >= 0) {
727 struct fd f = fdget(fd); 733 int fput_needed;
734 struct file * file;
735
736 file = fget_light(fd, &fput_needed);
728 mask = POLLNVAL; 737 mask = POLLNVAL;
729 if (f.file) { 738 if (file != NULL) {
730 mask = DEFAULT_POLLMASK; 739 mask = DEFAULT_POLLMASK;
731 if (f.file->f_op && f.file->f_op->poll) { 740 if (file->f_op && file->f_op->poll) {
732 pwait->_key = pollfd->events|POLLERR|POLLHUP; 741 if (pwait)
733 mask = f.file->f_op->poll(f.file, pwait); 742 pwait->key = pollfd->events |
743 POLLERR | POLLHUP;
744 mask = file->f_op->poll(file, pwait);
734 } 745 }
735 /* Mask out unneeded events. */ 746 /* Mask out unneeded events. */
736 mask &= pollfd->events | POLLERR | POLLHUP; 747 mask &= pollfd->events | POLLERR | POLLHUP;
737 fdput(f); 748 fput_light(file, fput_needed);
738 } 749 }
739 } 750 }
740 pollfd->revents = mask; 751 pollfd->revents = mask;
@@ -752,7 +763,7 @@ static int do_poll(unsigned int nfds, struct poll_list *list,
752 763
753 /* Optimise the no-wait case */ 764 /* Optimise the no-wait case */
754 if (end_time && !end_time->tv_sec && !end_time->tv_nsec) { 765 if (end_time && !end_time->tv_sec && !end_time->tv_nsec) {
755 pt->_qproc = NULL; 766 pt = NULL;
756 timed_out = 1; 767 timed_out = 1;
757 } 768 }
758 769
@@ -770,22 +781,22 @@ static int do_poll(unsigned int nfds, struct poll_list *list,
770 for (; pfd != pfd_end; pfd++) { 781 for (; pfd != pfd_end; pfd++) {
771 /* 782 /*
772 * Fish for events. If we found one, record it 783 * Fish for events. If we found one, record it
773 * and kill poll_table->_qproc, so we don't 784 * and kill the poll_table, so we don't
774 * needlessly register any other waiters after 785 * needlessly register any other waiters after
775 * this. They'll get immediately deregistered 786 * this. They'll get immediately deregistered
776 * when we break out and return. 787 * when we break out and return.
777 */ 788 */
778 if (do_pollfd(pfd, pt)) { 789 if (do_pollfd(pfd, pt)) {
779 count++; 790 count++;
780 pt->_qproc = NULL; 791 pt = NULL;
781 } 792 }
782 } 793 }
783 } 794 }
784 /* 795 /*
785 * All waiters have already been registered, so don't provide 796 * All waiters have already been registered, so don't provide
786 * a poll_table->_qproc to them on the next loop iteration. 797 * a poll_table to them on the next loop iteration.
787 */ 798 */
788 pt->_qproc = NULL; 799 pt = NULL;
789 if (!count) { 800 if (!count) {
790 count = wait->error; 801 count = wait->error;
791 if (signal_pending(current)) 802 if (signal_pending(current))
@@ -901,7 +912,7 @@ static long do_restart_poll(struct restart_block *restart_block)
901} 912}
902 913
903SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds, 914SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds,
904 int, timeout_msecs) 915 long, timeout_msecs)
905{ 916{
906 struct timespec end_time, *to = NULL; 917 struct timespec end_time, *to = NULL;
907 int ret; 918 int ret;
@@ -934,6 +945,7 @@ SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds,
934 return ret; 945 return ret;
935} 946}
936 947
948#ifdef HAVE_SET_RESTORE_SIGMASK
937SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds, 949SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
938 struct timespec __user *, tsp, const sigset_t __user *, sigmask, 950 struct timespec __user *, tsp, const sigset_t __user *, sigmask,
939 size_t, sigsetsize) 951 size_t, sigsetsize)
@@ -984,3 +996,4 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
984 996
985 return ret; 997 return ret;
986} 998}
999#endif /* HAVE_SET_RESTORE_SIGMASK */