Patchwork [3.5.y.z,extended,stable] Patch "tcp: fix MSG_SENDPAGE_NOTLAST logic" has been added to staging queue

mail settings
Submitter Herton Ronaldo Krzesinski
Date Jan. 14, 2013, 8:58 p.m.
Message ID <>
Download mbox | patch
Permalink /patch/211922/
State New
Headers show


Herton Ronaldo Krzesinski - Jan. 14, 2013, 8:58 p.m.
This is a note to let you know that I have just added a patch titled

    tcp: fix MSG_SENDPAGE_NOTLAST logic

to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree 
which can be found at:;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.y.z tree, see



From 663ba304005ac179f361078a607ecfec2b88ccc1 Mon Sep 17 00:00:00 2001
From: Eric Dumazet <>
Date: Sun, 6 Jan 2013 18:21:49 +0000
Subject: [PATCH] tcp: fix MSG_SENDPAGE_NOTLAST logic

commit ae62ca7b03217be5e74759dc6d7698c95df498b3 upstream.

commit 35f9c09fe9c72e (tcp: tcp_sendpages() should call tcp_push() once)
added an internal flag : MSG_SENDPAGE_NOTLAST meant to be set on all
frags but the last one for a splice() call.

The condition used to set the flag in pipe_to_sendpage() relied on
splice() user passing the exact number of bytes present in the pipe,
or a smaller one.

But some programs pass an arbitrary high value, and the test fails.

The effect of this bug is a lack of tcp_push() at the end of a
splice(pipe -> socket) call, and possibly very slow or erratic TCP

We should both test sd->total_len and fact that another fragment
is in the pipe (pipe->nrbufs > 1)

Many thanks to Willy for providing very clear bug report, bisection
and test programs.

Reported-by: Willy Tarreau <>
Bisected-by: Willy Tarreau <>
Tested-by: Willy Tarreau <>
Signed-off-by: Eric Dumazet <>
Signed-off-by: David S. Miller <>
Signed-off-by: Herton Ronaldo Krzesinski <>
 fs/splice.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)



diff --git a/fs/splice.c b/fs/splice.c
index 7bf08fa..6cb3acb 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -696,8 +696,10 @@  static int pipe_to_sendpage(struct pipe_inode_info *pipe,
 		return -EINVAL;

 	more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0;
-	if (sd->len < sd->total_len)
+	if (sd->len < sd->total_len && pipe->nrbufs > 1)
 	return file->f_op->sendpage(file, buf->page, buf->offset,
 				    sd->len, &pos, more);