diff options
Diffstat (limited to 'net/llc')
-rw-r--r-- | net/llc/af_llc.c | 42 |
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 | ||
40 | static int llc_ui_wait_for_conn(struct sock *sk, long timeout); | 40 | static int llc_ui_wait_for_conn(struct sock *sk, long timeout); |
41 | static int llc_ui_wait_for_disc(struct sock *sk, long timeout); | 41 | static int llc_ui_wait_for_disc(struct sock *sk, long timeout); |
42 | static int llc_ui_wait_for_data(struct sock *sk, long timeout); | ||
43 | static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout); | 42 | static 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 | ||
527 | static int llc_ui_wait_for_data(struct sock *sk, long timeout) | 526 | static 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 | ||
550 | static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout) | 551 | int 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 | } |