io_uring: provide generic io_req_complete() helper

We have lots of callers of:

io_cqring_add_event(req, result);
io_put_req(req);

Provide a helper that does this for us. It helps clean up the code, and
also provides a more convenient location for us to change the completion
handling.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Jens Axboe 2020-06-22 09:17:17 -06:00
parent d3cac64c49
commit e1e16097e2
1 changed files with 43 additions and 63 deletions

View File

@ -1335,7 +1335,7 @@ static void io_cqring_fill_event(struct io_kiocb *req, long res)
__io_cqring_fill_event(req, res, 0);
}
static void __io_cqring_add_event(struct io_kiocb *req, long res, long cflags)
static void io_cqring_add_event(struct io_kiocb *req, long res, long cflags)
{
struct io_ring_ctx *ctx = req->ctx;
unsigned long flags;
@ -1348,9 +1348,15 @@ static void __io_cqring_add_event(struct io_kiocb *req, long res, long cflags)
io_cqring_ev_posted(ctx);
}
static void io_cqring_add_event(struct io_kiocb *req, long res)
static void __io_req_complete(struct io_kiocb *req, long res, unsigned cflags)
{
__io_cqring_add_event(req, res, 0);
io_cqring_add_event(req, res, cflags);
io_put_req(req);
}
static void io_req_complete(struct io_kiocb *req, long res)
{
__io_req_complete(req, res, 0);
}
static inline bool io_is_fallback_req(struct io_kiocb *req)
@ -1978,7 +1984,7 @@ static void io_complete_rw_common(struct kiocb *kiocb, long res)
req_set_fail_links(req);
if (req->flags & REQ_F_BUFFER_SELECTED)
cflags = io_put_kbuf(req);
__io_cqring_add_event(req, res, cflags);
io_cqring_add_event(req, res, cflags);
}
static void io_sq_thread_drop_mm(struct io_ring_ctx *ctx)
@ -2048,9 +2054,8 @@ static bool io_resubmit_prep(struct io_kiocb *req, int error)
return true;
kfree(iovec);
end_req:
io_cqring_add_event(req, ret);
req_set_fail_links(req);
io_put_req(req);
io_req_complete(req, ret);
return false;
}
@ -3117,10 +3122,9 @@ static int io_tee(struct io_kiocb *req, bool force_nonblock)
io_put_file(req, in, (sp->flags & SPLICE_F_FD_IN_FIXED));
req->flags &= ~REQ_F_NEED_CLEANUP;
io_cqring_add_event(req, ret);
if (ret != sp->len)
req_set_fail_links(req);
io_put_req(req);
io_req_complete(req, ret);
return 0;
}
@ -3154,10 +3158,9 @@ static int io_splice(struct io_kiocb *req, bool force_nonblock)
io_put_file(req, in, (sp->flags & SPLICE_F_FD_IN_FIXED));
req->flags &= ~REQ_F_NEED_CLEANUP;
io_cqring_add_event(req, ret);
if (ret != sp->len)
req_set_fail_links(req);
io_put_req(req);
io_req_complete(req, ret);
return 0;
}
@ -3171,8 +3174,7 @@ static int io_nop(struct io_kiocb *req)
if (unlikely(ctx->flags & IORING_SETUP_IOPOLL))
return -EINVAL;
io_cqring_add_event(req, 0);
io_put_req(req);
io_req_complete(req, 0);
return 0;
}
@ -3211,8 +3213,7 @@ static int io_fsync(struct io_kiocb *req, bool force_nonblock)
req->sync.flags & IORING_FSYNC_DATASYNC);
if (ret < 0)
req_set_fail_links(req);
io_cqring_add_event(req, ret);
io_put_req(req);
io_req_complete(req, ret);
return 0;
}
@ -3245,8 +3246,7 @@ static int io_fallocate(struct io_kiocb *req, bool force_nonblock)
current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
if (ret < 0)
req_set_fail_links(req);
io_cqring_add_event(req, ret);
io_put_req(req);
io_req_complete(req, ret);
return 0;
}
@ -3342,8 +3342,7 @@ static int io_openat2(struct io_kiocb *req, bool force_nonblock)
req->flags &= ~REQ_F_NEED_CLEANUP;
if (ret < 0)
req_set_fail_links(req);
io_cqring_add_event(req, ret);
io_put_req(req);
io_req_complete(req, ret);
return 0;
}
@ -3416,8 +3415,7 @@ static int io_remove_buffers(struct io_kiocb *req, bool force_nonblock)
io_ring_submit_lock(ctx, !force_nonblock);
if (ret < 0)
req_set_fail_links(req);
io_cqring_add_event(req, ret);
io_put_req(req);
io_req_complete(req, ret);
return 0;
}
@ -3504,8 +3502,7 @@ static int io_provide_buffers(struct io_kiocb *req, bool force_nonblock)
io_ring_submit_unlock(ctx, !force_nonblock);
if (ret < 0)
req_set_fail_links(req);
io_cqring_add_event(req, ret);
io_put_req(req);
io_req_complete(req, ret);
return 0;
}
@ -3548,8 +3545,7 @@ static int io_epoll_ctl(struct io_kiocb *req, bool force_nonblock)
if (ret < 0)
req_set_fail_links(req);
io_cqring_add_event(req, ret);
io_put_req(req);
io_req_complete(req, ret);
return 0;
#else
return -EOPNOTSUPP;
@ -3585,8 +3581,7 @@ static int io_madvise(struct io_kiocb *req, bool force_nonblock)
ret = do_madvise(ma->addr, ma->len, ma->advice);
if (ret < 0)
req_set_fail_links(req);
io_cqring_add_event(req, ret);
io_put_req(req);
io_req_complete(req, ret);
return 0;
#else
return -EOPNOTSUPP;
@ -3625,8 +3620,7 @@ static int io_fadvise(struct io_kiocb *req, bool force_nonblock)
ret = vfs_fadvise(req->file, fa->offset, fa->len, fa->advice);
if (ret < 0)
req_set_fail_links(req);
io_cqring_add_event(req, ret);
io_put_req(req);
io_req_complete(req, ret);
return 0;
}
@ -3665,8 +3659,7 @@ static int io_statx(struct io_kiocb *req, bool force_nonblock)
if (ret < 0)
req_set_fail_links(req);
io_cqring_add_event(req, ret);
io_put_req(req);
io_req_complete(req, ret);
return 0;
}
@ -3722,10 +3715,9 @@ static int io_close(struct io_kiocb *req, bool force_nonblock)
ret = filp_close(close->put_file, req->work.files);
if (ret < 0)
req_set_fail_links(req);
io_cqring_add_event(req, ret);
fput(close->put_file);
close->put_file = NULL;
io_put_req(req);
io_req_complete(req, ret);
return 0;
}
@ -3759,8 +3751,7 @@ static int io_sync_file_range(struct io_kiocb *req, bool force_nonblock)
req->sync.flags);
if (ret < 0)
req_set_fail_links(req);
io_cqring_add_event(req, ret);
io_put_req(req);
io_req_complete(req, ret);
return 0;
}
@ -3859,10 +3850,9 @@ static int io_sendmsg(struct io_kiocb *req, bool force_nonblock)
if (kmsg && kmsg->iov != kmsg->fast_iov)
kfree(kmsg->iov);
req->flags &= ~REQ_F_NEED_CLEANUP;
io_cqring_add_event(req, ret);
if (ret < 0)
req_set_fail_links(req);
io_put_req(req);
io_req_complete(req, ret);
return 0;
}
@ -3902,10 +3892,9 @@ static int io_send(struct io_kiocb *req, bool force_nonblock)
ret = -EINTR;
}
io_cqring_add_event(req, ret);
if (ret < 0)
req_set_fail_links(req);
io_put_req(req);
io_req_complete(req, ret);
return 0;
}
@ -4102,10 +4091,9 @@ static int io_recvmsg(struct io_kiocb *req, bool force_nonblock)
if (kmsg && kmsg->iov != kmsg->fast_iov)
kfree(kmsg->iov);
req->flags &= ~REQ_F_NEED_CLEANUP;
__io_cqring_add_event(req, ret, cflags);
if (ret < 0)
req_set_fail_links(req);
io_put_req(req);
__io_req_complete(req, ret, cflags);
return 0;
}
@ -4159,10 +4147,9 @@ static int io_recv(struct io_kiocb *req, bool force_nonblock)
kfree(kbuf);
req->flags &= ~REQ_F_NEED_CLEANUP;
__io_cqring_add_event(req, ret, cflags);
if (ret < 0)
req_set_fail_links(req);
io_put_req(req);
__io_req_complete(req, ret, cflags);
return 0;
}
@ -4201,8 +4188,7 @@ static int io_accept(struct io_kiocb *req, bool force_nonblock)
ret = -EINTR;
req_set_fail_links(req);
}
io_cqring_add_event(req, ret);
io_put_req(req);
io_req_complete(req, ret);
return 0;
}
@ -4262,8 +4248,7 @@ static int io_connect(struct io_kiocb *req, bool force_nonblock)
out:
if (ret < 0)
req_set_fail_links(req);
io_cqring_add_event(req, ret);
io_put_req(req);
io_req_complete(req, ret);
return 0;
}
#else /* !CONFIG_NET */
@ -4555,7 +4540,7 @@ static void io_async_task_func(struct callback_head *cb)
if (!canceled) {
__set_current_state(TASK_RUNNING);
if (io_sq_thread_acquire_mm(ctx, req)) {
io_cqring_add_event(req, -EFAULT);
io_cqring_add_event(req, -EFAULT, 0);
goto end_req;
}
mutex_lock(&ctx->uring_lock);
@ -4804,10 +4789,9 @@ static int io_poll_remove(struct io_kiocb *req)
ret = io_poll_cancel(ctx, addr);
spin_unlock_irq(&ctx->completion_lock);
io_cqring_add_event(req, ret);
if (ret < 0)
req_set_fail_links(req);
io_put_req(req);
io_req_complete(req, ret);
return 0;
}
@ -5163,8 +5147,7 @@ static int io_files_update(struct io_kiocb *req, bool force_nonblock)
if (ret < 0)
req_set_fail_links(req);
io_cqring_add_event(req, ret);
io_put_req(req);
io_req_complete(req, ret);
return 0;
}
@ -5657,8 +5640,7 @@ static void io_wq_submit_work(struct io_wq_work **workptr)
if (ret) {
req_set_fail_links(req);
io_cqring_add_event(req, ret);
io_put_req(req);
io_req_complete(req, ret);
}
io_steal_work(req, workptr);
@ -5775,8 +5757,7 @@ static enum hrtimer_restart io_link_timeout_fn(struct hrtimer *timer)
io_async_find_and_cancel(ctx, req, prev->user_data, -ETIME);
io_put_req(prev);
} else {
io_cqring_add_event(req, -ETIME);
io_put_req(req);
io_req_complete(req, -ETIME);
}
return HRTIMER_NORESTART;
}
@ -5885,9 +5866,8 @@ static void __io_queue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe)
/* and drop final reference, if we failed */
if (ret) {
io_cqring_add_event(req, ret);
req_set_fail_links(req);
io_put_req(req);
io_req_complete(req, ret);
}
if (nxt) {
req = nxt;
@ -5909,9 +5889,9 @@ static void io_queue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe)
if (ret) {
if (ret != -EIOCBQUEUED) {
fail_req:
io_cqring_add_event(req, ret);
req_set_fail_links(req);
io_double_put_req(req);
io_put_req(req);
io_req_complete(req, ret);
}
} else if (req->flags & REQ_F_FORCE_ASYNC) {
if (!req->io) {
@ -5937,8 +5917,8 @@ static void io_queue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe)
static inline void io_queue_link_head(struct io_kiocb *req)
{
if (unlikely(req->flags & REQ_F_FAIL_LINK)) {
io_cqring_add_event(req, -ECANCELED);
io_double_put_req(req);
io_put_req(req);
io_req_complete(req, -ECANCELED);
} else
io_queue_sqe(req, NULL);
}
@ -6195,8 +6175,8 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr,
if (unlikely(err)) {
fail_req:
io_cqring_add_event(req, err);
io_double_put_req(req);
io_put_req(req);
io_req_complete(req, err);
break;
}