aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/tipc/socket.c80
1 files changed, 42 insertions, 38 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index c4803101fbdf..eab17eb9ca1d 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -55,9 +55,6 @@ struct tipc_sock {
55#define tipc_sk(sk) ((struct tipc_sock *)(sk)) 55#define tipc_sk(sk) ((struct tipc_sock *)(sk))
56#define tipc_sk_port(sk) (tipc_sk(sk)->p) 56#define tipc_sk_port(sk) (tipc_sk(sk)->p)
57 57
58#define tipc_rx_ready(sock) (!skb_queue_empty(&sock->sk->sk_receive_queue) || \
59 (sock->state == SS_DISCONNECTING))
60
61static int backlog_rcv(struct sock *sk, struct sk_buff *skb); 58static int backlog_rcv(struct sock *sk, struct sk_buff *skb);
62static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf); 59static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf);
63static void wakeupdispatch(struct tipc_port *tport); 60static void wakeupdispatch(struct tipc_port *tport);
@@ -994,6 +991,37 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
994 return 0; 991 return 0;
995} 992}
996 993
994static int tipc_wait_for_rcvmsg(struct socket *sock, long timeo)
995{
996 struct sock *sk = sock->sk;
997 DEFINE_WAIT(wait);
998 int err;
999
1000 for (;;) {
1001 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
1002 if (skb_queue_empty(&sk->sk_receive_queue)) {
1003 if (sock->state == SS_DISCONNECTING) {
1004 err = -ENOTCONN;
1005 break;
1006 }
1007 release_sock(sk);
1008 timeo = schedule_timeout(timeo);
1009 lock_sock(sk);
1010 }
1011 err = 0;
1012 if (!skb_queue_empty(&sk->sk_receive_queue))
1013 break;
1014 err = sock_intr_errno(timeo);
1015 if (signal_pending(current))
1016 break;
1017 err = -EAGAIN;
1018 if (!timeo)
1019 break;
1020 }
1021 finish_wait(sk_sleep(sk), &wait);
1022 return err;
1023}
1024
997/** 1025/**
998 * recv_msg - receive packet-oriented message 1026 * recv_msg - receive packet-oriented message
999 * @iocb: (unused) 1027 * @iocb: (unused)
@@ -1013,7 +1041,7 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
1013 struct tipc_port *tport = tipc_sk_port(sk); 1041 struct tipc_port *tport = tipc_sk_port(sk);
1014 struct sk_buff *buf; 1042 struct sk_buff *buf;
1015 struct tipc_msg *msg; 1043 struct tipc_msg *msg;
1016 long timeout; 1044 long timeo;
1017 unsigned int sz; 1045 unsigned int sz;
1018 u32 err; 1046 u32 err;
1019 int res; 1047 int res;
@@ -1029,25 +1057,13 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
1029 goto exit; 1057 goto exit;
1030 } 1058 }
1031 1059
1032 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); 1060 timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
1033restart: 1061restart:
1034 1062
1035 /* Look for a message in receive queue; wait if necessary */ 1063 /* Look for a message in receive queue; wait if necessary */
1036 while (skb_queue_empty(&sk->sk_receive_queue)) { 1064 res = tipc_wait_for_rcvmsg(sock, timeo);
1037 if (sock->state == SS_DISCONNECTING) { 1065 if (res)
1038 res = -ENOTCONN; 1066 goto exit;
1039 goto exit;
1040 }
1041 if (timeout <= 0L) {
1042 res = timeout ? timeout : -EWOULDBLOCK;
1043 goto exit;
1044 }
1045 release_sock(sk);
1046 timeout = wait_event_interruptible_timeout(*sk_sleep(sk),
1047 tipc_rx_ready(sock),
1048 timeout);
1049 lock_sock(sk);
1050 }
1051 1067
1052 /* Look at first message in receive queue */ 1068 /* Look at first message in receive queue */
1053 buf = skb_peek(&sk->sk_receive_queue); 1069 buf = skb_peek(&sk->sk_receive_queue);
@@ -1119,7 +1135,7 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
1119 struct tipc_port *tport = tipc_sk_port(sk); 1135 struct tipc_port *tport = tipc_sk_port(sk);
1120 struct sk_buff *buf; 1136 struct sk_buff *buf;
1121 struct tipc_msg *msg; 1137 struct tipc_msg *msg;
1122 long timeout; 1138 long timeo;
1123 unsigned int sz; 1139 unsigned int sz;
1124 int sz_to_copy, target, needed; 1140 int sz_to_copy, target, needed;
1125 int sz_copied = 0; 1141 int sz_copied = 0;
@@ -1132,31 +1148,19 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
1132 1148
1133 lock_sock(sk); 1149 lock_sock(sk);
1134 1150
1135 if (unlikely((sock->state == SS_UNCONNECTED))) { 1151 if (unlikely(sock->state == SS_UNCONNECTED)) {
1136 res = -ENOTCONN; 1152 res = -ENOTCONN;
1137 goto exit; 1153 goto exit;
1138 } 1154 }
1139 1155
1140 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); 1156 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
1141 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); 1157 timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
1142 1158
1143restart: 1159restart:
1144 /* Look for a message in receive queue; wait if necessary */ 1160 /* Look for a message in receive queue; wait if necessary */
1145 while (skb_queue_empty(&sk->sk_receive_queue)) { 1161 res = tipc_wait_for_rcvmsg(sock, timeo);
1146 if (sock->state == SS_DISCONNECTING) { 1162 if (res)
1147 res = -ENOTCONN; 1163 goto exit;
1148 goto exit;
1149 }
1150 if (timeout <= 0L) {
1151 res = timeout ? timeout : -EWOULDBLOCK;
1152 goto exit;
1153 }
1154 release_sock(sk);
1155 timeout = wait_event_interruptible_timeout(*sk_sleep(sk),
1156 tipc_rx_ready(sock),
1157 timeout);
1158 lock_sock(sk);
1159 }
1160 1164
1161 /* Look at first message in receive queue */ 1165 /* Look at first message in receive queue */
1162 buf = skb_peek(&sk->sk_receive_queue); 1166 buf = skb_peek(&sk->sk_receive_queue);