mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-29 09:13:38 +00:00
do_pollfd(): convert to CLASS(fd)
lift setting ->revents into the caller, so that failure exits (including the early one) would be plain returns. We need the scope of our struct fd to end before the store to ->revents, since that's shared with the failure exits prior to the point where we can do fdget(). Reviewed-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
d000e073ca
commit
8935989798
27
fs/select.c
27
fs/select.c
@ -855,15 +855,14 @@ static inline __poll_t do_pollfd(struct pollfd *pollfd, poll_table *pwait,
|
|||||||
__poll_t busy_flag)
|
__poll_t busy_flag)
|
||||||
{
|
{
|
||||||
int fd = pollfd->fd;
|
int fd = pollfd->fd;
|
||||||
__poll_t mask = 0, filter;
|
__poll_t mask, filter;
|
||||||
struct fd f;
|
|
||||||
|
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
goto out;
|
return 0;
|
||||||
mask = EPOLLNVAL;
|
|
||||||
f = fdget(fd);
|
CLASS(fd, f)(fd);
|
||||||
if (!fd_file(f))
|
if (fd_empty(f))
|
||||||
goto out;
|
return EPOLLNVAL;
|
||||||
|
|
||||||
/* userland u16 ->events contains POLL... bitmap */
|
/* userland u16 ->events contains POLL... bitmap */
|
||||||
filter = demangle_poll(pollfd->events) | EPOLLERR | EPOLLHUP;
|
filter = demangle_poll(pollfd->events) | EPOLLERR | EPOLLHUP;
|
||||||
@ -871,13 +870,7 @@ static inline __poll_t do_pollfd(struct pollfd *pollfd, poll_table *pwait,
|
|||||||
mask = vfs_poll(fd_file(f), pwait);
|
mask = vfs_poll(fd_file(f), pwait);
|
||||||
if (mask & busy_flag)
|
if (mask & busy_flag)
|
||||||
*can_busy_poll = true;
|
*can_busy_poll = true;
|
||||||
mask &= filter; /* Mask out unneeded events. */
|
return mask & filter; /* Mask out unneeded events. */
|
||||||
fdput(f);
|
|
||||||
|
|
||||||
out:
|
|
||||||
/* ... and so does ->revents */
|
|
||||||
pollfd->revents = mangle_poll(mask);
|
|
||||||
return mask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_poll(struct poll_list *list, struct poll_wqueues *wait,
|
static int do_poll(struct poll_list *list, struct poll_wqueues *wait,
|
||||||
@ -909,6 +902,7 @@ static int do_poll(struct poll_list *list, struct poll_wqueues *wait,
|
|||||||
pfd = walk->entries;
|
pfd = walk->entries;
|
||||||
pfd_end = pfd + walk->len;
|
pfd_end = pfd + walk->len;
|
||||||
for (; pfd != pfd_end; pfd++) {
|
for (; pfd != pfd_end; pfd++) {
|
||||||
|
__poll_t mask;
|
||||||
/*
|
/*
|
||||||
* Fish for events. If we found one, record it
|
* Fish for events. If we found one, record it
|
||||||
* and kill poll_table->_qproc, so we don't
|
* and kill poll_table->_qproc, so we don't
|
||||||
@ -916,8 +910,9 @@ static int do_poll(struct poll_list *list, struct poll_wqueues *wait,
|
|||||||
* this. They'll get immediately deregistered
|
* this. They'll get immediately deregistered
|
||||||
* when we break out and return.
|
* when we break out and return.
|
||||||
*/
|
*/
|
||||||
if (do_pollfd(pfd, pt, &can_busy_loop,
|
mask = do_pollfd(pfd, pt, &can_busy_loop, busy_flag);
|
||||||
busy_flag)) {
|
pfd->revents = mangle_poll(mask);
|
||||||
|
if (mask) {
|
||||||
count++;
|
count++;
|
||||||
pt->_qproc = NULL;
|
pt->_qproc = NULL;
|
||||||
/* found something, stop busy polling */
|
/* found something, stop busy polling */
|
||||||
|
Loading…
Reference in New Issue
Block a user