Skip to content

Commit 6f00089

Browse files
Parthasarathy Bhuvaragandavem330
authored andcommitted
tipc: remove SS_DISCONNECTING state
In this commit, we replace the references to SS_DISCONNECTING with the combination of sk_state TIPC_DISCONNECTING and flags set in sk_shutdown. We introduce a new function _tipc_shutdown(), which provides the common code required by tipc_release() and tipc_shutdown(). Signed-off-by: Parthasarathy Bhuvaragan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9fd4b07 commit 6f00089

File tree

1 file changed

+52
-80
lines changed

1 file changed

+52
-80
lines changed

net/tipc/socket.c

Lines changed: 52 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
442442
}
443443
msg_set_origport(msg, tsk->portid);
444444
setup_timer(&sk->sk_timer, tipc_sk_timeout, (unsigned long)tsk);
445+
sk->sk_shutdown = 0;
445446
sk->sk_backlog_rcv = tipc_backlog_rcv;
446447
sk->sk_rcvbuf = sysctl_tipc_rmem[1];
447448
sk->sk_data_ready = tipc_data_ready;
@@ -470,6 +471,44 @@ static void tipc_sk_callback(struct rcu_head *head)
470471
sock_put(&tsk->sk);
471472
}
472473

474+
/* Caller should hold socket lock for the socket. */
475+
static void __tipc_shutdown(struct socket *sock, int error)
476+
{
477+
struct sock *sk = sock->sk;
478+
struct tipc_sock *tsk = tipc_sk(sk);
479+
struct net *net = sock_net(sk);
480+
u32 dnode = tsk_peer_node(tsk);
481+
struct sk_buff *skb;
482+
483+
/* Reject all unreceived messages, except on an active connection
484+
* (which disconnects locally & sends a 'FIN+' to peer).
485+
*/
486+
while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) {
487+
if (TIPC_SKB_CB(skb)->bytes_read) {
488+
kfree_skb(skb);
489+
} else {
490+
if (!tipc_sk_type_connectionless(sk) &&
491+
sk->sk_state != TIPC_DISCONNECTING) {
492+
tipc_set_sk_state(sk, TIPC_DISCONNECTING);
493+
tipc_node_remove_conn(net, dnode, tsk->portid);
494+
}
495+
tipc_sk_respond(sk, skb, error);
496+
}
497+
}
498+
if (sk->sk_state != TIPC_DISCONNECTING) {
499+
skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
500+
TIPC_CONN_MSG, SHORT_H_SIZE, 0, dnode,
501+
tsk_own_node(tsk), tsk_peer_port(tsk),
502+
tsk->portid, error);
503+
if (skb)
504+
tipc_node_xmit_skb(net, skb, dnode, tsk->portid);
505+
if (!tipc_sk_type_connectionless(sk)) {
506+
tipc_node_remove_conn(net, dnode, tsk->portid);
507+
tipc_set_sk_state(sk, TIPC_DISCONNECTING);
508+
}
509+
}
510+
}
511+
473512
/**
474513
* tipc_release - destroy a TIPC socket
475514
* @sock: socket to destroy
@@ -489,10 +528,7 @@ static void tipc_sk_callback(struct rcu_head *head)
489528
static int tipc_release(struct socket *sock)
490529
{
491530
struct sock *sk = sock->sk;
492-
struct net *net;
493531
struct tipc_sock *tsk;
494-
struct sk_buff *skb;
495-
u32 dnode;
496532

497533
/*
498534
* Exit if socket isn't fully initialized (occurs when a failed accept()
@@ -501,46 +537,16 @@ static int tipc_release(struct socket *sock)
501537
if (sk == NULL)
502538
return 0;
503539

504-
net = sock_net(sk);
505540
tsk = tipc_sk(sk);
506541
lock_sock(sk);
507542

508-
/*
509-
* Reject all unreceived messages, except on an active connection
510-
* (which disconnects locally & sends a 'FIN+' to peer)
511-
*/
512-
dnode = tsk_peer_node(tsk);
513-
while (sock->state != SS_DISCONNECTING) {
514-
skb = __skb_dequeue(&sk->sk_receive_queue);
515-
if (skb == NULL)
516-
break;
517-
if (TIPC_SKB_CB(skb)->bytes_read)
518-
kfree_skb(skb);
519-
else {
520-
if ((sock->state == SS_CONNECTING) ||
521-
(sock->state == SS_CONNECTED)) {
522-
sock->state = SS_DISCONNECTING;
523-
tipc_node_remove_conn(net, dnode, tsk->portid);
524-
}
525-
tipc_sk_respond(sk, skb, TIPC_ERR_NO_PORT);
526-
}
527-
}
528-
543+
__tipc_shutdown(sock, TIPC_ERR_NO_PORT);
544+
sk->sk_shutdown = SHUTDOWN_MASK;
529545
tipc_sk_withdraw(tsk, 0, NULL);
530546
sk_stop_timer(sk, &sk->sk_timer);
531547
tipc_sk_remove(tsk);
532-
if (tipc_sk_connected(sk)) {
533-
skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
534-
TIPC_CONN_MSG, SHORT_H_SIZE, 0, dnode,
535-
tsk_own_node(tsk), tsk_peer_port(tsk),
536-
tsk->portid, TIPC_ERR_NO_PORT);
537-
if (skb)
538-
tipc_node_xmit_skb(net, skb, dnode, tsk->portid);
539-
tipc_node_remove_conn(net, dnode, tsk->portid);
540-
}
541548

542549
/* Reject any messages that accumulated in backlog queue */
543-
sock->state = SS_DISCONNECTING;
544550
release_sock(sk);
545551

546552
call_rcu(&tsk->rcu, tipc_sk_callback);
@@ -678,6 +684,11 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
678684

679685
sock_poll_wait(file, sk_sleep(sk), wait);
680686

687+
if (sk->sk_shutdown & RCV_SHUTDOWN)
688+
mask |= POLLRDHUP | POLLIN | POLLRDNORM;
689+
if (sk->sk_shutdown == SHUTDOWN_MASK)
690+
mask |= POLLHUP;
691+
681692
switch ((int)sock->state) {
682693
case SS_CONNECTED:
683694
if (!tsk->link_cong && !tsk_conn_cong(tsk))
@@ -687,9 +698,6 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
687698
if (!skb_queue_empty(&sk->sk_receive_queue))
688699
mask |= (POLLIN | POLLRDNORM);
689700
break;
690-
case SS_DISCONNECTING:
691-
mask = (POLLIN | POLLRDNORM | POLLHUP);
692-
break;
693701
default:
694702
switch (sk->sk_state) {
695703
case TIPC_OPEN:
@@ -882,7 +890,7 @@ static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p)
882890
int err = sock_error(sk);
883891
if (err)
884892
return err;
885-
if (sock->state == SS_DISCONNECTING)
893+
if (sk->sk_shutdown & SEND_SHUTDOWN)
886894
return -EPIPE;
887895
if (!*timeo_p)
888896
return -EAGAIN;
@@ -1335,7 +1343,7 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)
13351343
for (;;) {
13361344
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
13371345
if (timeo && skb_queue_empty(&sk->sk_receive_queue)) {
1338-
if (sock->state == SS_DISCONNECTING) {
1346+
if (sk->sk_shutdown & RCV_SHUTDOWN) {
13391347
err = -ENOTCONN;
13401348
break;
13411349
}
@@ -1676,9 +1684,6 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
16761684
/* 'ACK-' message is neither accepted nor rejected: */
16771685
msg_set_dest_droppable(hdr, 1);
16781686
return false;
1679-
1680-
case SS_DISCONNECTING:
1681-
break;
16821687
}
16831688

16841689
switch (sk->sk_state) {
@@ -2191,57 +2196,24 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
21912196
static int tipc_shutdown(struct socket *sock, int how)
21922197
{
21932198
struct sock *sk = sock->sk;
2194-
struct net *net = sock_net(sk);
2195-
struct tipc_sock *tsk = tipc_sk(sk);
2196-
struct sk_buff *skb;
2197-
u32 dnode = tsk_peer_node(tsk);
2198-
u32 dport = tsk_peer_port(tsk);
2199-
u32 onode = tipc_own_addr(net);
2200-
u32 oport = tsk->portid;
22012199
int res;
22022200

22032201
if (how != SHUT_RDWR)
22042202
return -EINVAL;
22052203

22062204
lock_sock(sk);
22072205

2208-
if (sock->state == SS_CONNECTING || sock->state == SS_CONNECTED) {
2209-
2210-
restart:
2211-
dnode = tsk_peer_node(tsk);
2212-
2213-
/* Disconnect and send a 'FIN+' or 'FIN-' message to peer */
2214-
skb = __skb_dequeue(&sk->sk_receive_queue);
2215-
if (skb) {
2216-
if (TIPC_SKB_CB(skb)->bytes_read) {
2217-
kfree_skb(skb);
2218-
goto restart;
2219-
}
2220-
tipc_sk_respond(sk, skb, TIPC_CONN_SHUTDOWN);
2221-
} else {
2222-
skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
2223-
TIPC_CONN_MSG, SHORT_H_SIZE,
2224-
0, dnode, onode, dport, oport,
2225-
TIPC_CONN_SHUTDOWN);
2226-
if (skb)
2227-
tipc_node_xmit_skb(net, skb, dnode, tsk->portid);
2228-
}
2229-
tipc_set_sk_state(sk, TIPC_DISCONNECTING);
2230-
tipc_node_remove_conn(net, dnode, tsk->portid);
2231-
}
2232-
2233-
switch (sk->sk_state) {
2234-
case TIPC_DISCONNECTING:
2206+
__tipc_shutdown(sock, TIPC_CONN_SHUTDOWN);
2207+
sk->sk_shutdown = SEND_SHUTDOWN;
22352208

2209+
if (sk->sk_state == TIPC_DISCONNECTING) {
22362210
/* Discard any unreceived messages */
22372211
__skb_queue_purge(&sk->sk_receive_queue);
22382212

22392213
/* Wake up anyone sleeping in poll */
22402214
sk->sk_state_change(sk);
22412215
res = 0;
2242-
break;
2243-
2244-
default:
2216+
} else {
22452217
res = -ENOTCONN;
22462218
}
22472219

0 commit comments

Comments
 (0)