|
@@ -522,8 +522,12 @@ static int tcp_splice_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
|
|
|
unsigned int offset, size_t len)
|
|
|
{
|
|
|
struct tcp_splice_state *tss = rd_desc->arg.data;
|
|
|
+ int ret;
|
|
|
|
|
|
- return skb_splice_bits(skb, offset, tss->pipe, tss->len, tss->flags);
|
|
|
+ ret = skb_splice_bits(skb, offset, tss->pipe, rd_desc->count, tss->flags);
|
|
|
+ if (ret > 0)
|
|
|
+ rd_desc->count -= ret;
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static int __tcp_splice_read(struct sock *sk, struct tcp_splice_state *tss)
|
|
@@ -531,6 +535,7 @@ static int __tcp_splice_read(struct sock *sk, struct tcp_splice_state *tss)
|
|
|
/* Store TCP splice context information in read_descriptor_t. */
|
|
|
read_descriptor_t rd_desc = {
|
|
|
.arg.data = tss,
|
|
|
+ .count = tss->len,
|
|
|
};
|
|
|
|
|
|
return tcp_read_sock(sk, &rd_desc, tcp_splice_data_recv);
|
|
@@ -611,11 +616,13 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos,
|
|
|
tss.len -= ret;
|
|
|
spliced += ret;
|
|
|
|
|
|
+ if (!timeo)
|
|
|
+ break;
|
|
|
release_sock(sk);
|
|
|
lock_sock(sk);
|
|
|
|
|
|
if (sk->sk_err || sk->sk_state == TCP_CLOSE ||
|
|
|
- (sk->sk_shutdown & RCV_SHUTDOWN) || !timeo ||
|
|
|
+ (sk->sk_shutdown & RCV_SHUTDOWN) ||
|
|
|
signal_pending(current))
|
|
|
break;
|
|
|
}
|