Commit aaa34256 authored by David S. Miller's avatar David S. Miller

Merge branch 'tipc-Fix-some-bugs-at-socket-layer'

Tung Nguyen says:

====================
tipc: Fix some bugs at socket layer

This series fixes some bugs at socket layer.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 61183b05 d34910e1
...@@ -532,7 +532,7 @@ static void __tipc_shutdown(struct socket *sock, int error) ...@@ -532,7 +532,7 @@ static void __tipc_shutdown(struct socket *sock, int error)
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct tipc_sock *tsk = tipc_sk(sk); struct tipc_sock *tsk = tipc_sk(sk);
struct net *net = sock_net(sk); struct net *net = sock_net(sk);
long timeout = CONN_TIMEOUT_DEFAULT; long timeout = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT);
u32 dnode = tsk_peer_node(tsk); u32 dnode = tsk_peer_node(tsk);
struct sk_buff *skb; struct sk_buff *skb;
...@@ -540,12 +540,10 @@ static void __tipc_shutdown(struct socket *sock, int error) ...@@ -540,12 +540,10 @@ static void __tipc_shutdown(struct socket *sock, int error)
tipc_wait_for_cond(sock, &timeout, (!tsk->cong_link_cnt && tipc_wait_for_cond(sock, &timeout, (!tsk->cong_link_cnt &&
!tsk_conn_cong(tsk))); !tsk_conn_cong(tsk)));
/* Push out unsent messages or remove if pending SYN */ /* Push out delayed messages if in Nagle mode */
skb = skb_peek(&sk->sk_write_queue); tipc_sk_push_backlog(tsk);
if (skb && !msg_is_syn(buf_msg(skb))) /* Remove pending SYN */
tipc_sk_push_backlog(tsk); __skb_queue_purge(&sk->sk_write_queue);
else
__skb_queue_purge(&sk->sk_write_queue);
/* Reject all unreceived messages, except on an active connection /* Reject all unreceived messages, except on an active connection
* (which disconnects locally & sends a 'FIN+' to peer). * (which disconnects locally & sends a 'FIN+' to peer).
...@@ -1248,9 +1246,14 @@ static void tipc_sk_push_backlog(struct tipc_sock *tsk) ...@@ -1248,9 +1246,14 @@ static void tipc_sk_push_backlog(struct tipc_sock *tsk)
struct sk_buff_head *txq = &tsk->sk.sk_write_queue; struct sk_buff_head *txq = &tsk->sk.sk_write_queue;
struct net *net = sock_net(&tsk->sk); struct net *net = sock_net(&tsk->sk);
u32 dnode = tsk_peer_node(tsk); u32 dnode = tsk_peer_node(tsk);
struct sk_buff *skb = skb_peek(txq);
int rc; int rc;
if (skb_queue_empty(txq) || tsk->cong_link_cnt) if (!skb || tsk->cong_link_cnt)
return;
/* Do not send SYN again after congestion */
if (msg_is_syn(buf_msg(skb)))
return; return;
tsk->snt_unacked += tsk->snd_backlog; tsk->snt_unacked += tsk->snd_backlog;
...@@ -1447,8 +1450,10 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen) ...@@ -1447,8 +1450,10 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen)
rc = tipc_msg_build(hdr, m, 0, dlen, mtu, &pkts); rc = tipc_msg_build(hdr, m, 0, dlen, mtu, &pkts);
if (unlikely(rc != dlen)) if (unlikely(rc != dlen))
return rc; return rc;
if (unlikely(syn && !tipc_msg_skb_clone(&pkts, &sk->sk_write_queue))) if (unlikely(syn && !tipc_msg_skb_clone(&pkts, &sk->sk_write_queue))) {
__skb_queue_purge(&pkts);
return -ENOMEM; return -ENOMEM;
}
trace_tipc_sk_sendmsg(sk, skb_peek(&pkts), TIPC_DUMP_SK_SNDQ, " "); trace_tipc_sk_sendmsg(sk, skb_peek(&pkts), TIPC_DUMP_SK_SNDQ, " ");
rc = tipc_node_xmit(net, &pkts, dnode, tsk->portid); rc = tipc_node_xmit(net, &pkts, dnode, tsk->portid);
...@@ -2757,6 +2762,7 @@ static void tipc_sk_timeout(struct timer_list *t) ...@@ -2757,6 +2762,7 @@ static void tipc_sk_timeout(struct timer_list *t)
if (sock_owned_by_user(sk)) { if (sock_owned_by_user(sk)) {
sk_reset_timer(sk, &sk->sk_timer, jiffies + HZ / 20); sk_reset_timer(sk, &sk->sk_timer, jiffies + HZ / 20);
bh_unlock_sock(sk); bh_unlock_sock(sk);
sock_put(sk);
return; return;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment