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.c108
1 files changed, 49 insertions, 59 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 800caaa699a1..f27462eeccbe 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -110,7 +110,6 @@ static void tipc_write_space(struct sock *sk);
110static void tipc_sock_destruct(struct sock *sk); 110static void tipc_sock_destruct(struct sock *sk);
111static int tipc_release(struct socket *sock); 111static int tipc_release(struct socket *sock);
112static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags); 112static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags);
113static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p);
114static void tipc_sk_timeout(unsigned long data); 113static void tipc_sk_timeout(unsigned long data);
115static int tipc_sk_publish(struct tipc_sock *tsk, uint scope, 114static int tipc_sk_publish(struct tipc_sock *tsk, uint scope,
116 struct tipc_name_seq const *seq); 115 struct tipc_name_seq const *seq);
@@ -334,6 +333,49 @@ static int tipc_set_sk_state(struct sock *sk, int state)
334 return res; 333 return res;
335} 334}
336 335
336static int tipc_sk_sock_err(struct socket *sock, long *timeout)
337{
338 struct sock *sk = sock->sk;
339 int err = sock_error(sk);
340 int typ = sock->type;
341
342 if (err)
343 return err;
344 if (typ == SOCK_STREAM || typ == SOCK_SEQPACKET) {
345 if (sk->sk_state == TIPC_DISCONNECTING)
346 return -EPIPE;
347 else if (!tipc_sk_connected(sk))
348 return -ENOTCONN;
349 }
350 if (!*timeout)
351 return -EAGAIN;
352 if (signal_pending(current))
353 return sock_intr_errno(*timeout);
354
355 return 0;
356}
357
358#define tipc_wait_for_cond(sock_, timeout_, condition_) \
359({ \
360 int rc_ = 0; \
361 int done_ = 0; \
362 \
363 while (!(condition_) && !done_) { \
364 struct sock *sk_ = sock->sk; \
365 DEFINE_WAIT_FUNC(wait_, woken_wake_function); \
366 \
367 rc_ = tipc_sk_sock_err(sock_, timeout_); \
368 if (rc_) \
369 break; \
370 prepare_to_wait(sk_sleep(sk_), &wait_, \
371 TASK_INTERRUPTIBLE); \
372 done_ = sk_wait_event(sk_, timeout_, \
373 (condition_), &wait_); \
374 remove_wait_queue(sk_sleep(sk_), &wait_); \
375 } \
376 rc_; \
377})
378
337/** 379/**
338 * tipc_sk_create - create a TIPC socket 380 * tipc_sk_create - create a TIPC socket
339 * @net: network namespace (must be default network) 381 * @net: network namespace (must be default network)
@@ -721,7 +763,7 @@ new_mtu:
721 763
722 if (rc == -ELINKCONG) { 764 if (rc == -ELINKCONG) {
723 tsk->link_cong = 1; 765 tsk->link_cong = 1;
724 rc = tipc_wait_for_sndmsg(sock, &timeo); 766 rc = tipc_wait_for_cond(sock, &timeo, !tsk->link_cong);
725 if (!rc) 767 if (!rc)
726 continue; 768 continue;
727 } 769 }
@@ -830,31 +872,6 @@ exit:
830 kfree_skb(skb); 872 kfree_skb(skb);
831} 873}
832 874
833static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p)
834{
835 DEFINE_WAIT_FUNC(wait, woken_wake_function);
836 struct sock *sk = sock->sk;
837 struct tipc_sock *tsk = tipc_sk(sk);
838 int done;
839
840 do {
841 int err = sock_error(sk);
842 if (err)
843 return err;
844 if (sk->sk_shutdown & SEND_SHUTDOWN)
845 return -EPIPE;
846 if (!*timeo_p)
847 return -EAGAIN;
848 if (signal_pending(current))
849 return sock_intr_errno(*timeo_p);
850
851 add_wait_queue(sk_sleep(sk), &wait);
852 done = sk_wait_event(sk, timeo_p, !tsk->link_cong, &wait);
853 remove_wait_queue(sk_sleep(sk), &wait);
854 } while (!done);
855 return 0;
856}
857
858/** 875/**
859 * tipc_sendmsg - send message in connectionless manner 876 * tipc_sendmsg - send message in connectionless manner
860 * @sock: socket structure 877 * @sock: socket structure
@@ -970,7 +987,7 @@ new_mtu:
970 } 987 }
971 if (rc == -ELINKCONG) { 988 if (rc == -ELINKCONG) {
972 tsk->link_cong = 1; 989 tsk->link_cong = 1;
973 rc = tipc_wait_for_sndmsg(sock, &timeo); 990 rc = tipc_wait_for_cond(sock, &timeo, !tsk->link_cong);
974 if (!rc) 991 if (!rc)
975 continue; 992 continue;
976 } 993 }
@@ -985,36 +1002,6 @@ new_mtu:
985 return rc; 1002 return rc;
986} 1003}
987 1004
988static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p)
989{
990 DEFINE_WAIT_FUNC(wait, woken_wake_function);
991 struct sock *sk = sock->sk;
992 struct tipc_sock *tsk = tipc_sk(sk);
993 int done;
994
995 do {
996 int err = sock_error(sk);
997 if (err)
998 return err;
999 if (sk->sk_state == TIPC_DISCONNECTING)
1000 return -EPIPE;
1001 else if (!tipc_sk_connected(sk))
1002 return -ENOTCONN;
1003 if (!*timeo_p)
1004 return -EAGAIN;
1005 if (signal_pending(current))
1006 return sock_intr_errno(*timeo_p);
1007
1008 add_wait_queue(sk_sleep(sk), &wait);
1009 done = sk_wait_event(sk, timeo_p,
1010 (!tsk->link_cong &&
1011 !tsk_conn_cong(tsk)) ||
1012 !tipc_sk_connected(sk), &wait);
1013 remove_wait_queue(sk_sleep(sk), &wait);
1014 } while (!done);
1015 return 0;
1016}
1017
1018/** 1005/**
1019 * tipc_send_stream - send stream-oriented data 1006 * tipc_send_stream - send stream-oriented data
1020 * @sock: socket structure 1007 * @sock: socket structure
@@ -1109,7 +1096,10 @@ next:
1109 1096
1110 tsk->link_cong = 1; 1097 tsk->link_cong = 1;
1111 } 1098 }
1112 rc = tipc_wait_for_sndpkt(sock, &timeo); 1099 rc = tipc_wait_for_cond(sock, &timeo,
1100 (!tsk->link_cong &&
1101 !tsk_conn_cong(tsk) &&
1102 tipc_sk_connected(sk)));
1113 } while (!rc); 1103 } while (!rc);
1114 1104
1115 __skb_queue_purge(&pktchain); 1105 __skb_queue_purge(&pktchain);