aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix
diff options
context:
space:
mode:
authorHannes Frederic Sowa <hannes@stressinduktion.org>2015-05-21 11:00:01 -0400
committerDavid S. Miller <davem@davemloft.net>2015-05-25 00:06:59 -0400
commit2b514574f7e88c8498027ee366fd6e7aae5aa4b5 (patch)
tree1fd7303692dfbbf1c9c3348cb79961ceb5078cd1 /net/unix
parenta60e3cc7c92973a31fad0fd04dc5cf4355d3d1ef (diff)
net: af_unix: implement splice for stream af_unix sockets
unix_stream_recvmsg is refactored to unix_stream_read_generic in this patch and enhanced to deal with pipe splicing. The refactoring is inneglible, we mostly have to deal with a non-existing struct msghdr argument. Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/unix')
-rw-r--r--net/unix/af_unix.c140
1 files changed, 119 insertions, 21 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 7762c0b46721..b8c44076c776 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -520,6 +520,9 @@ static int unix_stream_sendmsg(struct socket *, struct msghdr *, size_t);
520static int unix_stream_recvmsg(struct socket *, struct msghdr *, size_t, int); 520static int unix_stream_recvmsg(struct socket *, struct msghdr *, size_t, int);
521static ssize_t unix_stream_sendpage(struct socket *, struct page *, int offset, 521static ssize_t unix_stream_sendpage(struct socket *, struct page *, int offset,
522 size_t size, int flags); 522 size_t size, int flags);
523static ssize_t unix_stream_splice_read(struct socket *, loff_t *ppos,
524 struct pipe_inode_info *, size_t size,
525 unsigned int flags);
523static int unix_dgram_sendmsg(struct socket *, struct msghdr *, size_t); 526static int unix_dgram_sendmsg(struct socket *, struct msghdr *, size_t);
524static int unix_dgram_recvmsg(struct socket *, struct msghdr *, size_t, int); 527static int unix_dgram_recvmsg(struct socket *, struct msghdr *, size_t, int);
525static int unix_dgram_connect(struct socket *, struct sockaddr *, 528static int unix_dgram_connect(struct socket *, struct sockaddr *,
@@ -561,6 +564,7 @@ static const struct proto_ops unix_stream_ops = {
561 .recvmsg = unix_stream_recvmsg, 564 .recvmsg = unix_stream_recvmsg,
562 .mmap = sock_no_mmap, 565 .mmap = sock_no_mmap,
563 .sendpage = unix_stream_sendpage, 566 .sendpage = unix_stream_sendpage,
567 .splice_read = unix_stream_splice_read,
564 .set_peek_off = unix_set_peek_off, 568 .set_peek_off = unix_set_peek_off,
565}; 569};
566 570
@@ -1957,8 +1961,9 @@ out:
1957 * Sleep until more data has arrived. But check for races.. 1961 * Sleep until more data has arrived. But check for races..
1958 */ 1962 */
1959static long unix_stream_data_wait(struct sock *sk, long timeo, 1963static long unix_stream_data_wait(struct sock *sk, long timeo,
1960 struct sk_buff *last) 1964 struct sk_buff *last, unsigned int last_len)
1961{ 1965{
1966 struct sk_buff *tail;
1962 DEFINE_WAIT(wait); 1967 DEFINE_WAIT(wait);
1963 1968
1964 unix_state_lock(sk); 1969 unix_state_lock(sk);
@@ -1966,7 +1971,9 @@ static long unix_stream_data_wait(struct sock *sk, long timeo,
1966 for (;;) { 1971 for (;;) {
1967 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 1972 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
1968 1973
1969 if (skb_peek_tail(&sk->sk_receive_queue) != last || 1974 tail = skb_peek_tail(&sk->sk_receive_queue);
1975 if (tail != last ||
1976 (tail && tail->len != last_len) ||
1970 sk->sk_err || 1977 sk->sk_err ||
1971 (sk->sk_shutdown & RCV_SHUTDOWN) || 1978 (sk->sk_shutdown & RCV_SHUTDOWN) ||
1972 signal_pending(current) || 1979 signal_pending(current) ||
@@ -1990,38 +1997,50 @@ static unsigned int unix_skb_len(const struct sk_buff *skb)
1990 return skb->len - UNIXCB(skb).consumed; 1997 return skb->len - UNIXCB(skb).consumed;
1991} 1998}
1992 1999
1993static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg, 2000struct unix_stream_read_state {
1994 size_t size, int flags) 2001 int (*recv_actor)(struct sk_buff *, int, int,
2002 struct unix_stream_read_state *);
2003 struct socket *socket;
2004 struct msghdr *msg;
2005 struct pipe_inode_info *pipe;
2006 size_t size;
2007 int flags;
2008 unsigned int splice_flags;
2009};
2010
2011static int unix_stream_read_generic(struct unix_stream_read_state *state)
1995{ 2012{
1996 struct scm_cookie scm; 2013 struct scm_cookie scm;
2014 struct socket *sock = state->socket;
1997 struct sock *sk = sock->sk; 2015 struct sock *sk = sock->sk;
1998 struct unix_sock *u = unix_sk(sk); 2016 struct unix_sock *u = unix_sk(sk);
1999 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name);
2000 int copied = 0; 2017 int copied = 0;
2018 int flags = state->flags;
2001 int noblock = flags & MSG_DONTWAIT; 2019 int noblock = flags & MSG_DONTWAIT;
2002 int check_creds = 0; 2020 bool check_creds = false;
2003 int target; 2021 int target;
2004 int err = 0; 2022 int err = 0;
2005 long timeo; 2023 long timeo;
2006 int skip; 2024 int skip;
2025 size_t size = state->size;
2026 unsigned int last_len;
2007 2027
2008 err = -EINVAL; 2028 err = -EINVAL;
2009 if (sk->sk_state != TCP_ESTABLISHED) 2029 if (sk->sk_state != TCP_ESTABLISHED)
2010 goto out; 2030 goto out;
2011 2031
2012 err = -EOPNOTSUPP; 2032 err = -EOPNOTSUPP;
2013 if (flags&MSG_OOB) 2033 if (flags & MSG_OOB)
2014 goto out; 2034 goto out;
2015 2035
2016 target = sock_rcvlowat(sk, flags&MSG_WAITALL, size); 2036 target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
2017 timeo = sock_rcvtimeo(sk, noblock); 2037 timeo = sock_rcvtimeo(sk, noblock);
2018 2038
2039 memset(&scm, 0, sizeof(scm));
2040
2019 /* Lock the socket to prevent queue disordering 2041 /* Lock the socket to prevent queue disordering
2020 * while sleeps in memcpy_tomsg 2042 * while sleeps in memcpy_tomsg
2021 */ 2043 */
2022
2023 memset(&scm, 0, sizeof(scm));
2024
2025 err = mutex_lock_interruptible(&u->readlock); 2044 err = mutex_lock_interruptible(&u->readlock);
2026 if (unlikely(err)) { 2045 if (unlikely(err)) {
2027 /* recvmsg() in non blocking mode is supposed to return -EAGAIN 2046 /* recvmsg() in non blocking mode is supposed to return -EAGAIN
@@ -2037,6 +2056,7 @@ static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg,
2037 2056
2038 unix_state_lock(sk); 2057 unix_state_lock(sk);
2039 last = skb = skb_peek(&sk->sk_receive_queue); 2058 last = skb = skb_peek(&sk->sk_receive_queue);
2059 last_len = last ? last->len : 0;
2040again: 2060again:
2041 if (skb == NULL) { 2061 if (skb == NULL) {
2042 unix_sk(sk)->recursion_level = 0; 2062 unix_sk(sk)->recursion_level = 0;
@@ -2059,16 +2079,17 @@ again:
2059 break; 2079 break;
2060 mutex_unlock(&u->readlock); 2080 mutex_unlock(&u->readlock);
2061 2081
2062 timeo = unix_stream_data_wait(sk, timeo, last); 2082 timeo = unix_stream_data_wait(sk, timeo, last,
2083 last_len);
2063 2084
2064 if (signal_pending(current) 2085 if (signal_pending(current) ||
2065 || mutex_lock_interruptible(&u->readlock)) { 2086 mutex_lock_interruptible(&u->readlock)) {
2066 err = sock_intr_errno(timeo); 2087 err = sock_intr_errno(timeo);
2067 goto out; 2088 goto out;
2068 } 2089 }
2069 2090
2070 continue; 2091 continue;
2071 unlock: 2092unlock:
2072 unix_state_unlock(sk); 2093 unix_state_unlock(sk);
2073 break; 2094 break;
2074 } 2095 }
@@ -2077,6 +2098,7 @@ again:
2077 while (skip >= unix_skb_len(skb)) { 2098 while (skip >= unix_skb_len(skb)) {
2078 skip -= unix_skb_len(skb); 2099 skip -= unix_skb_len(skb);
2079 last = skb; 2100 last = skb;
2101 last_len = skb->len;
2080 skb = skb_peek_next(skb, &sk->sk_receive_queue); 2102 skb = skb_peek_next(skb, &sk->sk_receive_queue);
2081 if (!skb) 2103 if (!skb)
2082 goto again; 2104 goto again;
@@ -2093,18 +2115,20 @@ again:
2093 } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { 2115 } else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
2094 /* Copy credentials */ 2116 /* Copy credentials */
2095 scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid); 2117 scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
2096 check_creds = 1; 2118 check_creds = true;
2097 } 2119 }
2098 2120
2099 /* Copy address just once */ 2121 /* Copy address just once */
2100 if (sunaddr) { 2122 if (state->msg && state->msg->msg_name) {
2101 unix_copy_addr(msg, skb->sk); 2123 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr,
2124 state->msg->msg_name);
2125 unix_copy_addr(state->msg, skb->sk);
2102 sunaddr = NULL; 2126 sunaddr = NULL;
2103 } 2127 }
2104 2128
2105 chunk = min_t(unsigned int, unix_skb_len(skb) - skip, size); 2129 chunk = min_t(unsigned int, unix_skb_len(skb) - skip, size);
2106 if (skb_copy_datagram_msg(skb, UNIXCB(skb).consumed + skip, 2130 chunk = state->recv_actor(skb, skip, chunk, state);
2107 msg, chunk)) { 2131 if (chunk < 0) {
2108 if (copied == 0) 2132 if (copied == 0)
2109 copied = -EFAULT; 2133 copied = -EFAULT;
2110 break; 2134 break;
@@ -2142,11 +2166,85 @@ again:
2142 } while (size); 2166 } while (size);
2143 2167
2144 mutex_unlock(&u->readlock); 2168 mutex_unlock(&u->readlock);
2145 scm_recv(sock, msg, &scm, flags); 2169 if (state->msg)
2170 scm_recv(sock, state->msg, &scm, flags);
2171 else
2172 scm_destroy(&scm);
2146out: 2173out:
2147 return copied ? : err; 2174 return copied ? : err;
2148} 2175}
2149 2176
2177static int unix_stream_read_actor(struct sk_buff *skb,
2178 int skip, int chunk,
2179 struct unix_stream_read_state *state)
2180{
2181 int ret;
2182
2183 ret = skb_copy_datagram_msg(skb, UNIXCB(skb).consumed + skip,
2184 state->msg, chunk);
2185 return ret ?: chunk;
2186}
2187
2188static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg,
2189 size_t size, int flags)
2190{
2191 struct unix_stream_read_state state = {
2192 .recv_actor = unix_stream_read_actor,
2193 .socket = sock,
2194 .msg = msg,
2195 .size = size,
2196 .flags = flags
2197 };
2198
2199 return unix_stream_read_generic(&state);
2200}
2201
2202static ssize_t skb_unix_socket_splice(struct sock *sk,
2203 struct pipe_inode_info *pipe,
2204 struct splice_pipe_desc *spd)
2205{
2206 int ret;
2207 struct unix_sock *u = unix_sk(sk);
2208
2209 mutex_unlock(&u->readlock);
2210 ret = splice_to_pipe(pipe, spd);
2211 mutex_lock(&u->readlock);
2212
2213 return ret;
2214}
2215
2216static int unix_stream_splice_actor(struct sk_buff *skb,
2217 int skip, int chunk,
2218 struct unix_stream_read_state *state)
2219{
2220 return skb_splice_bits(skb, state->socket->sk,
2221 UNIXCB(skb).consumed + skip,
2222 state->pipe, chunk, state->splice_flags,
2223 skb_unix_socket_splice);
2224}
2225
2226static ssize_t unix_stream_splice_read(struct socket *sock, loff_t *ppos,
2227 struct pipe_inode_info *pipe,
2228 size_t size, unsigned int flags)
2229{
2230 struct unix_stream_read_state state = {
2231 .recv_actor = unix_stream_splice_actor,
2232 .socket = sock,
2233 .pipe = pipe,
2234 .size = size,
2235 .splice_flags = flags,
2236 };
2237
2238 if (unlikely(*ppos))
2239 return -ESPIPE;
2240
2241 if (sock->file->f_flags & O_NONBLOCK ||
2242 flags & SPLICE_F_NONBLOCK)
2243 state.flags = MSG_DONTWAIT;
2244
2245 return unix_stream_read_generic(&state);
2246}
2247
2150static int unix_shutdown(struct socket *sock, int mode) 2248static int unix_shutdown(struct socket *sock, int mode)
2151{ 2249{
2152 struct sock *sk = sock->sk; 2250 struct sock *sk = sock->sk;