aboutsummaryrefslogtreecommitdiffstats
path: root/net/llc/af_llc.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/llc/af_llc.c')
-rw-r--r--net/llc/af_llc.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 7e9cf3214b88..f536369cdb52 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -39,7 +39,6 @@ static struct proto_ops llc_ui_ops;
39 39
40static int llc_ui_wait_for_conn(struct sock *sk, long timeout); 40static int llc_ui_wait_for_conn(struct sock *sk, long timeout);
41static int llc_ui_wait_for_disc(struct sock *sk, long timeout); 41static int llc_ui_wait_for_disc(struct sock *sk, long timeout);
42static int llc_ui_wait_for_data(struct sock *sk, long timeout);
43static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout); 42static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout);
44 43
45#if 0 44#if 0
@@ -524,16 +523,19 @@ static int llc_ui_wait_for_conn(struct sock *sk, long timeout)
524 return timeout; 523 return timeout;
525} 524}
526 525
527static int llc_ui_wait_for_data(struct sock *sk, long timeout) 526static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout)
528{ 527{
529 DEFINE_WAIT(wait); 528 DEFINE_WAIT(wait);
530 int rc = 0; 529 struct llc_sock *llc = llc_sk(sk);
530 int rc;
531 531
532 while (1) { 532 while (1) {
533 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); 533 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
534 rc = 0;
534 if (sk_wait_event(sk, &timeout, 535 if (sk_wait_event(sk, &timeout,
535 (sk->sk_shutdown & RCV_SHUTDOWN) || 536 (sk->sk_shutdown & RCV_SHUTDOWN) ||
536 (!skb_queue_empty(&sk->sk_receive_queue)))) 537 (!llc_data_accept_state(llc->state) &&
538 !llc->p_flag)))
537 break; 539 break;
538 rc = -ERESTARTSYS; 540 rc = -ERESTARTSYS;
539 if (signal_pending(current)) 541 if (signal_pending(current))
@@ -541,34 +543,36 @@ static int llc_ui_wait_for_data(struct sock *sk, long timeout)
541 rc = -EAGAIN; 543 rc = -EAGAIN;
542 if (!timeout) 544 if (!timeout)
543 break; 545 break;
544 rc = 0;
545 } 546 }
546 finish_wait(sk->sk_sleep, &wait); 547 finish_wait(sk->sk_sleep, &wait);
547 return rc; 548 return rc;
548} 549}
549 550
550static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout) 551int llc_wait_data(struct sock *sk, long timeo)
551{ 552{
552 DEFINE_WAIT(wait);
553 struct llc_sock *llc = llc_sk(sk);
554 int rc; 553 int rc;
555 554
556 while (1) { 555 while (1) {
557 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); 556 /*
557 * POSIX 1003.1g mandates this order.
558 */
559 if (sk->sk_err) {
560 rc = sock_error(sk);
561 break;
562 }
558 rc = 0; 563 rc = 0;
559 if (sk_wait_event(sk, &timeout, 564 if (sk->sk_shutdown & RCV_SHUTDOWN)
560 (sk->sk_shutdown & RCV_SHUTDOWN) ||
561 (!llc_data_accept_state(llc->state) &&
562 !llc->p_flag)))
563 break; 565 break;
564 rc = -ERESTARTSYS; 566 rc = -EAGAIN;
567 if (!timeo)
568 break;
569 rc = sock_intr_errno(timeo);
565 if (signal_pending(current)) 570 if (signal_pending(current))
566 break; 571 break;
567 rc = -EAGAIN; 572 rc = 0;
568 if (!timeout) 573 if (sk_wait_data(sk, &timeo))
569 break; 574 break;
570 } 575 }
571 finish_wait(sk->sk_sleep, &wait);
572 return rc; 576 return rc;
573} 577}
574 578
@@ -599,7 +603,7 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
599 goto out; 603 goto out;
600 /* wait for a connection to arrive. */ 604 /* wait for a connection to arrive. */
601 if (skb_queue_empty(&sk->sk_receive_queue)) { 605 if (skb_queue_empty(&sk->sk_receive_queue)) {
602 rc = llc_ui_wait_for_data(sk, sk->sk_rcvtimeo); 606 rc = llc_wait_data(sk, sk->sk_rcvtimeo);
603 if (rc) 607 if (rc)
604 goto out; 608 goto out;
605 } 609 }
@@ -658,7 +662,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
658 llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap); 662 llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap);
659 lock_sock(sk); 663 lock_sock(sk);
660 if (skb_queue_empty(&sk->sk_receive_queue)) { 664 if (skb_queue_empty(&sk->sk_receive_queue)) {
661 rc = llc_ui_wait_for_data(sk, sock_rcvtimeo(sk, noblock)); 665 rc = llc_wait_data(sk, sock_rcvtimeo(sk, noblock));
662 if (rc) 666 if (rc)
663 goto out; 667 goto out;
664 } 668 }