Skip to content

Commit 45b8dc0

Browse files
Geliang Tangintel-lab-lkp
authored andcommitted
mptcp: implement .splice_read
This patch implements .splice_read interface of mptcp struct proto_ops as mptcp_splice_read() with reference to tcp_splice_read(). Signed-off-by: Geliang Tang <[email protected]>
1 parent 52423da commit 45b8dc0

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed

net/mptcp/protocol.c

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4023,6 +4023,140 @@ static int mptcp_read_sock(struct sock *sk, read_descriptor_t *desc,
40234023
return copied;
40244024
}
40254025

4026+
/*
4027+
* MPTCP splice context
4028+
*/
4029+
struct mptcp_splice_state {
4030+
struct pipe_inode_info *pipe;
4031+
size_t len;
4032+
unsigned int flags;
4033+
};
4034+
4035+
static int mptcp_splice_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
4036+
unsigned int offset, size_t len)
4037+
{
4038+
struct mptcp_splice_state *mss = rd_desc->arg.data;
4039+
int ret;
4040+
4041+
ret = skb_splice_bits(skb, skb->sk, offset, mss->pipe,
4042+
min(rd_desc->count, len), mss->flags);
4043+
if (ret > 0)
4044+
rd_desc->count -= ret;
4045+
return ret;
4046+
}
4047+
4048+
static int __mptcp_splice_read(struct sock *sk, struct mptcp_splice_state *mss)
4049+
{
4050+
/* Store MPTCP splice context information in read_descriptor_t. */
4051+
read_descriptor_t rd_desc = {
4052+
.arg.data = mss,
4053+
.count = mss->len,
4054+
};
4055+
4056+
return mptcp_read_sock(sk, &rd_desc, mptcp_splice_data_recv);
4057+
}
4058+
4059+
/**
4060+
* mptcp_splice_read - splice data from MPTCP socket to a pipe
4061+
* @sock: socket to splice from
4062+
* @ppos: position (not valid)
4063+
* @pipe: pipe to splice to
4064+
* @len: number of bytes to splice
4065+
* @flags: splice modifier flags
4066+
*
4067+
* Description:
4068+
* Will read pages from given socket and fill them into a pipe.
4069+
*
4070+
**/
4071+
static ssize_t mptcp_splice_read(struct socket *sock, loff_t *ppos,
4072+
struct pipe_inode_info *pipe, size_t len,
4073+
unsigned int flags)
4074+
{
4075+
struct mptcp_splice_state mss = {
4076+
.pipe = pipe,
4077+
.len = len,
4078+
.flags = flags,
4079+
};
4080+
struct sock *sk = sock->sk;
4081+
ssize_t spliced;
4082+
long timeo;
4083+
int ret;
4084+
4085+
/*
4086+
* We can't seek on a socket input
4087+
*/
4088+
if (unlikely(*ppos))
4089+
return -ESPIPE;
4090+
4091+
spliced = 0;
4092+
ret = 0;
4093+
4094+
lock_sock(sk);
4095+
4096+
timeo = sock_rcvtimeo(sk, sock->file->f_flags & O_NONBLOCK);
4097+
while (mss.len) {
4098+
ret = __mptcp_splice_read(sk, &mss);
4099+
if (ret < 0) {
4100+
break;
4101+
} else if (!ret) {
4102+
if (spliced)
4103+
break;
4104+
if (sock_flag(sk, SOCK_DONE))
4105+
break;
4106+
if (sk->sk_err) {
4107+
ret = sock_error(sk);
4108+
break;
4109+
}
4110+
if (sk->sk_shutdown & RCV_SHUTDOWN) {
4111+
if (__mptcp_move_skbs(sk))
4112+
continue;
4113+
break;
4114+
}
4115+
if (sk->sk_state == TCP_CLOSE) {
4116+
ret = -ENOTCONN;
4117+
break;
4118+
}
4119+
if (!timeo) {
4120+
ret = -EAGAIN;
4121+
break;
4122+
}
4123+
/* if __mptcp_splice_read() got nothing while we have
4124+
* an skb in receive queue, we do not want to loop.
4125+
* This might happen with URG data.
4126+
*/
4127+
if (!skb_queue_empty(&sk->sk_receive_queue))
4128+
break;
4129+
ret = sk_wait_data(sk, &timeo, NULL);
4130+
if (ret < 0)
4131+
break;
4132+
if (signal_pending(current)) {
4133+
ret = sock_intr_errno(timeo);
4134+
break;
4135+
}
4136+
continue;
4137+
}
4138+
mss.len -= ret;
4139+
spliced += ret;
4140+
4141+
if (!mss.len || !timeo)
4142+
break;
4143+
release_sock(sk);
4144+
lock_sock(sk);
4145+
4146+
if (sk->sk_err || sk->sk_state == TCP_CLOSE ||
4147+
(sk->sk_shutdown & RCV_SHUTDOWN) ||
4148+
signal_pending(current))
4149+
break;
4150+
}
4151+
4152+
release_sock(sk);
4153+
4154+
if (spliced)
4155+
return spliced;
4156+
4157+
return ret;
4158+
}
4159+
40264160
static const struct proto_ops mptcp_stream_ops = {
40274161
.family = PF_INET,
40284162
.owner = THIS_MODULE,
@@ -4044,6 +4178,7 @@ static const struct proto_ops mptcp_stream_ops = {
40444178
.mmap = sock_no_mmap,
40454179
.set_rcvlowat = mptcp_set_rcvlowat,
40464180
.read_sock = mptcp_read_sock,
4181+
.splice_read = mptcp_splice_read,
40474182
};
40484183

40494184
static struct inet_protosw mptcp_protosw = {
@@ -4149,6 +4284,7 @@ static const struct proto_ops mptcp_v6_stream_ops = {
41494284
#endif
41504285
.set_rcvlowat = mptcp_set_rcvlowat,
41514286
.read_sock = mptcp_read_sock,
4287+
.splice_read = mptcp_splice_read,
41524288
};
41534289

41544290
static struct proto mptcp_v6_prot;

0 commit comments

Comments
 (0)