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.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 008f6fdf95c3..3e019737e4b3 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -567,6 +567,31 @@ static int dest_name_check(struct sockaddr_tipc *dest, struct msghdr *m)
567 return 0; 567 return 0;
568} 568}
569 569
570static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p)
571{
572 struct sock *sk = sock->sk;
573 struct tipc_port *tport = tipc_sk_port(sk);
574 DEFINE_WAIT(wait);
575 int done;
576
577 do {
578 int err = sock_error(sk);
579 if (err)
580 return err;
581 if (sock->state == SS_DISCONNECTING)
582 return -EPIPE;
583 if (!*timeo_p)
584 return -EAGAIN;
585 if (signal_pending(current))
586 return sock_intr_errno(*timeo_p);
587
588 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
589 done = sk_wait_event(sk, timeo_p, !tport->congested);
590 finish_wait(sk_sleep(sk), &wait);
591 } while (!done);
592 return 0;
593}
594
570/** 595/**
571 * send_msg - send message in connectionless manner 596 * send_msg - send message in connectionless manner
572 * @iocb: if NULL, indicates that socket lock is already held 597 * @iocb: if NULL, indicates that socket lock is already held
@@ -588,7 +613,7 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
588 struct tipc_port *tport = tipc_sk_port(sk); 613 struct tipc_port *tport = tipc_sk_port(sk);
589 struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name; 614 struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name;
590 int needs_conn; 615 int needs_conn;
591 long timeout_val; 616 long timeo;
592 int res = -EINVAL; 617 int res = -EINVAL;
593 618
594 if (unlikely(!dest)) 619 if (unlikely(!dest))
@@ -625,8 +650,7 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
625 reject_rx_queue(sk); 650 reject_rx_queue(sk);
626 } 651 }
627 652
628 timeout_val = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); 653 timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
629
630 do { 654 do {
631 if (dest->addrtype == TIPC_ADDR_NAME) { 655 if (dest->addrtype == TIPC_ADDR_NAME) {
632 res = dest_name_check(dest, m); 656 res = dest_name_check(dest, m);
@@ -660,14 +684,9 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
660 sock->state = SS_CONNECTING; 684 sock->state = SS_CONNECTING;
661 break; 685 break;
662 } 686 }
663 if (timeout_val <= 0L) { 687 res = tipc_wait_for_sndmsg(sock, &timeo);
664 res = timeout_val ? timeout_val : -EWOULDBLOCK; 688 if (res)
665 break; 689 break;
666 }
667 release_sock(sk);
668 timeout_val = wait_event_interruptible_timeout(*sk_sleep(sk),
669 !tport->congested, timeout_val);
670 lock_sock(sk);
671 } while (1); 690 } while (1);
672 691
673exit: 692exit: