aboutsummaryrefslogtreecommitdiffstats
diff options
-rw-r--r--queue-6.15/io_uring-gate-req_f_isreg-on-s_anon_inode-as-well.patch51
-rw-r--r--queue-6.15/series1
2 files changed, 52 insertions, 0 deletions
diff --git a/queue-6.15/io_uring-gate-req_f_isreg-on-s_anon_inode-as-well.patch b/queue-6.15/io_uring-gate-req_f_isreg-on-s_anon_inode-as-well.patch
new file mode 100644
index 0000000000..d1d739952a
--- /dev/null
+++ b/queue-6.15/io_uring-gate-req_f_isreg-on-s_anon_inode-as-well.patch
@@ -0,0 +1,51 @@
+From 6f11adcc6f36ffd8f33dbdf5f5ce073368975bc3 Mon Sep 17 00:00:00 2001
+From: Jens Axboe <axboe@kernel.dk>
+Date: Sun, 29 Jun 2025 16:48:28 -0600
+Subject: io_uring: gate REQ_F_ISREG on !S_ANON_INODE as well
+
+From: Jens Axboe <axboe@kernel.dk>
+
+commit 6f11adcc6f36ffd8f33dbdf5f5ce073368975bc3 upstream.
+
+io_uring marks a request as dealing with a regular file on S_ISREG. This
+drives things like retries on short reads or writes, which is generally
+not expected on a regular file (or bdev). Applications tend to not
+expect that, so io_uring tries hard to ensure it doesn't deliver short
+IO on regular files.
+
+However, a recent commit added S_IFREG to anonymous inodes. When
+io_uring is used to read from various things that are backed by anon
+inodes, like eventfd, timerfd, etc, then it'll now all of a sudden wait
+for more data when rather than deliver what was read or written in a
+single operation. This breaks applications that issue reads on anon
+inodes, if they ask for more data than a single read delivers.
+
+Add a check for !S_ANON_INODE as well before setting REQ_F_ISREG to
+prevent that.
+
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://github.com/ghostty-org/ghostty/discussions/7720
+Fixes: cfd86ef7e8e7 ("anon_inode: use a proper mode internally")
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ io_uring/io_uring.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -1647,11 +1647,12 @@ static void io_iopoll_req_issued(struct
+
+ io_req_flags_t io_file_get_flags(struct file *file)
+ {
++ struct inode *inode = file_inode(file);
+ io_req_flags_t res = 0;
+
+ BUILD_BUG_ON(REQ_F_ISREG_BIT != REQ_F_SUPPORT_NOWAIT_BIT + 1);
+
+- if (S_ISREG(file_inode(file)->i_mode))
++ if (S_ISREG(inode->i_mode) && !(inode->i_flags & S_ANON_INODE))
+ res |= REQ_F_ISREG;
+ if ((file->f_flags & O_NONBLOCK) || (file->f_mode & FMODE_NOWAIT))
+ res |= REQ_F_SUPPORT_NOWAIT;
diff --git a/queue-6.15/series b/queue-6.15/series
index 143a2a6819..c015354971 100644
--- a/queue-6.15/series
+++ b/queue-6.15/series
@@ -260,3 +260,4 @@ x86-fpu-refactor-xfeature-bitmask-update-code-for-sigframe-xsave.patch
x86-pkeys-simplify-pkru-update-in-signal-frame.patch
s390-ptrace-fix-pointer-dereferencing-in-regs_get_kernel_stack_nth.patch
io_uring-kbuf-flag-partial-buffer-mappings.patch
+io_uring-gate-req_f_isreg-on-s_anon_inode-as-well.patch