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.c80
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:
607static int send_stream(struct kiocb *iocb, struct socket *sock, 607static 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
1608static int ioctl(struct socket *s, u32 cmd, unsigned long arg)
1609{
1610 return -EINVAL;
1611}
1612
1613static int no_mmap(struct file *file, struct socket *sock,
1614 struct vm_area_struct *vma)
1615{
1616 return -EINVAL;
1617}
1618static ssize_t no_sendpage(struct socket *sock, struct page *page,
1619 int offset, size_t size, int flags)
1620{
1621 return -EINVAL;
1622}
1623
1624static 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
1654static struct proto_ops packet_ops = { 1636static 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
1675static struct proto_ops stream_ops = { 1657static 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
1696static struct net_proto_family tipc_family_ops = { 1678static struct net_proto_family tipc_family_ops = {