aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
authorYing Xue <ying.xue@windriver.com>2015-01-09 02:27:02 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-12 16:24:32 -0500
commitf2f2a96a20d52d65aa79bd4019af43bbfb0e1528 (patch)
tree38c93810ecd5f8783e186dad1d43fd27aeb02aeb /net/tipc/socket.c
parent859fc7c0cedca0f84dac471fa31e9512259e1ecd (diff)
tipc: feed tipc sock pointer to tipc_sk_timeout routine
In order to make tipc socket table aware of namespace, a networking namespace instance must be passed to tipc_sk_lookup(), allowing it to look up tipc socket instance with a given port ID from a concrete socket table. However, as now tipc_sk_timeout() only has one port ID parameter and is not namespace aware, it's unable to obtain a correct socket instance through tipc_sk_lookup() just with a port ID, especially after namespace is completely supported. If port ID is replaced with socket instance as tipc_sk_timeout()'s parameter, it's unnecessary to look up socket table. But as the timer handler - tipc_sk_timeout() is run asynchronously, socket reference must be held before its timer is launched, and must be carefully checked to identify whether the socket reference needs to be put or not when its timer is terminated. Signed-off-by: Ying Xue <ying.xue@windriver.com> Tested-by: Tero Aho <Tero.Aho@coriant.com> Reviewed-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r--net/tipc/socket.c33
1 files changed, 16 insertions, 17 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index e16197eb7b9f..c58f66be7e18 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -110,7 +110,7 @@ static void tipc_write_space(struct sock *sk);
110static int tipc_release(struct socket *sock); 110static int tipc_release(struct socket *sock);
111static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags); 111static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags);
112static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p); 112static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p);
113static void tipc_sk_timeout(unsigned long portid); 113static void tipc_sk_timeout(unsigned long data);
114static int tipc_sk_publish(struct tipc_sock *tsk, uint scope, 114static int tipc_sk_publish(struct tipc_sock *tsk, uint scope,
115 struct tipc_name_seq const *seq); 115 struct tipc_name_seq const *seq);
116static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope, 116static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope,
@@ -361,7 +361,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
361 return -EINVAL; 361 return -EINVAL;
362 } 362 }
363 msg_set_origport(msg, tsk->portid); 363 msg_set_origport(msg, tsk->portid);
364 setup_timer(&tsk->timer, tipc_sk_timeout, tsk->portid); 364 setup_timer(&tsk->timer, tipc_sk_timeout, (unsigned long)tsk);
365 sk->sk_backlog_rcv = tipc_backlog_rcv; 365 sk->sk_backlog_rcv = tipc_backlog_rcv;
366 sk->sk_rcvbuf = sysctl_tipc_rmem[1]; 366 sk->sk_rcvbuf = sysctl_tipc_rmem[1];
367 sk->sk_data_ready = tipc_data_ready; 367 sk->sk_data_ready = tipc_data_ready;
@@ -475,7 +475,7 @@ static int tipc_release(struct socket *sock)
475 struct sock *sk = sock->sk; 475 struct sock *sk = sock->sk;
476 struct tipc_sock *tsk; 476 struct tipc_sock *tsk;
477 struct sk_buff *skb; 477 struct sk_buff *skb;
478 u32 dnode; 478 u32 dnode, probing_state;
479 479
480 /* 480 /*
481 * Exit if socket isn't fully initialized (occurs when a failed accept() 481 * Exit if socket isn't fully initialized (occurs when a failed accept()
@@ -511,7 +511,9 @@ static int tipc_release(struct socket *sock)
511 } 511 }
512 512
513 tipc_sk_withdraw(tsk, 0, NULL); 513 tipc_sk_withdraw(tsk, 0, NULL);
514 del_timer_sync(&tsk->timer); 514 probing_state = tsk->probing_state;
515 if (del_timer_sync(&tsk->timer) && probing_state != TIPC_CONN_PROBING)
516 sock_put(sk);
515 tipc_sk_remove(tsk); 517 tipc_sk_remove(tsk);
516 if (tsk->connected) { 518 if (tsk->connected) {
517 skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG, 519 skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
@@ -1141,7 +1143,8 @@ static void tipc_sk_finish_conn(struct tipc_sock *tsk, u32 peer_port,
1141 tsk->probing_intv = CONN_PROBING_INTERVAL; 1143 tsk->probing_intv = CONN_PROBING_INTERVAL;
1142 tsk->probing_state = TIPC_CONN_OK; 1144 tsk->probing_state = TIPC_CONN_OK;
1143 tsk->connected = 1; 1145 tsk->connected = 1;
1144 mod_timer(&tsk->timer, jiffies + tsk->probing_intv); 1146 if (!mod_timer(&tsk->timer, jiffies + tsk->probing_intv))
1147 sock_hold(&tsk->sk);
1145 tipc_node_add_conn(peer_node, tsk->portid, peer_port); 1148 tipc_node_add_conn(peer_node, tsk->portid, peer_port);
1146 tsk->max_pkt = tipc_node_get_mtu(peer_node, tsk->portid); 1149 tsk->max_pkt = tipc_node_get_mtu(peer_node, tsk->portid);
1147} 1150}
@@ -2096,18 +2099,13 @@ restart:
2096 return res; 2099 return res;
2097} 2100}
2098 2101
2099static void tipc_sk_timeout(unsigned long portid) 2102static void tipc_sk_timeout(unsigned long data)
2100{ 2103{
2101 struct tipc_sock *tsk; 2104 struct tipc_sock *tsk = (struct tipc_sock *)data;
2102 struct sock *sk; 2105 struct sock *sk = &tsk->sk;
2103 struct sk_buff *skb = NULL; 2106 struct sk_buff *skb = NULL;
2104 u32 peer_port, peer_node; 2107 u32 peer_port, peer_node;
2105 2108
2106 tsk = tipc_sk_lookup(portid);
2107 if (!tsk)
2108 return;
2109
2110 sk = &tsk->sk;
2111 bh_lock_sock(sk); 2109 bh_lock_sock(sk);
2112 if (!tsk->connected) { 2110 if (!tsk->connected) {
2113 bh_unlock_sock(sk); 2111 bh_unlock_sock(sk);
@@ -2120,18 +2118,19 @@ static void tipc_sk_timeout(unsigned long portid)
2120 /* Previous probe not answered -> self abort */ 2118 /* Previous probe not answered -> self abort */
2121 skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG, 2119 skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
2122 SHORT_H_SIZE, 0, tipc_own_addr, 2120 SHORT_H_SIZE, 0, tipc_own_addr,
2123 peer_node, portid, peer_port, 2121 peer_node, tsk->portid, peer_port,
2124 TIPC_ERR_NO_PORT); 2122 TIPC_ERR_NO_PORT);
2125 } else { 2123 } else {
2126 skb = tipc_msg_create(CONN_MANAGER, CONN_PROBE, INT_H_SIZE, 2124 skb = tipc_msg_create(CONN_MANAGER, CONN_PROBE, INT_H_SIZE,
2127 0, peer_node, tipc_own_addr, 2125 0, peer_node, tipc_own_addr,
2128 peer_port, portid, TIPC_OK); 2126 peer_port, tsk->portid, TIPC_OK);
2129 tsk->probing_state = TIPC_CONN_PROBING; 2127 tsk->probing_state = TIPC_CONN_PROBING;
2130 mod_timer(&tsk->timer, jiffies + tsk->probing_intv); 2128 if (!mod_timer(&tsk->timer, jiffies + tsk->probing_intv))
2129 sock_hold(sk);
2131 } 2130 }
2132 bh_unlock_sock(sk); 2131 bh_unlock_sock(sk);
2133 if (skb) 2132 if (skb)
2134 tipc_link_xmit_skb(skb, peer_node, portid); 2133 tipc_link_xmit_skb(skb, peer_node, tsk->portid);
2135exit: 2134exit:
2136 sock_put(sk); 2135 sock_put(sk);
2137} 2136}