summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2025-10-17 08:45:54 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2025-10-17 08:45:54 -0700
commit6f3b6e91f7201e248d83232538db14d30100e9c7 (patch)
tree0816816c57ab778fa0a81d26efc29e64e6e6fcdc
parent0c8df15f758a69a7bf88ecf9b7f95dc7db2c463c (diff)
parent18d6b1743eafeb3fb1e0ea5a2b7fd0a773d525a8 (diff)
downloadlinux-6f3b6e91f7201e248d83232538db14d30100e9c7.tar.gz
linux-6f3b6e91f7201e248d83232538db14d30100e9c7.tar.bz2
linux-6f3b6e91f7201e248d83232538db14d30100e9c7.zip
Merge tag 'io_uring-6.18-20251016' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux
Pull io_uring fixes from Jens Axboe: - Revert of a change that went into an older kernel, and which has been reported to cause a regression for some write workloads on LVM while a snapshop is being created - Fix a regression from this merge window, where some compilers (and/or certain .config options) would cause an earlier evaluations of a dereference which would then cause a NULL pointer dereference. I was only able to reproduce this with OPTIMIZE_FOR_SIZE=y, but David Howells hit it with just KASAN enabled. Depending on how things inlined, this makes sense - Fix for a missing lock around a mem region unregistration - Fix for ring resizing with the same placement after resize * tag 'io_uring-6.18-20251016' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux: io_uring/rw: check for NULL io_br_sel when putting a buffer io_uring: fix unexpected placement on same size resizing io_uring: protect mem region deregistration Revert "io_uring/rw: drop -EOPNOTSUPP check in __io_complete_rw_common()"
-rw-r--r--io_uring/register.c8
-rw-r--r--io_uring/rw.c8
2 files changed, 7 insertions, 9 deletions
diff --git a/io_uring/register.c b/io_uring/register.c
index 43f04c47522c..2e4717f1357c 100644
--- a/io_uring/register.c
+++ b/io_uring/register.c
@@ -421,13 +421,6 @@ static int io_register_resize_rings(struct io_ring_ctx *ctx, void __user *arg)
if (unlikely(ret))
return ret;
- /* nothing to do, but copy params back */
- if (p.sq_entries == ctx->sq_entries && p.cq_entries == ctx->cq_entries) {
- if (copy_to_user(arg, &p, sizeof(p)))
- return -EFAULT;
- return 0;
- }
-
size = rings_size(p.flags, p.sq_entries, p.cq_entries,
&sq_array_offset);
if (size == SIZE_MAX)
@@ -613,6 +606,7 @@ static int io_register_mem_region(struct io_ring_ctx *ctx, void __user *uarg)
if (ret)
return ret;
if (copy_to_user(rd_uptr, &rd, sizeof(rd))) {
+ guard(mutex)(&ctx->mmap_lock);
io_free_region(ctx, &ctx->param_region);
return -EFAULT;
}
diff --git a/io_uring/rw.c b/io_uring/rw.c
index 08882648d569..5b2241a5813c 100644
--- a/io_uring/rw.c
+++ b/io_uring/rw.c
@@ -542,7 +542,7 @@ static void __io_complete_rw_common(struct io_kiocb *req, long res)
{
if (res == req->cqe.res)
return;
- if (res == -EAGAIN && io_rw_should_reissue(req)) {
+ if ((res == -EOPNOTSUPP || res == -EAGAIN) && io_rw_should_reissue(req)) {
req->flags |= REQ_F_REISSUE | REQ_F_BL_NO_RECYCLE;
} else {
req_set_fail(req);
@@ -655,13 +655,17 @@ static int kiocb_done(struct io_kiocb *req, ssize_t ret,
if (ret >= 0 && req->flags & REQ_F_CUR_POS)
req->file->f_pos = rw->kiocb.ki_pos;
if (ret >= 0 && !(req->ctx->flags & IORING_SETUP_IOPOLL)) {
+ u32 cflags = 0;
+
__io_complete_rw_common(req, ret);
/*
* Safe to call io_end from here as we're inline
* from the submission path.
*/
io_req_io_end(req);
- io_req_set_res(req, final_ret, io_put_kbuf(req, ret, sel->buf_list));
+ if (sel)
+ cflags = io_put_kbuf(req, ret, sel->buf_list);
+ io_req_set_res(req, final_ret, cflags);
io_req_rw_cleanup(req, issue_flags);
return IOU_COMPLETE;
} else {