diff options
author | Eric Biggers <ebiggers@google.com> | 2021-12-08 17:04:54 -0800 |
---|---|---|
committer | Eric Biggers <ebiggers@google.com> | 2021-12-09 10:49:56 -0800 |
commit | 363bee27e25804d8981dd1c025b4ad49dc39c530 (patch) | |
tree | 7dbb64b98bd9a7e88ab608d2cda29e7dc7e889e1 /fs/xfs/xfs_trace.c | |
parent | 9537bae0da1f8d1e2361ab6d0479e8af7824e160 (diff) |
aio: keep poll requests on waitqueue until completed
Currently, aio_poll_wake() will always remove the poll request from the
waitqueue. Then, if aio_poll_complete_work() sees that none of the
polled events are ready and the request isn't cancelled, it re-adds the
request to the waitqueue. (This can easily happen when polling a file
that doesn't pass an event mask when waking up its waitqueue.)
This is fundamentally broken for two reasons:
1. If a wakeup occurs between vfs_poll() and the request being
re-added to the waitqueue, it will be missed because the request
wasn't on the waitqueue at the time. Therefore, IOCB_CMD_POLL
might never complete even if the polled file is ready.
2. When the request isn't on the waitqueue, there is no way to be
notified that the waitqueue is being freed (which happens when its
lifetime is shorter than the struct file's). This is supposed to
happen via the waitqueue entries being woken up with POLLFREE.
Therefore, leave the requests on the waitqueue until they are actually
completed (or cancelled). To keep track of when aio_poll_complete_work
needs to be scheduled, use new fields in struct poll_iocb. Remove the
'done' field which is now redundant.
Note that this is consistent with how sys_poll() and eventpoll work;
their wakeup functions do *not* remove the waitqueue entries.
Fixes: 2c14fa838cbe ("aio: implement IOCB_CMD_POLL")
Cc: <stable@vger.kernel.org> # v4.18+
Link: https://lore.kernel.org/r/20211209010455.42744-5-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>
Diffstat (limited to 'fs/xfs/xfs_trace.c')
0 files changed, 0 insertions, 0 deletions