inet, inet6: make tcp_sendmsg() and tcp_sendpage() through inet_sendmsg() and inet_se...
Changli Gao [Sat, 10 Jul 2010 20:41:55 +0000 (20:41 +0000)]
a new boolean flag no_autobind is added to structure proto to avoid the autobind
calls when the protocol is TCP. Then sock_rps_record_flow() is called int the
TCP's sendmsg() and sendpage() pathes.

Signed-off-by: Changli Gao <xiaosuo@gmail.com>
----
 include/net/inet_common.h |    4 ++++
 include/net/sock.h        |    1 +
 include/net/tcp.h         |    8 ++++----
 net/ipv4/af_inet.c        |   15 +++++++++------
 net/ipv4/tcp.c            |   11 +++++------
 net/ipv4/tcp_ipv4.c       |    3 +++
 net/ipv6/af_inet6.c       |    8 ++++----
 net/ipv6/tcp_ipv6.c       |    3 +++
 8 files changed, 33 insertions(+), 20 deletions(-)
Signed-off-by: David S. Miller <davem@davemloft.net>

include/net/inet_common.h
include/net/sock.h
include/net/tcp.h
net/ipv4/af_inet.c
net/ipv4/tcp.c
net/ipv4/tcp_ipv4.c
net/ipv6/af_inet6.c
net/ipv6/tcp_ipv6.c

index 140c1ec..22fac98 100644 (file)
@@ -21,6 +21,10 @@ extern int inet_dgram_connect(struct socket *sock, struct sockaddr * uaddr,
 extern int inet_accept(struct socket *sock, struct socket *newsock, int flags);
 extern int inet_sendmsg(struct kiocb *iocb, struct socket *sock,
                        struct msghdr *msg, size_t size);
+extern ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset,
+                            size_t size, int flags);
+extern int inet_recvmsg(struct kiocb *iocb, struct socket *sock,
+                       struct msghdr *msg, size_t size, int flags);
 extern int inet_shutdown(struct socket *sock, int how);
 extern int inet_listen(struct socket *sock, int backlog);
 extern void inet_sock_destruct(struct sock *sk);
index 4f26f2f..3100e71 100644 (file)
@@ -772,6 +772,7 @@ struct proto {
        int                     *sysctl_wmem;
        int                     *sysctl_rmem;
        int                     max_header;
+       bool                    no_autobind;
 
        struct kmem_cache       *slab;
        unsigned int            obj_size;
index 33ce524..468b01f 100644 (file)
@@ -304,10 +304,10 @@ extern int tcp_v4_rcv(struct sk_buff *skb);
 
 extern int tcp_v4_remember_stamp(struct sock *sk);
 extern int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw);
-extern int tcp_sendmsg(struct kiocb *iocb, struct socket *sock,
-                      struct msghdr *msg, size_t size);
-extern ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset,
-                           size_t size, int flags);
+extern int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+                      size_t size);
+extern int tcp_sendpage(struct sock *sk, struct page *page, int offset,
+                       size_t size, int flags);
 extern int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg);
 extern int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                                 struct tcphdr *th, unsigned len);
index 3ceb025..6a1100c 100644 (file)
@@ -727,28 +727,31 @@ int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
        sock_rps_record_flow(sk);
 
        /* We may need to bind the socket. */
-       if (!inet_sk(sk)->inet_num && inet_autobind(sk))
+       if (!inet_sk(sk)->inet_num && !sk->sk_prot->no_autobind &&
+           inet_autobind(sk))
                return -EAGAIN;
 
        return sk->sk_prot->sendmsg(iocb, sk, msg, size);
 }
 EXPORT_SYMBOL(inet_sendmsg);
 
-static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset,
-                            size_t size, int flags)
+ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset,
+                     size_t size, int flags)
 {
        struct sock *sk = sock->sk;
 
        sock_rps_record_flow(sk);
 
        /* We may need to bind the socket. */
-       if (!inet_sk(sk)->inet_num && inet_autobind(sk))
+       if (!inet_sk(sk)->inet_num && !sk->sk_prot->no_autobind &&
+           inet_autobind(sk))
                return -EAGAIN;
 
        if (sk->sk_prot->sendpage)
                return sk->sk_prot->sendpage(sk, page, offset, size, flags);
        return sock_no_sendpage(sock, page, offset, size, flags);
 }
+EXPORT_SYMBOL(inet_sendpage);
 
 int inet_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
                 size_t size, int flags)
@@ -894,10 +897,10 @@ const struct proto_ops inet_stream_ops = {
        .shutdown          = inet_shutdown,
        .setsockopt        = sock_common_setsockopt,
        .getsockopt        = sock_common_getsockopt,
-       .sendmsg           = tcp_sendmsg,
+       .sendmsg           = inet_sendmsg,
        .recvmsg           = inet_recvmsg,
        .mmap              = sock_no_mmap,
-       .sendpage          = tcp_sendpage,
+       .sendpage          = inet_sendpage,
        .splice_read       = tcp_splice_read,
 #ifdef CONFIG_COMPAT
        .compat_setsockopt = compat_sock_common_setsockopt,
index b8601b7..9fce8a8 100644 (file)
@@ -857,15 +857,15 @@ out_err:
        return sk_stream_error(sk, flags, err);
 }
 
-ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset,
-                    size_t size, int flags)
+int tcp_sendpage(struct sock *sk, struct page *page, int offset,
+                size_t size, int flags)
 {
        ssize_t res;
-       struct sock *sk = sock->sk;
 
        if (!(sk->sk_route_caps & NETIF_F_SG) ||
            !(sk->sk_route_caps & NETIF_F_ALL_CSUM))
-               return sock_no_sendpage(sock, page, offset, size, flags);
+               return sock_no_sendpage(sk->sk_socket, page, offset, size,
+                                       flags);
 
        lock_sock(sk);
        TCP_CHECK_TIMER(sk);
@@ -899,10 +899,9 @@ static inline int select_size(struct sock *sk, int sg)
        return tmp;
 }
 
-int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
+int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                size_t size)
 {
-       struct sock *sk = sock->sk;
        struct iovec *iov;
        struct tcp_sock *tp = tcp_sk(sk);
        struct sk_buff *skb;
index 44545e8..0207662 100644 (file)
@@ -2600,6 +2600,8 @@ struct proto tcp_prot = {
        .setsockopt             = tcp_setsockopt,
        .getsockopt             = tcp_getsockopt,
        .recvmsg                = tcp_recvmsg,
+       .sendmsg                = tcp_sendmsg,
+       .sendpage               = tcp_sendpage,
        .backlog_rcv            = tcp_v4_do_rcv,
        .hash                   = inet_hash,
        .unhash                 = inet_unhash,
@@ -2618,6 +2620,7 @@ struct proto tcp_prot = {
        .twsk_prot              = &tcp_timewait_sock_ops,
        .rsk_prot               = &tcp_request_sock_ops,
        .h.hashinfo             = &tcp_hashinfo,
+       .no_autobind            = true,
 #ifdef CONFIG_COMPAT
        .compat_setsockopt      = compat_tcp_setsockopt,
        .compat_getsockopt      = compat_tcp_getsockopt,
index e830cd4..56b9bf2 100644 (file)
@@ -522,10 +522,10 @@ const struct proto_ops inet6_stream_ops = {
        .shutdown          = inet_shutdown,             /* ok           */
        .setsockopt        = sock_common_setsockopt,    /* ok           */
        .getsockopt        = sock_common_getsockopt,    /* ok           */
-       .sendmsg           = tcp_sendmsg,               /* ok           */
-       .recvmsg           = sock_common_recvmsg,       /* ok           */
+       .sendmsg           = inet_sendmsg,              /* ok           */
+       .recvmsg           = inet_recvmsg,              /* ok           */
        .mmap              = sock_no_mmap,
-       .sendpage          = tcp_sendpage,
+       .sendpage          = inet_sendpage,
        .splice_read       = tcp_splice_read,
 #ifdef CONFIG_COMPAT
        .compat_setsockopt = compat_sock_common_setsockopt,
@@ -549,7 +549,7 @@ const struct proto_ops inet6_dgram_ops = {
        .setsockopt        = sock_common_setsockopt,    /* ok           */
        .getsockopt        = sock_common_getsockopt,    /* ok           */
        .sendmsg           = inet_sendmsg,              /* ok           */
-       .recvmsg           = sock_common_recvmsg,       /* ok           */
+       .recvmsg           = inet_recvmsg,              /* ok           */
        .mmap              = sock_no_mmap,
        .sendpage          = sock_no_sendpage,
 #ifdef CONFIG_COMPAT
index 5ebc27e..fe6d404 100644 (file)
@@ -2142,6 +2142,8 @@ struct proto tcpv6_prot = {
        .setsockopt             = tcp_setsockopt,
        .getsockopt             = tcp_getsockopt,
        .recvmsg                = tcp_recvmsg,
+       .sendmsg                = tcp_sendmsg,
+       .sendpage               = tcp_sendpage,
        .backlog_rcv            = tcp_v6_do_rcv,
        .hash                   = tcp_v6_hash,
        .unhash                 = inet_unhash,
@@ -2160,6 +2162,7 @@ struct proto tcpv6_prot = {
        .twsk_prot              = &tcp6_timewait_sock_ops,
        .rsk_prot               = &tcp6_request_sock_ops,
        .h.hashinfo             = &tcp_hashinfo,
+       .no_autobind            = true,
 #ifdef CONFIG_COMPAT
        .compat_setsockopt      = compat_tcp_setsockopt,
        .compat_getsockopt      = compat_tcp_getsockopt,