diff options
Diffstat (limited to 'net/tipc/socket.c')
| -rw-r--r-- | net/tipc/socket.c | 52 |
1 files changed, 25 insertions, 27 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index adb2eff4a102..42b8324ff2ee 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | * POSSIBILITY OF SUCH DAMAGE. | 34 | * POSSIBILITY OF SUCH DAMAGE. |
| 35 | */ | 35 | */ |
| 36 | 36 | ||
| 37 | #include <linux/export.h> | ||
| 37 | #include <net/sock.h> | 38 | #include <net/sock.h> |
| 38 | 39 | ||
| 39 | #include "core.h" | 40 | #include "core.h" |
| @@ -49,7 +50,7 @@ struct tipc_sock { | |||
| 49 | struct sock sk; | 50 | struct sock sk; |
| 50 | struct tipc_port *p; | 51 | struct tipc_port *p; |
| 51 | struct tipc_portid peer_name; | 52 | struct tipc_portid peer_name; |
| 52 | long conn_timeout; | 53 | unsigned int conn_timeout; |
| 53 | }; | 54 | }; |
| 54 | 55 | ||
| 55 | #define tipc_sk(sk) ((struct tipc_sock *)(sk)) | 56 | #define tipc_sk(sk) ((struct tipc_sock *)(sk)) |
| @@ -231,7 +232,7 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol, | |||
| 231 | sock_init_data(sock, sk); | 232 | sock_init_data(sock, sk); |
| 232 | sk->sk_backlog_rcv = backlog_rcv; | 233 | sk->sk_backlog_rcv = backlog_rcv; |
| 233 | tipc_sk(sk)->p = tp_ptr; | 234 | tipc_sk(sk)->p = tp_ptr; |
| 234 | tipc_sk(sk)->conn_timeout = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT); | 235 | tipc_sk(sk)->conn_timeout = CONN_TIMEOUT_DEFAULT; |
| 235 | 236 | ||
| 236 | spin_unlock_bh(tp_ptr->lock); | 237 | spin_unlock_bh(tp_ptr->lock); |
| 237 | 238 | ||
| @@ -525,6 +526,7 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, | |||
| 525 | struct tipc_port *tport = tipc_sk_port(sk); | 526 | struct tipc_port *tport = tipc_sk_port(sk); |
| 526 | struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name; | 527 | struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name; |
| 527 | int needs_conn; | 528 | int needs_conn; |
| 529 | long timeout_val; | ||
| 528 | int res = -EINVAL; | 530 | int res = -EINVAL; |
| 529 | 531 | ||
| 530 | if (unlikely(!dest)) | 532 | if (unlikely(!dest)) |
| @@ -564,6 +566,8 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, | |||
| 564 | reject_rx_queue(sk); | 566 | reject_rx_queue(sk); |
| 565 | } | 567 | } |
| 566 | 568 | ||
| 569 | timeout_val = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); | ||
| 570 | |||
| 567 | do { | 571 | do { |
| 568 | if (dest->addrtype == TIPC_ADDR_NAME) { | 572 | if (dest->addrtype == TIPC_ADDR_NAME) { |
| 569 | res = dest_name_check(dest, m); | 573 | res = dest_name_check(dest, m); |
| @@ -600,16 +604,14 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, | |||
| 600 | sock->state = SS_CONNECTING; | 604 | sock->state = SS_CONNECTING; |
| 601 | break; | 605 | break; |
| 602 | } | 606 | } |
| 603 | if (m->msg_flags & MSG_DONTWAIT) { | 607 | if (timeout_val <= 0L) { |
| 604 | res = -EWOULDBLOCK; | 608 | res = timeout_val ? timeout_val : -EWOULDBLOCK; |
| 605 | break; | 609 | break; |
| 606 | } | 610 | } |
| 607 | release_sock(sk); | 611 | release_sock(sk); |
| 608 | res = wait_event_interruptible(*sk_sleep(sk), | 612 | timeout_val = wait_event_interruptible_timeout(*sk_sleep(sk), |
| 609 | !tport->congested); | 613 | !tport->congested, timeout_val); |
| 610 | lock_sock(sk); | 614 | lock_sock(sk); |
| 611 | if (res) | ||
| 612 | break; | ||
| 613 | } while (1); | 615 | } while (1); |
| 614 | 616 | ||
| 615 | exit: | 617 | exit: |
| @@ -636,6 +638,7 @@ static int send_packet(struct kiocb *iocb, struct socket *sock, | |||
| 636 | struct sock *sk = sock->sk; | 638 | struct sock *sk = sock->sk; |
| 637 | struct tipc_port *tport = tipc_sk_port(sk); | 639 | struct tipc_port *tport = tipc_sk_port(sk); |
| 638 | struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name; | 640 | struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name; |
| 641 | long timeout_val; | ||
| 639 | int res; | 642 | int res; |
| 640 | 643 | ||
| 641 | /* Handle implied connection establishment */ | 644 | /* Handle implied connection establishment */ |
| @@ -650,6 +653,8 @@ static int send_packet(struct kiocb *iocb, struct socket *sock, | |||
| 650 | if (iocb) | 653 | if (iocb) |
| 651 | lock_sock(sk); | 654 | lock_sock(sk); |
| 652 | 655 | ||
| 656 | timeout_val = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); | ||
| 657 | |||
| 653 | do { | 658 | do { |
| 654 | if (unlikely(sock->state != SS_CONNECTED)) { | 659 | if (unlikely(sock->state != SS_CONNECTED)) { |
| 655 | if (sock->state == SS_DISCONNECTING) | 660 | if (sock->state == SS_DISCONNECTING) |
| @@ -663,16 +668,14 @@ static int send_packet(struct kiocb *iocb, struct socket *sock, | |||
| 663 | total_len); | 668 | total_len); |
| 664 | if (likely(res != -ELINKCONG)) | 669 | if (likely(res != -ELINKCONG)) |
| 665 | break; | 670 | break; |
| 666 | if (m->msg_flags & MSG_DONTWAIT) { | 671 | if (timeout_val <= 0L) { |
| 667 | res = -EWOULDBLOCK; | 672 | res = timeout_val ? timeout_val : -EWOULDBLOCK; |
| 668 | break; | 673 | break; |
| 669 | } | 674 | } |
| 670 | release_sock(sk); | 675 | release_sock(sk); |
| 671 | res = wait_event_interruptible(*sk_sleep(sk), | 676 | timeout_val = wait_event_interruptible_timeout(*sk_sleep(sk), |
| 672 | (!tport->congested || !tport->connected)); | 677 | (!tport->congested || !tport->connected), timeout_val); |
| 673 | lock_sock(sk); | 678 | lock_sock(sk); |
| 674 | if (res) | ||
| 675 | break; | ||
| 676 | } while (1); | 679 | } while (1); |
| 677 | 680 | ||
| 678 | if (iocb) | 681 | if (iocb) |
| @@ -1369,7 +1372,7 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, | |||
| 1369 | struct msghdr m = {NULL,}; | 1372 | struct msghdr m = {NULL,}; |
| 1370 | struct sk_buff *buf; | 1373 | struct sk_buff *buf; |
| 1371 | struct tipc_msg *msg; | 1374 | struct tipc_msg *msg; |
| 1372 | long timeout; | 1375 | unsigned int timeout; |
| 1373 | int res; | 1376 | int res; |
| 1374 | 1377 | ||
| 1375 | lock_sock(sk); | 1378 | lock_sock(sk); |
| @@ -1434,7 +1437,8 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, | |||
| 1434 | res = wait_event_interruptible_timeout(*sk_sleep(sk), | 1437 | res = wait_event_interruptible_timeout(*sk_sleep(sk), |
| 1435 | (!skb_queue_empty(&sk->sk_receive_queue) || | 1438 | (!skb_queue_empty(&sk->sk_receive_queue) || |
| 1436 | (sock->state != SS_CONNECTING)), | 1439 | (sock->state != SS_CONNECTING)), |
| 1437 | timeout ? timeout : MAX_SCHEDULE_TIMEOUT); | 1440 | timeout ? (long)msecs_to_jiffies(timeout) |
| 1441 | : MAX_SCHEDULE_TIMEOUT); | ||
| 1438 | lock_sock(sk); | 1442 | lock_sock(sk); |
| 1439 | 1443 | ||
| 1440 | if (res > 0) { | 1444 | if (res > 0) { |
| @@ -1480,9 +1484,7 @@ static int listen(struct socket *sock, int len) | |||
| 1480 | 1484 | ||
| 1481 | lock_sock(sk); | 1485 | lock_sock(sk); |
| 1482 | 1486 | ||
| 1483 | if (sock->state == SS_READY) | 1487 | if (sock->state != SS_UNCONNECTED) |
| 1484 | res = -EOPNOTSUPP; | ||
| 1485 | else if (sock->state != SS_UNCONNECTED) | ||
| 1486 | res = -EINVAL; | 1488 | res = -EINVAL; |
| 1487 | else { | 1489 | else { |
| 1488 | sock->state = SS_LISTENING; | 1490 | sock->state = SS_LISTENING; |
| @@ -1510,10 +1512,6 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) | |||
| 1510 | 1512 | ||
| 1511 | lock_sock(sk); | 1513 | lock_sock(sk); |
| 1512 | 1514 | ||
| 1513 | if (sock->state == SS_READY) { | ||
| 1514 | res = -EOPNOTSUPP; | ||
| 1515 | goto exit; | ||
| 1516 | } | ||
| 1517 | if (sock->state != SS_LISTENING) { | 1515 | if (sock->state != SS_LISTENING) { |
| 1518 | res = -EINVAL; | 1516 | res = -EINVAL; |
| 1519 | goto exit; | 1517 | goto exit; |
| @@ -1696,7 +1694,7 @@ static int setsockopt(struct socket *sock, | |||
| 1696 | res = tipc_set_portunreturnable(tport->ref, value); | 1694 | res = tipc_set_portunreturnable(tport->ref, value); |
| 1697 | break; | 1695 | break; |
| 1698 | case TIPC_CONN_TIMEOUT: | 1696 | case TIPC_CONN_TIMEOUT: |
| 1699 | tipc_sk(sk)->conn_timeout = msecs_to_jiffies(value); | 1697 | tipc_sk(sk)->conn_timeout = value; |
| 1700 | /* no need to set "res", since already 0 at this point */ | 1698 | /* no need to set "res", since already 0 at this point */ |
| 1701 | break; | 1699 | break; |
| 1702 | default: | 1700 | default: |
| @@ -1752,7 +1750,7 @@ static int getsockopt(struct socket *sock, | |||
| 1752 | res = tipc_portunreturnable(tport->ref, &value); | 1750 | res = tipc_portunreturnable(tport->ref, &value); |
| 1753 | break; | 1751 | break; |
| 1754 | case TIPC_CONN_TIMEOUT: | 1752 | case TIPC_CONN_TIMEOUT: |
| 1755 | value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout); | 1753 | value = tipc_sk(sk)->conn_timeout; |
| 1756 | /* no need to set "res", since already 0 at this point */ | 1754 | /* no need to set "res", since already 0 at this point */ |
| 1757 | break; | 1755 | break; |
| 1758 | case TIPC_NODE_RECVQ_DEPTH: | 1756 | case TIPC_NODE_RECVQ_DEPTH: |
| @@ -1790,11 +1788,11 @@ static const struct proto_ops msg_ops = { | |||
| 1790 | .bind = bind, | 1788 | .bind = bind, |
| 1791 | .connect = connect, | 1789 | .connect = connect, |
| 1792 | .socketpair = sock_no_socketpair, | 1790 | .socketpair = sock_no_socketpair, |
| 1793 | .accept = accept, | 1791 | .accept = sock_no_accept, |
| 1794 | .getname = get_name, | 1792 | .getname = get_name, |
| 1795 | .poll = poll, | 1793 | .poll = poll, |
| 1796 | .ioctl = sock_no_ioctl, | 1794 | .ioctl = sock_no_ioctl, |
| 1797 | .listen = listen, | 1795 | .listen = sock_no_listen, |
| 1798 | .shutdown = shutdown, | 1796 | .shutdown = shutdown, |
| 1799 | .setsockopt = setsockopt, | 1797 | .setsockopt = setsockopt, |
| 1800 | .getsockopt = getsockopt, | 1798 | .getsockopt = getsockopt, |
