return 0;
}
-static int io_poll_add(struct io_kiocb *req, unsigned int issue_flags)
+static int __io_poll_add(struct io_kiocb *req, unsigned int issue_flags)
{
struct io_poll_iocb *poll = &req->poll;
struct io_poll_table ipt;
if (!ret && ipt.error)
req_set_fail(req);
ret = ret ?: ipt.error;
- if (ret)
+ if (ret > 0) {
__io_req_complete(req, issue_flags, ret, 0);
+ return ret;
+ }
return 0;
}
+static int io_poll_add(struct io_kiocb *req, unsigned int issue_flags)
+{
+ int ret;
+
+ ret = __io_poll_add(req, issue_flags);
+ return ret < 0 ? ret : 0;
+}
+
static int io_poll_update(struct io_kiocb *req, unsigned int issue_flags)
{
struct io_ring_ctx *ctx = req->ctx;
ret = preq ? -EALREADY : -ENOENT;
goto out;
}
+ preq->result = -ECANCELED;
spin_unlock(&ctx->completion_lock);
if (req->poll_update.update_events || req->poll_update.update_user_data) {
if (req->poll_update.update_user_data)
preq->user_data = req->poll_update.new_user_data;
- ret2 = io_poll_add(preq, issue_flags);
+ ret2 = __io_poll_add(preq, issue_flags);
/* successfully updated, don't complete poll request */
if (!ret2)
goto out;
+ preq->result = ret2;
+
}
- req_set_fail(preq);
- io_req_complete(preq, -ECANCELED);
+ if (preq->result < 0)
+ req_set_fail(preq);
+ io_req_complete(preq, preq->result);
out:
- if (ret < 0)
- req_set_fail(req);
/* complete update request, we're done with it */
io_req_complete(req, ret);
io_ring_submit_unlock(ctx, !(issue_flags & IO_URING_F_NONBLOCK));