* FAILED: patch "[PATCH] splice: avoid stale f_pos writeback on error" failed to apply to 5.15-stable tree
@ 2026-11-07 11:13 Sasha Levin
2026-11-11 15:58 ` [PATCH 5.15.y 1/3] splice: report related fsnotify events Sasha Levin
0 siblings, 1 reply; 4+ messages in thread
From: Sasha Levin @ 2026-11-07 11:13 UTC (permalink / raw)
To: 4ncienth, brauner; +Cc: stable
The patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x 79b496ebe382866e3a05090b7dc9ae95e85e65b2
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '20261107061356-failed-5.15-79b496ebe382@kernel.org' --subject-prefix 'PATCH 5.15.y' 'HEAD^..'
Thanks,
Sasha
------------------ original commit in Linus's tree ------------------
From 79b496ebe382866e3a05090b7dc9ae95e85e65b2 Mon Sep 17 00:00:00 2001
From: Daehyeon Ko <4ncienth@gmail.com>
Date: Sun, 18 Oct 2026 14:17:08 +0900
Subject: [PATCH] splice: avoid stale f_pos writeback on error
do_splice() snapshots an implicit file position before calling the splice
helper. Since splice does not take f_pos_lock, another operation on the
same open file description can update f_pos while the helper is blocked.
If the helper then fails, the unconditional writeback restores the stale
snapshot.
For a directory without ->splice_read, a file-to-pipe splice fails with
-EINVAL. A concurrent directory mutation and getdents() call can advance
f_pos and refresh the filesystem's revalidation cookie before that failure
restores only the old position. The next ext2 readdir can then trust an
offset inside a directory entry and copy data from the adjacent page to
userspace.
Only update an implicit file position when splice returns a non-negative
result, matching read and write. Keep explicit offset updates unchanged.
Fixes: 7995bd287134 ("splice: don't pass the address of ->f_pos to methods")
Cc: stable@vger.kernel.org
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Link: https://patch.msgid.link/20261018051708.2422394-1-4ncienth@gmail.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
fs/splice.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/fs/splice.c b/fs/splice.c
index bc243ab8dc431..f4bce35890671 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1377,10 +1377,10 @@ ssize_t do_splice(struct file *in, loff_t *off_in, struct file *out,
ret = do_splice_from(ipipe, out, &offset, len, flags);
file_end_write(out);
- if (!off_out)
- out->f_pos = offset;
- else
+ if (off_out)
*off_out = offset;
+ else if (ret >= 0)
+ out->f_pos = offset;
} else if (opipe) {
if (off_out)
return -ESPIPE;
@@ -1401,10 +1401,10 @@ ssize_t do_splice(struct file *in, loff_t *off_in, struct file *out,
ret = splice_file_to_pipe(in, opipe, &offset, len, flags);
- if (!off_in)
- in->f_pos = offset;
- else
+ if (off_in)
*off_in = offset;
+ else if (ret >= 0)
+ in->f_pos = offset;
} else {
ret = -EINVAL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 5.15.y 1/3] splice: report related fsnotify events
2026-11-07 11:13 FAILED: patch "[PATCH] splice: avoid stale f_pos writeback on error" failed to apply to 5.15-stable tree Sasha Levin
@ 2026-11-11 15:58 ` Sasha Levin
2026-11-11 15:58 ` [PATCH 5.15.y 2/3] splice: always fsnotify_access(in), fsnotify_modify(out) on success Sasha Levin
2026-11-11 15:58 ` [PATCH 5.15.y 3/3] splice: avoid stale f_pos writeback on error Sasha Levin
0 siblings, 2 replies; 4+ messages in thread
From: Sasha Levin @ 2026-11-11 15:58 UTC (permalink / raw)
To: stable
Cc: Chung-Chiang Cheng, Amir Goldstein, Jan Kara, Christian Brauner,
Sasha Levin
From: Chung-Chiang Cheng <cccheng@synology.com>
[ Upstream commit 983652c691990b3257a07f67f4263eb847baa82d ]
The fsnotify ACCESS and MODIFY event are missing when manipulating a file
with splice(2).
Signed-off-by: Chung-Chiang Cheng <cccheng@synology.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Acked-by: Jan Kara <jack@suse.cz>
Message-Id: <20230322062519.409752-1-cccheng@synology.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: 79b496ebe382 ("splice: avoid stale f_pos writeback on error")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/splice.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/fs/splice.c b/fs/splice.c
index a43152bb106fc..b939b101fd832 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -30,6 +30,7 @@
#include <linux/export.h>
#include <linux/syscalls.h>
#include <linux/uio.h>
+#include <linux/fsnotify.h>
#include <linux/security.h>
#include <linux/gfp.h>
#include <linux/socket.h>
@@ -1108,6 +1109,9 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
ret = do_splice_from(ipipe, out, &offset, len, flags);
file_end_write(out);
+ if (ret > 0)
+ fsnotify_modify(out);
+
if (!off_out)
out->f_pos = offset;
else
@@ -1131,6 +1135,10 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
flags |= SPLICE_F_NONBLOCK;
ret = splice_file_to_pipe(in, opipe, &offset, len, flags);
+
+ if (ret > 0)
+ fsnotify_access(in);
+
if (!off_in)
in->f_pos = offset;
else
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 5.15.y 2/3] splice: always fsnotify_access(in), fsnotify_modify(out) on success
2026-11-11 15:58 ` [PATCH 5.15.y 1/3] splice: report related fsnotify events Sasha Levin
@ 2026-11-11 15:58 ` Sasha Levin
2026-11-11 15:58 ` [PATCH 5.15.y 3/3] splice: avoid stale f_pos writeback on error Sasha Levin
1 sibling, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-11-11 15:58 UTC (permalink / raw)
To: stable
Cc: Ahelenia Ziemiańska, Jan Kara, Amir Goldstein,
Christian Brauner, Sasha Levin
From: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
[ Upstream commit 12ee4b66af34f8e72f3b2fd93a946a955efe7c86 ]
The current behaviour caused an asymmetry where some write APIs
(write, sendfile) would notify the written-to/read-from objects,
but splice wouldn't.
This affected userspace which uses inotify, most notably coreutils
tail -f, to monitor pipes.
If the pipe buffer had been filled by a splice-family function:
* tail wouldn't know and thus wouldn't service the pipe, and
* all writes to the pipe would block because it's full,
thus service was denied.
(For the particular case of tail -f this could be worked around
with ---disable-inotify.)
Fixes: 983652c69199 ("splice: report related fsnotify events")
Link: https://lore.kernel.org/linux-fsdevel/jbyihkyk5dtaohdwjyivambb2gffyjs3dodpofafnkkunxq7bu@jngkdxx65pux/t/#u
Link: https://bugs.debian.org/1039488
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Acked-by: Jan Kara <jack@suse.cz>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Message-Id: <604ec704d933e0e0121d9e107ce914512e045fad.1688393619.git.nabijaczleweli@nabijaczleweli.xyz>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: 79b496ebe382 ("splice: avoid stale f_pos writeback on error")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/splice.c | 32 +++++++++++++++-----------------
1 file changed, 15 insertions(+), 17 deletions(-)
diff --git a/fs/splice.c b/fs/splice.c
index b939b101fd832..70008e08998f5 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1081,10 +1081,8 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
if ((in->f_flags | out->f_flags) & O_NONBLOCK)
flags |= SPLICE_F_NONBLOCK;
- return splice_pipe_to_pipe(ipipe, opipe, len, flags);
- }
-
- if (ipipe) {
+ ret = splice_pipe_to_pipe(ipipe, opipe, len, flags);
+ } else if (ipipe) {
if (off_in)
return -ESPIPE;
if (off_out) {
@@ -1109,18 +1107,11 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
ret = do_splice_from(ipipe, out, &offset, len, flags);
file_end_write(out);
- if (ret > 0)
- fsnotify_modify(out);
-
if (!off_out)
out->f_pos = offset;
else
*off_out = offset;
-
- return ret;
- }
-
- if (opipe) {
+ } else if (opipe) {
if (off_out)
return -ESPIPE;
if (off_in) {
@@ -1136,18 +1127,25 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
ret = splice_file_to_pipe(in, opipe, &offset, len, flags);
- if (ret > 0)
- fsnotify_access(in);
-
if (!off_in)
in->f_pos = offset;
else
*off_in = offset;
+ } else {
+ ret = -EINVAL;
+ }
- return ret;
+ if (ret > 0) {
+ /*
+ * Generate modify out before access in:
+ * do_splice_from() may've already sent modify out,
+ * and this ensures the events get merged.
+ */
+ fsnotify_modify(out);
+ fsnotify_access(in);
}
- return -EINVAL;
+ return ret;
}
static long __do_splice(struct file *in, loff_t __user *off_in,
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 5.15.y 3/3] splice: avoid stale f_pos writeback on error
2026-11-11 15:58 ` [PATCH 5.15.y 1/3] splice: report related fsnotify events Sasha Levin
2026-11-11 15:58 ` [PATCH 5.15.y 2/3] splice: always fsnotify_access(in), fsnotify_modify(out) on success Sasha Levin
@ 2026-11-11 15:58 ` Sasha Levin
1 sibling, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-11-11 15:58 UTC (permalink / raw)
To: stable; +Cc: Daehyeon Ko, Christian Brauner (Amutable), Sasha Levin
From: Daehyeon Ko <4ncienth@gmail.com>
[ Upstream commit 79b496ebe382866e3a05090b7dc9ae95e85e65b2 ]
do_splice() snapshots an implicit file position before calling the splice
helper. Since splice does not take f_pos_lock, another operation on the
same open file description can update f_pos while the helper is blocked.
If the helper then fails, the unconditional writeback restores the stale
snapshot.
For a directory without ->splice_read, a file-to-pipe splice fails with
-EINVAL. A concurrent directory mutation and getdents() call can advance
f_pos and refresh the filesystem's revalidation cookie before that failure
restores only the old position. The next ext2 readdir can then trust an
offset inside a directory entry and copy data from the adjacent page to
userspace.
Only update an implicit file position when splice returns a non-negative
result, matching read and write. Keep explicit offset updates unchanged.
Fixes: 7995bd287134 ("splice: don't pass the address of ->f_pos to methods")
Cc: stable@vger.kernel.org
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Link: https://patch.msgid.link/20261018051708.2422394-1-4ncienth@gmail.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/splice.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/fs/splice.c b/fs/splice.c
index 70008e08998f5..3630fd18a12e8 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1107,10 +1107,10 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
ret = do_splice_from(ipipe, out, &offset, len, flags);
file_end_write(out);
- if (!off_out)
- out->f_pos = offset;
- else
+ if (off_out)
*off_out = offset;
+ else if (ret >= 0)
+ out->f_pos = offset;
} else if (opipe) {
if (off_out)
return -ESPIPE;
@@ -1127,10 +1127,10 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
ret = splice_file_to_pipe(in, opipe, &offset, len, flags);
- if (!off_in)
- in->f_pos = offset;
- else
+ if (off_in)
*off_in = offset;
+ else if (ret >= 0)
+ in->f_pos = offset;
} else {
ret = -EINVAL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-11-11 15:59 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-07 11:13 FAILED: patch "[PATCH] splice: avoid stale f_pos writeback on error" failed to apply to 5.15-stable tree Sasha Levin
2026-11-11 15:58 ` [PATCH 5.15.y 1/3] splice: report related fsnotify events Sasha Levin
2026-11-11 15:58 ` [PATCH 5.15.y 2/3] splice: always fsnotify_access(in), fsnotify_modify(out) on success Sasha Levin
2026-11-11 15:58 ` [PATCH 5.15.y 3/3] splice: avoid stale f_pos writeback on error Sasha Levin
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.