summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2019-11-14 22:39:04 -0700
committerJens Axboe <axboe@kernel.dk>2019-11-25 19:48:31 -0700
commit978db57e2c329fc612ff669cab9bf0007efd3ca3 (patch)
treef94cf385de3279e086d24123ecf1a449de75d1bc /fs
parent0e0702dac26b282603261f04a62711a2d9aac17b (diff)
io_uring: make io_double_put_req() use normal completion path
If we don't use the normal completion path, we may skip killing links that should be errored and freed. Add __io_double_put_req() for use within the completion path itself, other calls should just use io_double_put_req(). Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs')
-rw-r--r--fs/io_uring.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c
index d877c7f6368e..1da103df2bfa 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -383,6 +383,7 @@ static void io_cqring_fill_event(struct io_kiocb *req, long res);
static void __io_free_req(struct io_kiocb *req);
static void io_put_req(struct io_kiocb *req);
static void io_double_put_req(struct io_kiocb *req);
+static void __io_double_put_req(struct io_kiocb *req);
static struct kmem_cache *req_cachep;
@@ -916,7 +917,7 @@ static void io_fail_links(struct io_kiocb *req)
io_link_cancel_timeout(link);
} else {
io_cqring_fill_event(link, -ECANCELED);
- io_double_put_req(link);
+ __io_double_put_req(link);
}
}
@@ -990,13 +991,24 @@ static void io_put_req(struct io_kiocb *req)
io_free_req(req);
}
-static void io_double_put_req(struct io_kiocb *req)
+/*
+ * Must only be used if we don't need to care about links, usually from
+ * within the completion handling itself.
+ */
+static void __io_double_put_req(struct io_kiocb *req)
{
/* drop both submit and complete references */
if (refcount_sub_and_test(2, &req->refs))
__io_free_req(req);
}
+static void io_double_put_req(struct io_kiocb *req)
+{
+ /* drop both submit and complete references */
+ if (refcount_sub_and_test(2, &req->refs))
+ io_free_req(req);
+}
+
static unsigned io_cqring_events(struct io_ring_ctx *ctx, bool noflush)
{
struct io_rings *rings = ctx->rings;