@@ -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+
40264160static 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
40494184static 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
41544290static struct proto mptcp_v6_prot ;
0 commit comments