diff options
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 108 |
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); | |||
110 | static void tipc_sock_destruct(struct sock *sk); | 110 | static void tipc_sock_destruct(struct sock *sk); |
111 | static int tipc_release(struct socket *sock); | 111 | static int tipc_release(struct socket *sock); |
112 | static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags); | 112 | static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags); |
113 | static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p); | ||
114 | static void tipc_sk_timeout(unsigned long data); | 113 | static void tipc_sk_timeout(unsigned long data); |
115 | static int tipc_sk_publish(struct tipc_sock *tsk, uint scope, | 114 | static 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 | ||
336 | static 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 | ||
833 | static 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 | ||
988 | static 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); |