diff options
Diffstat (limited to 'fs/select.c')
-rw-r--r-- | fs/select.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/fs/select.c b/fs/select.c index 6de493bb42a4..ec14171dd78a 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -212,7 +212,7 @@ static int pollwake(wait_queue_entry_t *wait, unsigned mode, int sync, void *key | |||
212 | struct poll_table_entry *entry; | 212 | struct poll_table_entry *entry; |
213 | 213 | ||
214 | entry = container_of(wait, struct poll_table_entry, wait); | 214 | entry = container_of(wait, struct poll_table_entry, wait); |
215 | if (key && !((unsigned long)key & entry->key)) | 215 | if (key && !(key_to_poll(key) & entry->key)) |
216 | return 0; | 216 | return 0; |
217 | return __pollwake(wait, mode, sync, key); | 217 | return __pollwake(wait, mode, sync, key); |
218 | } | 218 | } |
@@ -438,7 +438,7 @@ get_max: | |||
438 | 438 | ||
439 | static inline void wait_key_set(poll_table *wait, unsigned long in, | 439 | static inline void wait_key_set(poll_table *wait, unsigned long in, |
440 | unsigned long out, unsigned long bit, | 440 | unsigned long out, unsigned long bit, |
441 | unsigned int ll_flag) | 441 | __poll_t ll_flag) |
442 | { | 442 | { |
443 | wait->_key = POLLEX_SET | ll_flag; | 443 | wait->_key = POLLEX_SET | ll_flag; |
444 | if (in & bit) | 444 | if (in & bit) |
@@ -454,7 +454,7 @@ static int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time) | |||
454 | poll_table *wait; | 454 | poll_table *wait; |
455 | int retval, i, timed_out = 0; | 455 | int retval, i, timed_out = 0; |
456 | u64 slack = 0; | 456 | u64 slack = 0; |
457 | unsigned int busy_flag = net_busy_loop_on() ? POLL_BUSY_LOOP : 0; | 457 | __poll_t busy_flag = net_busy_loop_on() ? POLL_BUSY_LOOP : 0; |
458 | unsigned long busy_start = 0; | 458 | unsigned long busy_start = 0; |
459 | 459 | ||
460 | rcu_read_lock(); | 460 | rcu_read_lock(); |
@@ -484,8 +484,9 @@ static int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time) | |||
484 | rinp = fds->res_in; routp = fds->res_out; rexp = fds->res_ex; | 484 | rinp = fds->res_in; routp = fds->res_out; rexp = fds->res_ex; |
485 | 485 | ||
486 | for (i = 0; i < n; ++rinp, ++routp, ++rexp) { | 486 | for (i = 0; i < n; ++rinp, ++routp, ++rexp) { |
487 | unsigned long in, out, ex, all_bits, bit = 1, mask, j; | 487 | unsigned long in, out, ex, all_bits, bit = 1, j; |
488 | unsigned long res_in = 0, res_out = 0, res_ex = 0; | 488 | unsigned long res_in = 0, res_out = 0, res_ex = 0; |
489 | __poll_t mask; | ||
489 | 490 | ||
490 | in = *inp++; out = *outp++; ex = *exp++; | 491 | in = *inp++; out = *outp++; ex = *exp++; |
491 | all_bits = in | out | ex; | 492 | all_bits = in | out | ex; |
@@ -802,11 +803,11 @@ struct poll_list { | |||
802 | * pwait poll_table will be used by the fd-provided poll handler for waiting, | 803 | * pwait poll_table will be used by the fd-provided poll handler for waiting, |
803 | * if pwait->_qproc is non-NULL. | 804 | * if pwait->_qproc is non-NULL. |
804 | */ | 805 | */ |
805 | static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait, | 806 | static inline __poll_t do_pollfd(struct pollfd *pollfd, poll_table *pwait, |
806 | bool *can_busy_poll, | 807 | bool *can_busy_poll, |
807 | unsigned int busy_flag) | 808 | __poll_t busy_flag) |
808 | { | 809 | { |
809 | unsigned int mask; | 810 | __poll_t mask; |
810 | int fd; | 811 | int fd; |
811 | 812 | ||
812 | mask = 0; | 813 | mask = 0; |
@@ -815,20 +816,24 @@ static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait, | |||
815 | struct fd f = fdget(fd); | 816 | struct fd f = fdget(fd); |
816 | mask = POLLNVAL; | 817 | mask = POLLNVAL; |
817 | if (f.file) { | 818 | if (f.file) { |
819 | /* userland u16 ->events contains POLL... bitmap */ | ||
820 | __poll_t filter = demangle_poll(pollfd->events) | | ||
821 | POLLERR | POLLHUP; | ||
818 | mask = DEFAULT_POLLMASK; | 822 | mask = DEFAULT_POLLMASK; |
819 | if (f.file->f_op->poll) { | 823 | if (f.file->f_op->poll) { |
820 | pwait->_key = pollfd->events|POLLERR|POLLHUP; | 824 | pwait->_key = filter; |
821 | pwait->_key |= busy_flag; | 825 | pwait->_key |= busy_flag; |
822 | mask = f.file->f_op->poll(f.file, pwait); | 826 | mask = f.file->f_op->poll(f.file, pwait); |
823 | if (mask & busy_flag) | 827 | if (mask & busy_flag) |
824 | *can_busy_poll = true; | 828 | *can_busy_poll = true; |
825 | } | 829 | } |
826 | /* Mask out unneeded events. */ | 830 | /* Mask out unneeded events. */ |
827 | mask &= pollfd->events | POLLERR | POLLHUP; | 831 | mask &= filter; |
828 | fdput(f); | 832 | fdput(f); |
829 | } | 833 | } |
830 | } | 834 | } |
831 | pollfd->revents = mask; | 835 | /* ... and so does ->revents */ |
836 | pollfd->revents = mangle_poll(mask); | ||
832 | 837 | ||
833 | return mask; | 838 | return mask; |
834 | } | 839 | } |
@@ -840,7 +845,7 @@ static int do_poll(struct poll_list *list, struct poll_wqueues *wait, | |||
840 | ktime_t expire, *to = NULL; | 845 | ktime_t expire, *to = NULL; |
841 | int timed_out = 0, count = 0; | 846 | int timed_out = 0, count = 0; |
842 | u64 slack = 0; | 847 | u64 slack = 0; |
843 | unsigned int busy_flag = net_busy_loop_on() ? POLL_BUSY_LOOP : 0; | 848 | __poll_t busy_flag = net_busy_loop_on() ? POLL_BUSY_LOOP : 0; |
844 | unsigned long busy_start = 0; | 849 | unsigned long busy_start = 0; |
845 | 850 | ||
846 | /* Optimise the no-wait case */ | 851 | /* Optimise the no-wait case */ |