From 584284cae2ed06132603e823cef1e94a1c0f1181 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 15 Apr 2021 17:33:33 +0800 Subject: [PATCH] io_uring: make io_double_put_req() use normal completion path mainline inclusion from mainline-5.5-rc1 commit 978db57e2c329fc612ff669cab9bf0007efd3ca3 category: feature bugzilla: https://bugzilla.openeuler.org/show_bug.cgi?id=27 CVE: NA --------------------------- 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 Signed-off-by: Zhihao Cheng Signed-off-by: yangerkun Reviewed-by: zhangyi (F) Signed-off-by: Cheng Jian --- fs/io_uring.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 9b10335b68fc..700ae01d986f 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; @@ -915,7 +916,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); } } @@ -989,13 +990,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; -- GitLab