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:
Al Viro 2024-06-07 16:03:33 -04:00
parent d000e073ca
commit 8935989798

View File

@ -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 */