diff options
author | Christoph Hellwig <hch@lst.de> | 2018-03-05 10:26:05 -0500 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2018-05-26 03:16:44 -0400 |
commit | 9965ed174e7d38896e5d2582159d8ef31ecd4cb5 (patch) | |
tree | 955bfa805fff87c169a4814deaf311b90cca84b2 | |
parent | 6e8b704df58407aad7607053cb1b5ead4ac4a0bc (diff) |
fs: add new vfs_poll and file_can_poll helpers
These abstract out calls to the poll method in preparation for changes
in how we poll.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
-rw-r--r-- | drivers/staging/comedi/drivers/serial2002.c | 4 | ||||
-rw-r--r-- | drivers/vfio/virqfd.c | 2 | ||||
-rw-r--r-- | drivers/vhost/vhost.c | 2 | ||||
-rw-r--r-- | fs/eventpoll.c | 5 | ||||
-rw-r--r-- | fs/select.c | 23 | ||||
-rw-r--r-- | include/linux/poll.h | 12 | ||||
-rw-r--r-- | mm/memcontrol.c | 2 | ||||
-rw-r--r-- | net/9p/trans_fd.c | 18 | ||||
-rw-r--r-- | virt/kvm/eventfd.c | 2 |
9 files changed, 32 insertions, 38 deletions
diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index b3f3b4a201af..5471b2212a62 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c | |||
@@ -113,7 +113,7 @@ static void serial2002_tty_read_poll_wait(struct file *f, int timeout) | |||
113 | long elapsed; | 113 | long elapsed; |
114 | __poll_t mask; | 114 | __poll_t mask; |
115 | 115 | ||
116 | mask = f->f_op->poll(f, &table.pt); | 116 | mask = vfs_poll(f, &table.pt); |
117 | if (mask & (EPOLLRDNORM | EPOLLRDBAND | EPOLLIN | | 117 | if (mask & (EPOLLRDNORM | EPOLLRDBAND | EPOLLIN | |
118 | EPOLLHUP | EPOLLERR)) { | 118 | EPOLLHUP | EPOLLERR)) { |
119 | break; | 119 | break; |
@@ -136,7 +136,7 @@ static int serial2002_tty_read(struct file *f, int timeout) | |||
136 | 136 | ||
137 | result = -1; | 137 | result = -1; |
138 | if (!IS_ERR(f)) { | 138 | if (!IS_ERR(f)) { |
139 | if (f->f_op->poll) { | 139 | if (file_can_poll(f)) { |
140 | serial2002_tty_read_poll_wait(f, timeout); | 140 | serial2002_tty_read_poll_wait(f, timeout); |
141 | 141 | ||
142 | if (kernel_read(f, &ch, 1, &pos) == 1) | 142 | if (kernel_read(f, &ch, 1, &pos) == 1) |
diff --git a/drivers/vfio/virqfd.c b/drivers/vfio/virqfd.c index 085700f1be10..2a1be859ee71 100644 --- a/drivers/vfio/virqfd.c +++ b/drivers/vfio/virqfd.c | |||
@@ -166,7 +166,7 @@ int vfio_virqfd_enable(void *opaque, | |||
166 | init_waitqueue_func_entry(&virqfd->wait, virqfd_wakeup); | 166 | init_waitqueue_func_entry(&virqfd->wait, virqfd_wakeup); |
167 | init_poll_funcptr(&virqfd->pt, virqfd_ptable_queue_proc); | 167 | init_poll_funcptr(&virqfd->pt, virqfd_ptable_queue_proc); |
168 | 168 | ||
169 | events = irqfd.file->f_op->poll(irqfd.file, &virqfd->pt); | 169 | events = vfs_poll(irqfd.file, &virqfd->pt); |
170 | 170 | ||
171 | /* | 171 | /* |
172 | * Check if there was an event already pending on the eventfd | 172 | * Check if there was an event already pending on the eventfd |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index f3bd8e941224..f6022881f147 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -208,7 +208,7 @@ int vhost_poll_start(struct vhost_poll *poll, struct file *file) | |||
208 | if (poll->wqh) | 208 | if (poll->wqh) |
209 | return 0; | 209 | return 0; |
210 | 210 | ||
211 | mask = file->f_op->poll(file, &poll->table); | 211 | mask = vfs_poll(file, &poll->table); |
212 | if (mask) | 212 | if (mask) |
213 | vhost_poll_wakeup(&poll->wait, 0, 0, poll_to_key(mask)); | 213 | vhost_poll_wakeup(&poll->wait, 0, 0, poll_to_key(mask)); |
214 | if (mask & EPOLLERR) { | 214 | if (mask & EPOLLERR) { |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 602ca4285b2e..67db22fe99c5 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -884,8 +884,7 @@ static __poll_t ep_item_poll(const struct epitem *epi, poll_table *pt, | |||
884 | 884 | ||
885 | pt->_key = epi->event.events; | 885 | pt->_key = epi->event.events; |
886 | if (!is_file_epoll(epi->ffd.file)) | 886 | if (!is_file_epoll(epi->ffd.file)) |
887 | return epi->ffd.file->f_op->poll(epi->ffd.file, pt) & | 887 | return vfs_poll(epi->ffd.file, pt) & epi->event.events; |
888 | epi->event.events; | ||
889 | 888 | ||
890 | ep = epi->ffd.file->private_data; | 889 | ep = epi->ffd.file->private_data; |
891 | poll_wait(epi->ffd.file, &ep->poll_wait, pt); | 890 | poll_wait(epi->ffd.file, &ep->poll_wait, pt); |
@@ -2025,7 +2024,7 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, | |||
2025 | 2024 | ||
2026 | /* The target file descriptor must support poll */ | 2025 | /* The target file descriptor must support poll */ |
2027 | error = -EPERM; | 2026 | error = -EPERM; |
2028 | if (!tf.file->f_op->poll) | 2027 | if (!file_can_poll(tf.file)) |
2029 | goto error_tgt_fput; | 2028 | goto error_tgt_fput; |
2030 | 2029 | ||
2031 | /* Check if EPOLLWAKEUP is allowed */ | 2030 | /* Check if EPOLLWAKEUP is allowed */ |
diff --git a/fs/select.c b/fs/select.c index 25da26253485..e30def680b2e 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -502,14 +502,10 @@ static int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time) | |||
502 | continue; | 502 | continue; |
503 | f = fdget(i); | 503 | f = fdget(i); |
504 | if (f.file) { | 504 | if (f.file) { |
505 | const struct file_operations *f_op; | 505 | wait_key_set(wait, in, out, bit, |
506 | f_op = f.file->f_op; | 506 | busy_flag); |
507 | mask = DEFAULT_POLLMASK; | 507 | mask = vfs_poll(f.file, wait); |
508 | if (f_op->poll) { | 508 | |
509 | wait_key_set(wait, in, out, | ||
510 | bit, busy_flag); | ||
511 | mask = (*f_op->poll)(f.file, wait); | ||
512 | } | ||
513 | fdput(f); | 509 | fdput(f); |
514 | if ((mask & POLLIN_SET) && (in & bit)) { | 510 | if ((mask & POLLIN_SET) && (in & bit)) { |
515 | res_in |= bit; | 511 | res_in |= bit; |
@@ -825,13 +821,10 @@ static inline __poll_t do_pollfd(struct pollfd *pollfd, poll_table *pwait, | |||
825 | 821 | ||
826 | /* userland u16 ->events contains POLL... bitmap */ | 822 | /* userland u16 ->events contains POLL... bitmap */ |
827 | filter = demangle_poll(pollfd->events) | EPOLLERR | EPOLLHUP; | 823 | filter = demangle_poll(pollfd->events) | EPOLLERR | EPOLLHUP; |
828 | mask = DEFAULT_POLLMASK; | 824 | pwait->_key = filter | busy_flag; |
829 | if (f.file->f_op->poll) { | 825 | mask = vfs_poll(f.file, pwait); |
830 | pwait->_key = filter | busy_flag; | 826 | if (mask & busy_flag) |
831 | mask = f.file->f_op->poll(f.file, pwait); | 827 | *can_busy_poll = true; |
832 | if (mask & busy_flag) | ||
833 | *can_busy_poll = true; | ||
834 | } | ||
835 | mask &= filter; /* Mask out unneeded events. */ | 828 | mask &= filter; /* Mask out unneeded events. */ |
836 | fdput(f); | 829 | fdput(f); |
837 | 830 | ||
diff --git a/include/linux/poll.h b/include/linux/poll.h index a3576da63377..7e0fdcf905d2 100644 --- a/include/linux/poll.h +++ b/include/linux/poll.h | |||
@@ -74,6 +74,18 @@ static inline void init_poll_funcptr(poll_table *pt, poll_queue_proc qproc) | |||
74 | pt->_key = ~(__poll_t)0; /* all events enabled */ | 74 | pt->_key = ~(__poll_t)0; /* all events enabled */ |
75 | } | 75 | } |
76 | 76 | ||
77 | static inline bool file_can_poll(struct file *file) | ||
78 | { | ||
79 | return file->f_op->poll; | ||
80 | } | ||
81 | |||
82 | static inline __poll_t vfs_poll(struct file *file, struct poll_table_struct *pt) | ||
83 | { | ||
84 | if (unlikely(!file->f_op->poll)) | ||
85 | return DEFAULT_POLLMASK; | ||
86 | return file->f_op->poll(file, pt); | ||
87 | } | ||
88 | |||
77 | struct poll_table_entry { | 89 | struct poll_table_entry { |
78 | struct file *filp; | 90 | struct file *filp; |
79 | __poll_t key; | 91 | __poll_t key; |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 2bd3df3d101a..1695f38630f1 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -3849,7 +3849,7 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of, | |||
3849 | if (ret) | 3849 | if (ret) |
3850 | goto out_put_css; | 3850 | goto out_put_css; |
3851 | 3851 | ||
3852 | efile.file->f_op->poll(efile.file, &event->pt); | 3852 | vfs_poll(efile.file, &event->pt); |
3853 | 3853 | ||
3854 | spin_lock(&memcg->event_list_lock); | 3854 | spin_lock(&memcg->event_list_lock); |
3855 | list_add(&event->list, &memcg->event_list); | 3855 | list_add(&event->list, &memcg->event_list); |
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 0cfba919d167..3811775692d0 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c | |||
@@ -231,7 +231,7 @@ static void p9_conn_cancel(struct p9_conn *m, int err) | |||
231 | static __poll_t | 231 | static __poll_t |
232 | p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt, int *err) | 232 | p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt, int *err) |
233 | { | 233 | { |
234 | __poll_t ret, n; | 234 | __poll_t ret; |
235 | struct p9_trans_fd *ts = NULL; | 235 | struct p9_trans_fd *ts = NULL; |
236 | 236 | ||
237 | if (client && client->status == Connected) | 237 | if (client && client->status == Connected) |
@@ -243,19 +243,9 @@ p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt, int *err) | |||
243 | return EPOLLERR; | 243 | return EPOLLERR; |
244 | } | 244 | } |
245 | 245 | ||
246 | if (!ts->rd->f_op->poll) | 246 | ret = vfs_poll(ts->rd, pt); |
247 | ret = DEFAULT_POLLMASK; | 247 | if (ts->rd != ts->wr) |
248 | else | 248 | ret = (ret & ~EPOLLOUT) | (vfs_poll(ts->wr, pt) & ~EPOLLIN); |
249 | ret = ts->rd->f_op->poll(ts->rd, pt); | ||
250 | |||
251 | if (ts->rd != ts->wr) { | ||
252 | if (!ts->wr->f_op->poll) | ||
253 | n = DEFAULT_POLLMASK; | ||
254 | else | ||
255 | n = ts->wr->f_op->poll(ts->wr, pt); | ||
256 | ret = (ret & ~EPOLLOUT) | (n & ~EPOLLIN); | ||
257 | } | ||
258 | |||
259 | return ret; | 249 | return ret; |
260 | } | 250 | } |
261 | 251 | ||
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index 6e865e8b5b10..90d30fbe95ae 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c | |||
@@ -397,7 +397,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args) | |||
397 | * Check if there was an event already pending on the eventfd | 397 | * Check if there was an event already pending on the eventfd |
398 | * before we registered, and trigger it as if we didn't miss it. | 398 | * before we registered, and trigger it as if we didn't miss it. |
399 | */ | 399 | */ |
400 | events = f.file->f_op->poll(f.file, &irqfd->pt); | 400 | events = vfs_poll(f.file, &irqfd->pt); |
401 | 401 | ||
402 | if (events & EPOLLIN) | 402 | if (events & EPOLLIN) |
403 | schedule_work(&irqfd->inject); | 403 | schedule_work(&irqfd->inject); |