diff --git a/fs/aio.c b/fs/aio.c
index 8e624e3a7be981322a22481a88a2d4f133098d18..471dd6abc679a0b50268b68a9fdb7a4a7b3e4f08 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1713,6 +1713,7 @@ static ssize_t aio_poll(struct aio_kiocb *aiocb, struct iocb *iocb)
 	struct kioctx *ctx = aiocb->ki_ctx;
 	struct poll_iocb *req = &aiocb->poll;
 	struct aio_poll_table apt;
+	bool async = false;
 	__poll_t mask;
 
 	/* reject any unknown events outside the normal event mask. */
@@ -1754,18 +1755,19 @@ static ssize_t aio_poll(struct aio_kiocb *aiocb, struct iocb *iocb)
 
 	spin_lock_irq(&ctx->ctx_lock);
 	spin_lock(&req->head->lock);
-	if (req->woken) {
-		/* wake_up context handles the rest */
-		mask = 0;
+	if (req->woken) {  /* already taken up by aio_poll_wake() */
+		async = true;
 		apt.error = 0;
-	} else if (mask || apt.error) {
-		/* if we get an error or a mask we are done */
-		WARN_ON_ONCE(list_empty(&req->wait.entry));
-		list_del_init(&req->wait.entry);
-	} else {
-		/* actually waiting for an event */
+	} else if (!mask && !apt.error) { /* actually waiting for an event */
 		list_add_tail(&aiocb->ki_list, &ctx->active_reqs);
 		aiocb->ki_cancel = aio_poll_cancel;
+		async = true;
+	} else { /* if we get an error or a mask we are done */
+		WARN_ON_ONCE(list_empty(&req->wait.entry));
+		list_del_init(&req->wait.entry);
+		/* no wakeup in the future either;
+		 * aiocb is ours to dispose of
+		 */
 	}
 	spin_unlock(&req->head->lock);
 	spin_unlock_irq(&ctx->ctx_lock);
@@ -1775,13 +1777,12 @@ static ssize_t aio_poll(struct aio_kiocb *aiocb, struct iocb *iocb)
 	fput(req->file);
 	if (unlikely(apt.error)) {
 		fput(req->file);
-		return apt.error;
 	}
 
-	if (mask)
+	if (!async && !apt.error)
 		aio_poll_complete(aiocb, mask);
 	iocb_put(aiocb);
-	return 0;
+	return apt.error;
 }
 
 static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,