aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r--net/tipc/socket.c49
1 files changed, 31 insertions, 18 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 25ecf1201527..0a2eac309177 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -709,41 +709,43 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
709 poll_table *wait) 709 poll_table *wait)
710{ 710{
711 struct sock *sk = sock->sk; 711 struct sock *sk = sock->sk;
712 struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
712 struct tipc_sock *tsk = tipc_sk(sk); 713 struct tipc_sock *tsk = tipc_sk(sk);
713 struct tipc_group *grp = tsk->group; 714 struct tipc_group *grp = tsk->group;
714 u32 mask = 0; 715 u32 revents = 0;
715 716
716 sock_poll_wait(file, sk_sleep(sk), wait); 717 sock_poll_wait(file, sk_sleep(sk), wait);
717 718
718 if (sk->sk_shutdown & RCV_SHUTDOWN) 719 if (sk->sk_shutdown & RCV_SHUTDOWN)
719 mask |= POLLRDHUP | POLLIN | POLLRDNORM; 720 revents |= POLLRDHUP | POLLIN | POLLRDNORM;
720 if (sk->sk_shutdown == SHUTDOWN_MASK) 721 if (sk->sk_shutdown == SHUTDOWN_MASK)
721 mask |= POLLHUP; 722 revents |= POLLHUP;
722 723
723 switch (sk->sk_state) { 724 switch (sk->sk_state) {
724 case TIPC_ESTABLISHED: 725 case TIPC_ESTABLISHED:
725 if (!tsk->cong_link_cnt && !tsk_conn_cong(tsk)) 726 if (!tsk->cong_link_cnt && !tsk_conn_cong(tsk))
726 mask |= POLLOUT; 727 revents |= POLLOUT;
727 /* fall thru' */ 728 /* fall thru' */
728 case TIPC_LISTEN: 729 case TIPC_LISTEN:
729 case TIPC_CONNECTING: 730 case TIPC_CONNECTING:
730 if (!skb_queue_empty(&sk->sk_receive_queue)) 731 if (skb)
731 mask |= (POLLIN | POLLRDNORM); 732 revents |= POLLIN | POLLRDNORM;
732 break; 733 break;
733 case TIPC_OPEN: 734 case TIPC_OPEN:
734 if (!grp || tipc_group_size(grp)) 735 if (!grp || tipc_group_size(grp))
735 if (!tsk->cong_link_cnt) 736 if (!tsk->cong_link_cnt)
736 mask |= POLLOUT; 737 revents |= POLLOUT;
737 if (tipc_sk_type_connectionless(sk) && 738 if (!tipc_sk_type_connectionless(sk))
738 (!skb_queue_empty(&sk->sk_receive_queue))) 739 break;
739 mask |= (POLLIN | POLLRDNORM); 740 if (!skb)
741 break;
742 revents |= POLLIN | POLLRDNORM;
740 break; 743 break;
741 case TIPC_DISCONNECTING: 744 case TIPC_DISCONNECTING:
742 mask = (POLLIN | POLLRDNORM | POLLHUP); 745 revents = POLLIN | POLLRDNORM | POLLHUP;
743 break; 746 break;
744 } 747 }
745 748 return revents;
746 return mask;
747} 749}
748 750
749/** 751/**
@@ -1415,11 +1417,12 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m,
1415 size_t buflen, int flags) 1417 size_t buflen, int flags)
1416{ 1418{
1417 struct sock *sk = sock->sk; 1419 struct sock *sk = sock->sk;
1418 struct tipc_sock *tsk = tipc_sk(sk);
1419 struct sk_buff *skb;
1420 struct tipc_msg *hdr;
1421 bool connected = !tipc_sk_type_connectionless(sk); 1420 bool connected = !tipc_sk_type_connectionless(sk);
1421 struct tipc_sock *tsk = tipc_sk(sk);
1422 int rc, err, hlen, dlen, copy; 1422 int rc, err, hlen, dlen, copy;
1423 struct tipc_msg *hdr;
1424 struct sk_buff *skb;
1425 bool grp_evt;
1423 long timeout; 1426 long timeout;
1424 1427
1425 /* Catch invalid receive requests */ 1428 /* Catch invalid receive requests */
@@ -1443,6 +1446,7 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m,
1443 dlen = msg_data_sz(hdr); 1446 dlen = msg_data_sz(hdr);
1444 hlen = msg_hdr_sz(hdr); 1447 hlen = msg_hdr_sz(hdr);
1445 err = msg_errcode(hdr); 1448 err = msg_errcode(hdr);
1449 grp_evt = msg_is_grp_evt(hdr);
1446 if (likely(dlen || err)) 1450 if (likely(dlen || err))
1447 break; 1451 break;
1448 tsk_advance_rx_queue(sk); 1452 tsk_advance_rx_queue(sk);
@@ -1469,11 +1473,20 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m,
1469 if (unlikely(rc)) 1473 if (unlikely(rc))
1470 goto exit; 1474 goto exit;
1471 1475
1476 /* Mark message as group event if applicable */
1477 if (unlikely(grp_evt)) {
1478 if (msg_grp_evt(hdr) == TIPC_WITHDRAWN)
1479 m->msg_flags |= MSG_EOR;
1480 m->msg_flags |= MSG_OOB;
1481 copy = 0;
1482 }
1483
1472 /* Caption of data or error code/rejected data was successful */ 1484 /* Caption of data or error code/rejected data was successful */
1473 if (unlikely(flags & MSG_PEEK)) 1485 if (unlikely(flags & MSG_PEEK))
1474 goto exit; 1486 goto exit;
1475 1487
1476 tsk_advance_rx_queue(sk); 1488 tsk_advance_rx_queue(sk);
1489
1477 if (likely(!connected)) 1490 if (likely(!connected))
1478 goto exit; 1491 goto exit;
1479 1492
@@ -1648,10 +1661,10 @@ static void tipc_sk_proto_rcv(struct sock *sk,
1648 sk->sk_write_space(sk); 1661 sk->sk_write_space(sk);
1649 break; 1662 break;
1650 case GROUP_PROTOCOL: 1663 case GROUP_PROTOCOL:
1651 tipc_group_proto_rcv(grp, hdr, xmitq); 1664 tipc_group_proto_rcv(grp, hdr, inputq, xmitq);
1652 break; 1665 break;
1653 case TOP_SRV: 1666 case TOP_SRV:
1654 tipc_group_member_evt(tsk->group, skb, xmitq); 1667 tipc_group_member_evt(tsk->group, skb, inputq, xmitq);
1655 skb = NULL; 1668 skb = NULL;
1656 break; 1669 break;
1657 default: 1670 default: