@@ -1918,6 +1918,7 @@ static bool __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe,
19181918 struct splice_pipe_desc * spd , struct sock * sk )
19191919{
19201920 int seg ;
1921+ struct sk_buff * iter ;
19211922
19221923 /* map the linear part :
19231924 * If skb->head_frag is set, this 'linear' part is backed by a
@@ -1944,6 +1945,19 @@ static bool __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe,
19441945 return true;
19451946 }
19461947
1948+ skb_walk_frags (skb , iter ) {
1949+ if (* offset >= iter -> len ) {
1950+ * offset -= iter -> len ;
1951+ continue ;
1952+ }
1953+ /* __skb_splice_bits() only fails if the output has no room
1954+ * left, so no point in going over the frag_list for the error
1955+ * case.
1956+ */
1957+ if (__skb_splice_bits (iter , pipe , offset , len , spd , sk ))
1958+ return true;
1959+ }
1960+
19471961 return false;
19481962}
19491963
@@ -1970,9 +1984,7 @@ ssize_t skb_socket_splice(struct sock *sk,
19701984
19711985/*
19721986 * Map data from the skb to a pipe. Should handle both the linear part,
1973- * the fragments, and the frag list. It does NOT handle frag lists within
1974- * the frag list, if such a thing exists. We'd probably need to recurse to
1975- * handle that cleanly.
1987+ * the fragments, and the frag list.
19761988 */
19771989int skb_splice_bits (struct sk_buff * skb , struct sock * sk , unsigned int offset ,
19781990 struct pipe_inode_info * pipe , unsigned int tlen ,
@@ -1991,29 +2003,10 @@ int skb_splice_bits(struct sk_buff *skb, struct sock *sk, unsigned int offset,
19912003 .ops = & nosteal_pipe_buf_ops ,
19922004 .spd_release = sock_spd_release ,
19932005 };
1994- struct sk_buff * frag_iter ;
19952006 int ret = 0 ;
19962007
1997- /*
1998- * __skb_splice_bits() only fails if the output has no room left,
1999- * so no point in going over the frag_list for the error case.
2000- */
2001- if (__skb_splice_bits (skb , pipe , & offset , & tlen , & spd , sk ))
2002- goto done ;
2003- else if (!tlen )
2004- goto done ;
2008+ __skb_splice_bits (skb , pipe , & offset , & tlen , & spd , sk );
20052009
2006- /*
2007- * now see if we have a frag_list to map
2008- */
2009- skb_walk_frags (skb , frag_iter ) {
2010- if (!tlen )
2011- break ;
2012- if (__skb_splice_bits (frag_iter , pipe , & offset , & tlen , & spd , sk ))
2013- break ;
2014- }
2015-
2016- done :
20172010 if (spd .nr_pages )
20182011 ret = splice_cb (sk , pipe , & spd );
20192012
0 commit comments