[RFC PATCH 2/3] fs/splice: Atomically read pipe->{head,tail} in opipe_prep()

From: K Prateek Nayak
Date: Thu Mar 06 2025 - 06:46:51 EST


opipe_prep() checks pipe_full() before taking the "pipe->mutex". Use the
newly introduced "pipe->head_tail" member to read the head and the tail
atomically and not miss any updates between the reads.

Signed-off-by: K Prateek Nayak <kprateek.nayak@xxxxxxx>
---
fs/splice.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/splice.c b/fs/splice.c
index 28cfa63aa236..e51f33aca032 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1682,13 +1682,14 @@ static int ipipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
*/
static int opipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
{
+ union pipe_index idx = { .head_tail = READ_ONCE(pipe->head_tail) };
int ret;

/*
* Check pipe occupancy without the inode lock first. This function
* is speculative anyways, so missing one is ok.
*/
- if (!pipe_full(pipe->head, pipe->tail, pipe->max_usage))
+ if (!pipe_full(idx.head, idx.tail, READ_ONCE(pipe->max_usage)))
return 0;

ret = 0;
--
2.43.0