diff options
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 80 |
1 files changed, 31 insertions, 49 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 45832fb75ea4..4a8f37f48764 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * net/tipc/socket.c: TIPC socket API | 2 | * net/tipc/socket.c: TIPC socket API |
3 | * | 3 | * |
4 | * Copyright (c) 2001-2006, Ericsson AB | 4 | * Copyright (c) 2001-2007, Ericsson AB |
5 | * Copyright (c) 2004-2006, Wind River Systems | 5 | * Copyright (c) 2004-2007, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -607,23 +607,24 @@ exit: | |||
607 | static int send_stream(struct kiocb *iocb, struct socket *sock, | 607 | static int send_stream(struct kiocb *iocb, struct socket *sock, |
608 | struct msghdr *m, size_t total_len) | 608 | struct msghdr *m, size_t total_len) |
609 | { | 609 | { |
610 | struct tipc_port *tport; | ||
610 | struct msghdr my_msg; | 611 | struct msghdr my_msg; |
611 | struct iovec my_iov; | 612 | struct iovec my_iov; |
612 | struct iovec *curr_iov; | 613 | struct iovec *curr_iov; |
613 | int curr_iovlen; | 614 | int curr_iovlen; |
614 | char __user *curr_start; | 615 | char __user *curr_start; |
616 | u32 hdr_size; | ||
615 | int curr_left; | 617 | int curr_left; |
616 | int bytes_to_send; | 618 | int bytes_to_send; |
617 | int bytes_sent; | 619 | int bytes_sent; |
618 | int res; | 620 | int res; |
619 | 621 | ||
620 | if (likely(total_len <= TIPC_MAX_USER_MSG_SIZE)) | 622 | /* Handle special cases where there is no connection */ |
621 | return send_packet(iocb, sock, m, total_len); | ||
622 | |||
623 | /* Can only send large data streams if already connected */ | ||
624 | 623 | ||
625 | if (unlikely(sock->state != SS_CONNECTED)) { | 624 | if (unlikely(sock->state != SS_CONNECTED)) { |
626 | if (sock->state == SS_DISCONNECTING) | 625 | if (sock->state == SS_UNCONNECTED) |
626 | return send_packet(iocb, sock, m, total_len); | ||
627 | else if (sock->state == SS_DISCONNECTING) | ||
627 | return -EPIPE; | 628 | return -EPIPE; |
628 | else | 629 | else |
629 | return -ENOTCONN; | 630 | return -ENOTCONN; |
@@ -648,17 +649,25 @@ static int send_stream(struct kiocb *iocb, struct socket *sock, | |||
648 | my_msg.msg_name = NULL; | 649 | my_msg.msg_name = NULL; |
649 | bytes_sent = 0; | 650 | bytes_sent = 0; |
650 | 651 | ||
652 | tport = tipc_sk(sock->sk)->p; | ||
653 | hdr_size = msg_hdr_sz(&tport->phdr); | ||
654 | |||
651 | while (curr_iovlen--) { | 655 | while (curr_iovlen--) { |
652 | curr_start = curr_iov->iov_base; | 656 | curr_start = curr_iov->iov_base; |
653 | curr_left = curr_iov->iov_len; | 657 | curr_left = curr_iov->iov_len; |
654 | 658 | ||
655 | while (curr_left) { | 659 | while (curr_left) { |
656 | bytes_to_send = (curr_left < TIPC_MAX_USER_MSG_SIZE) | 660 | bytes_to_send = tport->max_pkt - hdr_size; |
657 | ? curr_left : TIPC_MAX_USER_MSG_SIZE; | 661 | if (bytes_to_send > TIPC_MAX_USER_MSG_SIZE) |
662 | bytes_to_send = TIPC_MAX_USER_MSG_SIZE; | ||
663 | if (curr_left < bytes_to_send) | ||
664 | bytes_to_send = curr_left; | ||
658 | my_iov.iov_base = curr_start; | 665 | my_iov.iov_base = curr_start; |
659 | my_iov.iov_len = bytes_to_send; | 666 | my_iov.iov_len = bytes_to_send; |
660 | if ((res = send_packet(iocb, sock, &my_msg, 0)) < 0) { | 667 | if ((res = send_packet(iocb, sock, &my_msg, 0)) < 0) { |
661 | return bytes_sent ? bytes_sent : res; | 668 | if (bytes_sent != 0) |
669 | res = bytes_sent; | ||
670 | return res; | ||
662 | } | 671 | } |
663 | curr_left -= bytes_to_send; | 672 | curr_left -= bytes_to_send; |
664 | curr_start += bytes_to_send; | 673 | curr_start += bytes_to_send; |
@@ -1600,33 +1609,6 @@ static int getsockopt(struct socket *sock, | |||
1600 | } | 1609 | } |
1601 | 1610 | ||
1602 | /** | 1611 | /** |
1603 | * Placeholders for non-implemented functionality | ||
1604 | * | ||
1605 | * Returns error code (POSIX-compliant where defined) | ||
1606 | */ | ||
1607 | |||
1608 | static int ioctl(struct socket *s, u32 cmd, unsigned long arg) | ||
1609 | { | ||
1610 | return -EINVAL; | ||
1611 | } | ||
1612 | |||
1613 | static int no_mmap(struct file *file, struct socket *sock, | ||
1614 | struct vm_area_struct *vma) | ||
1615 | { | ||
1616 | return -EINVAL; | ||
1617 | } | ||
1618 | static ssize_t no_sendpage(struct socket *sock, struct page *page, | ||
1619 | int offset, size_t size, int flags) | ||
1620 | { | ||
1621 | return -EINVAL; | ||
1622 | } | ||
1623 | |||
1624 | static int no_skpair(struct socket *s1, struct socket *s2) | ||
1625 | { | ||
1626 | return -EOPNOTSUPP; | ||
1627 | } | ||
1628 | |||
1629 | /** | ||
1630 | * Protocol switches for the various types of TIPC sockets | 1612 | * Protocol switches for the various types of TIPC sockets |
1631 | */ | 1613 | */ |
1632 | 1614 | ||
@@ -1636,19 +1618,19 @@ static struct proto_ops msg_ops = { | |||
1636 | .release = release, | 1618 | .release = release, |
1637 | .bind = bind, | 1619 | .bind = bind, |
1638 | .connect = connect, | 1620 | .connect = connect, |
1639 | .socketpair = no_skpair, | 1621 | .socketpair = sock_no_socketpair, |
1640 | .accept = accept, | 1622 | .accept = accept, |
1641 | .getname = get_name, | 1623 | .getname = get_name, |
1642 | .poll = poll, | 1624 | .poll = poll, |
1643 | .ioctl = ioctl, | 1625 | .ioctl = sock_no_ioctl, |
1644 | .listen = listen, | 1626 | .listen = listen, |
1645 | .shutdown = shutdown, | 1627 | .shutdown = shutdown, |
1646 | .setsockopt = setsockopt, | 1628 | .setsockopt = setsockopt, |
1647 | .getsockopt = getsockopt, | 1629 | .getsockopt = getsockopt, |
1648 | .sendmsg = send_msg, | 1630 | .sendmsg = send_msg, |
1649 | .recvmsg = recv_msg, | 1631 | .recvmsg = recv_msg, |
1650 | .mmap = no_mmap, | 1632 | .mmap = sock_no_mmap, |
1651 | .sendpage = no_sendpage | 1633 | .sendpage = sock_no_sendpage |
1652 | }; | 1634 | }; |
1653 | 1635 | ||
1654 | static struct proto_ops packet_ops = { | 1636 | static struct proto_ops packet_ops = { |
@@ -1657,19 +1639,19 @@ static struct proto_ops packet_ops = { | |||
1657 | .release = release, | 1639 | .release = release, |
1658 | .bind = bind, | 1640 | .bind = bind, |
1659 | .connect = connect, | 1641 | .connect = connect, |
1660 | .socketpair = no_skpair, | 1642 | .socketpair = sock_no_socketpair, |
1661 | .accept = accept, | 1643 | .accept = accept, |
1662 | .getname = get_name, | 1644 | .getname = get_name, |
1663 | .poll = poll, | 1645 | .poll = poll, |
1664 | .ioctl = ioctl, | 1646 | .ioctl = sock_no_ioctl, |
1665 | .listen = listen, | 1647 | .listen = listen, |
1666 | .shutdown = shutdown, | 1648 | .shutdown = shutdown, |
1667 | .setsockopt = setsockopt, | 1649 | .setsockopt = setsockopt, |
1668 | .getsockopt = getsockopt, | 1650 | .getsockopt = getsockopt, |
1669 | .sendmsg = send_packet, | 1651 | .sendmsg = send_packet, |
1670 | .recvmsg = recv_msg, | 1652 | .recvmsg = recv_msg, |
1671 | .mmap = no_mmap, | 1653 | .mmap = sock_no_mmap, |
1672 | .sendpage = no_sendpage | 1654 | .sendpage = sock_no_sendpage |
1673 | }; | 1655 | }; |
1674 | 1656 | ||
1675 | static struct proto_ops stream_ops = { | 1657 | static struct proto_ops stream_ops = { |
@@ -1678,19 +1660,19 @@ static struct proto_ops stream_ops = { | |||
1678 | .release = release, | 1660 | .release = release, |
1679 | .bind = bind, | 1661 | .bind = bind, |
1680 | .connect = connect, | 1662 | .connect = connect, |
1681 | .socketpair = no_skpair, | 1663 | .socketpair = sock_no_socketpair, |
1682 | .accept = accept, | 1664 | .accept = accept, |
1683 | .getname = get_name, | 1665 | .getname = get_name, |
1684 | .poll = poll, | 1666 | .poll = poll, |
1685 | .ioctl = ioctl, | 1667 | .ioctl = sock_no_ioctl, |
1686 | .listen = listen, | 1668 | .listen = listen, |
1687 | .shutdown = shutdown, | 1669 | .shutdown = shutdown, |
1688 | .setsockopt = setsockopt, | 1670 | .setsockopt = setsockopt, |
1689 | .getsockopt = getsockopt, | 1671 | .getsockopt = getsockopt, |
1690 | .sendmsg = send_stream, | 1672 | .sendmsg = send_stream, |
1691 | .recvmsg = recv_stream, | 1673 | .recvmsg = recv_stream, |
1692 | .mmap = no_mmap, | 1674 | .mmap = sock_no_mmap, |
1693 | .sendpage = no_sendpage | 1675 | .sendpage = sock_no_sendpage |
1694 | }; | 1676 | }; |
1695 | 1677 | ||
1696 | static struct net_proto_family tipc_family_ops = { | 1678 | static struct net_proto_family tipc_family_ops = { |