diff options
author | Paul Mundt <lethal@linux-sh.org> | 2011-01-13 01:06:28 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-01-13 01:06:28 -0500 |
commit | f43dc23d5ea91fca257be02138a255f02d98e806 (patch) | |
tree | b29722f6e965316e90ac97abf79923ced250dc21 /net/tipc/socket.c | |
parent | f8e53553f452dcbf67cb89c8cba63a1cd6eb4cc0 (diff) | |
parent | 4162cf64973df51fc885825bc9ca4d055891c49f (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 into common/serial-rework
Conflicts:
arch/sh/kernel/cpu/sh2/setup-sh7619.c
arch/sh/kernel/cpu/sh2a/setup-mxg.c
arch/sh/kernel/cpu/sh2a/setup-sh7201.c
arch/sh/kernel/cpu/sh2a/setup-sh7203.c
arch/sh/kernel/cpu/sh2a/setup-sh7206.c
arch/sh/kernel/cpu/sh3/setup-sh7705.c
arch/sh/kernel/cpu/sh3/setup-sh770x.c
arch/sh/kernel/cpu/sh3/setup-sh7710.c
arch/sh/kernel/cpu/sh3/setup-sh7720.c
arch/sh/kernel/cpu/sh4/setup-sh4-202.c
arch/sh/kernel/cpu/sh4/setup-sh7750.c
arch/sh/kernel/cpu/sh4/setup-sh7760.c
arch/sh/kernel/cpu/sh4a/setup-sh7343.c
arch/sh/kernel/cpu/sh4a/setup-sh7366.c
arch/sh/kernel/cpu/sh4a/setup-sh7722.c
arch/sh/kernel/cpu/sh4a/setup-sh7723.c
arch/sh/kernel/cpu/sh4a/setup-sh7724.c
arch/sh/kernel/cpu/sh4a/setup-sh7763.c
arch/sh/kernel/cpu/sh4a/setup-sh7770.c
arch/sh/kernel/cpu/sh4a/setup-sh7780.c
arch/sh/kernel/cpu/sh4a/setup-sh7785.c
arch/sh/kernel/cpu/sh4a/setup-sh7786.c
arch/sh/kernel/cpu/sh4a/setup-shx3.c
arch/sh/kernel/cpu/sh5/setup-sh5.c
drivers/serial/sh-sci.c
drivers/serial/sh-sci.h
include/linux/serial_sci.h
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 293 |
1 files changed, 147 insertions, 146 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 1848693ebb82..2b02a3a80313 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -34,25 +34,13 @@ | |||
34 | * POSSIBILITY OF SUCH DAMAGE. | 34 | * POSSIBILITY OF SUCH DAMAGE. |
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include <linux/module.h> | ||
38 | #include <linux/types.h> | ||
39 | #include <linux/net.h> | ||
40 | #include <linux/socket.h> | ||
41 | #include <linux/errno.h> | ||
42 | #include <linux/mm.h> | ||
43 | #include <linux/slab.h> | ||
44 | #include <linux/poll.h> | ||
45 | #include <linux/fcntl.h> | ||
46 | #include <asm/string.h> | ||
47 | #include <asm/atomic.h> | ||
48 | #include <net/sock.h> | 37 | #include <net/sock.h> |
49 | 38 | ||
50 | #include <linux/tipc.h> | 39 | #include <linux/tipc.h> |
51 | #include <linux/tipc_config.h> | 40 | #include <linux/tipc_config.h> |
52 | #include <net/tipc/tipc_msg.h> | ||
53 | #include <net/tipc/tipc_port.h> | ||
54 | 41 | ||
55 | #include "core.h" | 42 | #include "core.h" |
43 | #include "port.h" | ||
56 | 44 | ||
57 | #define SS_LISTENING -1 /* socket is listening */ | 45 | #define SS_LISTENING -1 /* socket is listening */ |
58 | #define SS_READY -2 /* socket is connectionless */ | 46 | #define SS_READY -2 /* socket is connectionless */ |
@@ -64,6 +52,7 @@ struct tipc_sock { | |||
64 | struct sock sk; | 52 | struct sock sk; |
65 | struct tipc_port *p; | 53 | struct tipc_port *p; |
66 | struct tipc_portid peer_name; | 54 | struct tipc_portid peer_name; |
55 | long conn_timeout; | ||
67 | }; | 56 | }; |
68 | 57 | ||
69 | #define tipc_sk(sk) ((struct tipc_sock *)(sk)) | 58 | #define tipc_sk(sk) ((struct tipc_sock *)(sk)) |
@@ -79,7 +68,7 @@ static const struct proto_ops msg_ops; | |||
79 | 68 | ||
80 | static struct proto tipc_proto; | 69 | static struct proto tipc_proto; |
81 | 70 | ||
82 | static int sockets_enabled = 0; | 71 | static int sockets_enabled; |
83 | 72 | ||
84 | static atomic_t tipc_queue_size = ATOMIC_INIT(0); | 73 | static atomic_t tipc_queue_size = ATOMIC_INIT(0); |
85 | 74 | ||
@@ -177,6 +166,7 @@ static void reject_rx_queue(struct sock *sk) | |||
177 | * @net: network namespace (must be default network) | 166 | * @net: network namespace (must be default network) |
178 | * @sock: pre-allocated socket structure | 167 | * @sock: pre-allocated socket structure |
179 | * @protocol: protocol indicator (must be 0) | 168 | * @protocol: protocol indicator (must be 0) |
169 | * @kern: caused by kernel or by userspace? | ||
180 | * | 170 | * |
181 | * This routine creates additional data structures used by the TIPC socket, | 171 | * This routine creates additional data structures used by the TIPC socket, |
182 | * initializes them, and links them together. | 172 | * initializes them, and links them together. |
@@ -184,7 +174,8 @@ static void reject_rx_queue(struct sock *sk) | |||
184 | * Returns 0 on success, errno otherwise | 174 | * Returns 0 on success, errno otherwise |
185 | */ | 175 | */ |
186 | 176 | ||
187 | static int tipc_create(struct net *net, struct socket *sock, int protocol) | 177 | static int tipc_create(struct net *net, struct socket *sock, int protocol, |
178 | int kern) | ||
188 | { | 179 | { |
189 | const struct proto_ops *ops; | 180 | const struct proto_ops *ops; |
190 | socket_state state; | 181 | socket_state state; |
@@ -193,7 +184,7 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol) | |||
193 | 184 | ||
194 | /* Validate arguments */ | 185 | /* Validate arguments */ |
195 | 186 | ||
196 | if (net != &init_net) | 187 | if (!net_eq(net, &init_net)) |
197 | return -EAFNOSUPPORT; | 188 | return -EAFNOSUPPORT; |
198 | 189 | ||
199 | if (unlikely(protocol != 0)) | 190 | if (unlikely(protocol != 0)) |
@@ -238,9 +229,9 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol) | |||
238 | sock->state = state; | 229 | sock->state = state; |
239 | 230 | ||
240 | sock_init_data(sock, sk); | 231 | sock_init_data(sock, sk); |
241 | sk->sk_rcvtimeo = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT); | ||
242 | sk->sk_backlog_rcv = backlog_rcv; | 232 | sk->sk_backlog_rcv = backlog_rcv; |
243 | tipc_sk(sk)->p = tp_ptr; | 233 | tipc_sk(sk)->p = tp_ptr; |
234 | tipc_sk(sk)->conn_timeout = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT); | ||
244 | 235 | ||
245 | spin_unlock_bh(tp_ptr->lock); | 236 | spin_unlock_bh(tp_ptr->lock); |
246 | 237 | ||
@@ -384,7 +375,7 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) | |||
384 | * | 375 | * |
385 | * NOTE: This routine doesn't need to take the socket lock since it only | 376 | * NOTE: This routine doesn't need to take the socket lock since it only |
386 | * accesses socket information that is unchanging (or which changes in | 377 | * accesses socket information that is unchanging (or which changes in |
387 | * a completely predictable manner). | 378 | * a completely predictable manner). |
388 | */ | 379 | */ |
389 | 380 | ||
390 | static int get_name(struct socket *sock, struct sockaddr *uaddr, | 381 | static int get_name(struct socket *sock, struct sockaddr *uaddr, |
@@ -393,6 +384,7 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr, | |||
393 | struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; | 384 | struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; |
394 | struct tipc_sock *tsock = tipc_sk(sock->sk); | 385 | struct tipc_sock *tsock = tipc_sk(sock->sk); |
395 | 386 | ||
387 | memset(addr, 0, sizeof(*addr)); | ||
396 | if (peer) { | 388 | if (peer) { |
397 | if ((sock->state != SS_CONNECTED) && | 389 | if ((sock->state != SS_CONNECTED) && |
398 | ((peer != 2) || (sock->state != SS_DISCONNECTING))) | 390 | ((peer != 2) || (sock->state != SS_DISCONNECTING))) |
@@ -400,7 +392,8 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr, | |||
400 | addr->addr.id.ref = tsock->peer_name.ref; | 392 | addr->addr.id.ref = tsock->peer_name.ref; |
401 | addr->addr.id.node = tsock->peer_name.node; | 393 | addr->addr.id.node = tsock->peer_name.node; |
402 | } else { | 394 | } else { |
403 | tipc_ownidentity(tsock->p->ref, &addr->addr.id); | 395 | addr->addr.id.ref = tsock->p->ref; |
396 | addr->addr.id.node = tipc_own_addr; | ||
404 | } | 397 | } |
405 | 398 | ||
406 | *uaddr_len = sizeof(*addr); | 399 | *uaddr_len = sizeof(*addr); |
@@ -427,36 +420,55 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr, | |||
427 | * to handle any preventable race conditions, so TIPC will do the same ... | 420 | * to handle any preventable race conditions, so TIPC will do the same ... |
428 | * | 421 | * |
429 | * TIPC sets the returned events as follows: | 422 | * TIPC sets the returned events as follows: |
430 | * a) POLLRDNORM and POLLIN are set if the socket's receive queue is non-empty | 423 | * |
431 | * or if a connection-oriented socket is does not have an active connection | 424 | * socket state flags set |
432 | * (i.e. a read operation will not block). | 425 | * ------------ --------- |
433 | * b) POLLOUT is set except when a socket's connection has been terminated | 426 | * unconnected no read flags |
434 | * (i.e. a write operation will not block). | 427 | * no write flags |
435 | * c) POLLHUP is set when a socket's connection has been terminated. | 428 | * |
436 | * | 429 | * connecting POLLIN/POLLRDNORM if ACK/NACK in rx queue |
437 | * IMPORTANT: The fact that a read or write operation will not block does NOT | 430 | * no write flags |
438 | * imply that the operation will succeed! | 431 | * |
432 | * connected POLLIN/POLLRDNORM if data in rx queue | ||
433 | * POLLOUT if port is not congested | ||
434 | * | ||
435 | * disconnecting POLLIN/POLLRDNORM/POLLHUP | ||
436 | * no write flags | ||
437 | * | ||
438 | * listening POLLIN if SYN in rx queue | ||
439 | * no write flags | ||
440 | * | ||
441 | * ready POLLIN/POLLRDNORM if data in rx queue | ||
442 | * [connectionless] POLLOUT (since port cannot be congested) | ||
443 | * | ||
444 | * IMPORTANT: The fact that a read or write operation is indicated does NOT | ||
445 | * imply that the operation will succeed, merely that it should be performed | ||
446 | * and will not block. | ||
439 | */ | 447 | */ |
440 | 448 | ||
441 | static unsigned int poll(struct file *file, struct socket *sock, | 449 | static unsigned int poll(struct file *file, struct socket *sock, |
442 | poll_table *wait) | 450 | poll_table *wait) |
443 | { | 451 | { |
444 | struct sock *sk = sock->sk; | 452 | struct sock *sk = sock->sk; |
445 | u32 mask; | 453 | u32 mask = 0; |
446 | 454 | ||
447 | poll_wait(file, sk->sk_sleep, wait); | 455 | poll_wait(file, sk_sleep(sk), wait); |
448 | |||
449 | if (!skb_queue_empty(&sk->sk_receive_queue) || | ||
450 | (sock->state == SS_UNCONNECTED) || | ||
451 | (sock->state == SS_DISCONNECTING)) | ||
452 | mask = (POLLRDNORM | POLLIN); | ||
453 | else | ||
454 | mask = 0; | ||
455 | 456 | ||
456 | if (sock->state == SS_DISCONNECTING) | 457 | switch ((int)sock->state) { |
457 | mask |= POLLHUP; | 458 | case SS_READY: |
458 | else | 459 | case SS_CONNECTED: |
459 | mask |= POLLOUT; | 460 | if (!tipc_sk_port(sk)->congested) |
461 | mask |= POLLOUT; | ||
462 | /* fall thru' */ | ||
463 | case SS_CONNECTING: | ||
464 | case SS_LISTENING: | ||
465 | if (!skb_queue_empty(&sk->sk_receive_queue)) | ||
466 | mask |= (POLLIN | POLLRDNORM); | ||
467 | break; | ||
468 | case SS_DISCONNECTING: | ||
469 | mask = (POLLIN | POLLRDNORM | POLLHUP); | ||
470 | break; | ||
471 | } | ||
460 | 472 | ||
461 | return mask; | 473 | return mask; |
462 | } | 474 | } |
@@ -551,37 +563,35 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, | |||
551 | 563 | ||
552 | do { | 564 | do { |
553 | if (dest->addrtype == TIPC_ADDR_NAME) { | 565 | if (dest->addrtype == TIPC_ADDR_NAME) { |
554 | if ((res = dest_name_check(dest, m))) | 566 | res = dest_name_check(dest, m); |
567 | if (res) | ||
555 | break; | 568 | break; |
556 | res = tipc_send2name(tport->ref, | 569 | res = tipc_send2name(tport->ref, |
557 | &dest->addr.name.name, | 570 | &dest->addr.name.name, |
558 | dest->addr.name.domain, | 571 | dest->addr.name.domain, |
559 | m->msg_iovlen, | 572 | m->msg_iovlen, |
560 | m->msg_iov); | 573 | m->msg_iov); |
561 | } | 574 | } else if (dest->addrtype == TIPC_ADDR_ID) { |
562 | else if (dest->addrtype == TIPC_ADDR_ID) { | ||
563 | res = tipc_send2port(tport->ref, | 575 | res = tipc_send2port(tport->ref, |
564 | &dest->addr.id, | 576 | &dest->addr.id, |
565 | m->msg_iovlen, | 577 | m->msg_iovlen, |
566 | m->msg_iov); | 578 | m->msg_iov); |
567 | } | 579 | } else if (dest->addrtype == TIPC_ADDR_MCAST) { |
568 | else if (dest->addrtype == TIPC_ADDR_MCAST) { | ||
569 | if (needs_conn) { | 580 | if (needs_conn) { |
570 | res = -EOPNOTSUPP; | 581 | res = -EOPNOTSUPP; |
571 | break; | 582 | break; |
572 | } | 583 | } |
573 | if ((res = dest_name_check(dest, m))) | 584 | res = dest_name_check(dest, m); |
585 | if (res) | ||
574 | break; | 586 | break; |
575 | res = tipc_multicast(tport->ref, | 587 | res = tipc_multicast(tport->ref, |
576 | &dest->addr.nameseq, | 588 | &dest->addr.nameseq, |
577 | 0, | ||
578 | m->msg_iovlen, | 589 | m->msg_iovlen, |
579 | m->msg_iov); | 590 | m->msg_iov); |
580 | } | 591 | } |
581 | if (likely(res != -ELINKCONG)) { | 592 | if (likely(res != -ELINKCONG)) { |
582 | if (needs_conn && (res >= 0)) { | 593 | if (needs_conn && (res >= 0)) |
583 | sock->state = SS_CONNECTING; | 594 | sock->state = SS_CONNECTING; |
584 | } | ||
585 | break; | 595 | break; |
586 | } | 596 | } |
587 | if (m->msg_flags & MSG_DONTWAIT) { | 597 | if (m->msg_flags & MSG_DONTWAIT) { |
@@ -589,7 +599,7 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, | |||
589 | break; | 599 | break; |
590 | } | 600 | } |
591 | release_sock(sk); | 601 | release_sock(sk); |
592 | res = wait_event_interruptible(*sk->sk_sleep, | 602 | res = wait_event_interruptible(*sk_sleep(sk), |
593 | !tport->congested); | 603 | !tport->congested); |
594 | lock_sock(sk); | 604 | lock_sock(sk); |
595 | if (res) | 605 | if (res) |
@@ -640,15 +650,14 @@ static int send_packet(struct kiocb *iocb, struct socket *sock, | |||
640 | } | 650 | } |
641 | 651 | ||
642 | res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov); | 652 | res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov); |
643 | if (likely(res != -ELINKCONG)) { | 653 | if (likely(res != -ELINKCONG)) |
644 | break; | 654 | break; |
645 | } | ||
646 | if (m->msg_flags & MSG_DONTWAIT) { | 655 | if (m->msg_flags & MSG_DONTWAIT) { |
647 | res = -EWOULDBLOCK; | 656 | res = -EWOULDBLOCK; |
648 | break; | 657 | break; |
649 | } | 658 | } |
650 | release_sock(sk); | 659 | release_sock(sk); |
651 | res = wait_event_interruptible(*sk->sk_sleep, | 660 | res = wait_event_interruptible(*sk_sleep(sk), |
652 | (!tport->congested || !tport->connected)); | 661 | (!tport->congested || !tport->connected)); |
653 | lock_sock(sk); | 662 | lock_sock(sk); |
654 | if (res) | 663 | if (res) |
@@ -741,7 +750,8 @@ static int send_stream(struct kiocb *iocb, struct socket *sock, | |||
741 | bytes_to_send = curr_left; | 750 | bytes_to_send = curr_left; |
742 | my_iov.iov_base = curr_start; | 751 | my_iov.iov_base = curr_start; |
743 | my_iov.iov_len = bytes_to_send; | 752 | my_iov.iov_len = bytes_to_send; |
744 | if ((res = send_packet(NULL, sock, &my_msg, 0)) < 0) { | 753 | res = send_packet(NULL, sock, &my_msg, 0); |
754 | if (res < 0) { | ||
745 | if (bytes_sent) | 755 | if (bytes_sent) |
746 | res = bytes_sent; | 756 | res = bytes_sent; |
747 | goto exit; | 757 | goto exit; |
@@ -801,8 +811,8 @@ static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg) | |||
801 | addr->addrtype = TIPC_ADDR_ID; | 811 | addr->addrtype = TIPC_ADDR_ID; |
802 | addr->addr.id.ref = msg_origport(msg); | 812 | addr->addr.id.ref = msg_origport(msg); |
803 | addr->addr.id.node = msg_orignode(msg); | 813 | addr->addr.id.node = msg_orignode(msg); |
804 | addr->addr.name.domain = 0; /* could leave uninitialized */ | 814 | addr->addr.name.domain = 0; /* could leave uninitialized */ |
805 | addr->scope = 0; /* could leave uninitialized */ | 815 | addr->scope = 0; /* could leave uninitialized */ |
806 | m->msg_namelen = sizeof(struct sockaddr_tipc); | 816 | m->msg_namelen = sizeof(struct sockaddr_tipc); |
807 | } | 817 | } |
808 | } | 818 | } |
@@ -836,12 +846,15 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg, | |||
836 | if (unlikely(err)) { | 846 | if (unlikely(err)) { |
837 | anc_data[0] = err; | 847 | anc_data[0] = err; |
838 | anc_data[1] = msg_data_sz(msg); | 848 | anc_data[1] = msg_data_sz(msg); |
839 | if ((res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data))) | 849 | res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data); |
840 | return res; | 850 | if (res) |
841 | if (anc_data[1] && | ||
842 | (res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1], | ||
843 | msg_data(msg)))) | ||
844 | return res; | 851 | return res; |
852 | if (anc_data[1]) { | ||
853 | res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1], | ||
854 | msg_data(msg)); | ||
855 | if (res) | ||
856 | return res; | ||
857 | } | ||
845 | } | 858 | } |
846 | 859 | ||
847 | /* Optionally capture message destination object */ | 860 | /* Optionally capture message destination object */ |
@@ -869,9 +882,11 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg, | |||
869 | default: | 882 | default: |
870 | has_name = 0; | 883 | has_name = 0; |
871 | } | 884 | } |
872 | if (has_name && | 885 | if (has_name) { |
873 | (res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data))) | 886 | res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data); |
874 | return res; | 887 | if (res) |
888 | return res; | ||
889 | } | ||
875 | 890 | ||
876 | return 0; | 891 | return 0; |
877 | } | 892 | } |
@@ -929,7 +944,7 @@ restart: | |||
929 | goto exit; | 944 | goto exit; |
930 | } | 945 | } |
931 | release_sock(sk); | 946 | release_sock(sk); |
932 | res = wait_event_interruptible(*sk->sk_sleep, | 947 | res = wait_event_interruptible(*sk_sleep(sk), |
933 | (!skb_queue_empty(&sk->sk_receive_queue) || | 948 | (!skb_queue_empty(&sk->sk_receive_queue) || |
934 | (sock->state == SS_DISCONNECTING))); | 949 | (sock->state == SS_DISCONNECTING))); |
935 | lock_sock(sk); | 950 | lock_sock(sk); |
@@ -1024,9 +1039,8 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, | |||
1024 | struct sk_buff *buf; | 1039 | struct sk_buff *buf; |
1025 | struct tipc_msg *msg; | 1040 | struct tipc_msg *msg; |
1026 | unsigned int sz; | 1041 | unsigned int sz; |
1027 | int sz_to_copy; | 1042 | int sz_to_copy, target, needed; |
1028 | int sz_copied = 0; | 1043 | int sz_copied = 0; |
1029 | int needed; | ||
1030 | char __user *crs = m->msg_iov->iov_base; | 1044 | char __user *crs = m->msg_iov->iov_base; |
1031 | unsigned char *buf_crs; | 1045 | unsigned char *buf_crs; |
1032 | u32 err; | 1046 | u32 err; |
@@ -1048,6 +1062,8 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, | |||
1048 | goto exit; | 1062 | goto exit; |
1049 | } | 1063 | } |
1050 | 1064 | ||
1065 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); | ||
1066 | |||
1051 | restart: | 1067 | restart: |
1052 | 1068 | ||
1053 | /* Look for a message in receive queue; wait if necessary */ | 1069 | /* Look for a message in receive queue; wait if necessary */ |
@@ -1062,7 +1078,7 @@ restart: | |||
1062 | goto exit; | 1078 | goto exit; |
1063 | } | 1079 | } |
1064 | release_sock(sk); | 1080 | release_sock(sk); |
1065 | res = wait_event_interruptible(*sk->sk_sleep, | 1081 | res = wait_event_interruptible(*sk_sleep(sk), |
1066 | (!skb_queue_empty(&sk->sk_receive_queue) || | 1082 | (!skb_queue_empty(&sk->sk_receive_queue) || |
1067 | (sock->state == SS_DISCONNECTING))); | 1083 | (sock->state == SS_DISCONNECTING))); |
1068 | lock_sock(sk); | 1084 | lock_sock(sk); |
@@ -1134,13 +1150,11 @@ restart: | |||
1134 | 1150 | ||
1135 | /* Loop around if more data is required */ | 1151 | /* Loop around if more data is required */ |
1136 | 1152 | ||
1137 | if ((sz_copied < buf_len) /* didn't get all requested data */ | 1153 | if ((sz_copied < buf_len) && /* didn't get all requested data */ |
1138 | && (!skb_queue_empty(&sk->sk_receive_queue) || | 1154 | (!skb_queue_empty(&sk->sk_receive_queue) || |
1139 | (flags & MSG_WAITALL)) | 1155 | (sz_copied < target)) && /* and more is ready or required */ |
1140 | /* ... and more is ready or required */ | 1156 | (!(flags & MSG_PEEK)) && /* and aren't just peeking at data */ |
1141 | && (!(flags & MSG_PEEK)) /* ... and aren't just peeking at data */ | 1157 | (!err)) /* and haven't reached a FIN */ |
1142 | && (!err) /* ... and haven't reached a FIN */ | ||
1143 | ) | ||
1144 | goto restart; | 1158 | goto restart; |
1145 | 1159 | ||
1146 | exit: | 1160 | exit: |
@@ -1174,7 +1188,7 @@ static int rx_queue_full(struct tipc_msg *msg, u32 queue_size, u32 base) | |||
1174 | if (msg_connected(msg)) | 1188 | if (msg_connected(msg)) |
1175 | threshold *= 4; | 1189 | threshold *= 4; |
1176 | 1190 | ||
1177 | return (queue_size >= threshold); | 1191 | return queue_size >= threshold; |
1178 | } | 1192 | } |
1179 | 1193 | ||
1180 | /** | 1194 | /** |
@@ -1205,42 +1219,25 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf) | |||
1205 | */ | 1219 | */ |
1206 | 1220 | ||
1207 | if (sock->state == SS_READY) { | 1221 | if (sock->state == SS_READY) { |
1208 | if (msg_connected(msg)) { | 1222 | if (msg_connected(msg)) |
1209 | msg_dbg(msg, "dispatch filter 1\n"); | ||
1210 | return TIPC_ERR_NO_PORT; | 1223 | return TIPC_ERR_NO_PORT; |
1211 | } | ||
1212 | } else { | 1224 | } else { |
1213 | if (msg_mcast(msg)) { | 1225 | if (msg_mcast(msg)) |
1214 | msg_dbg(msg, "dispatch filter 2\n"); | ||
1215 | return TIPC_ERR_NO_PORT; | 1226 | return TIPC_ERR_NO_PORT; |
1216 | } | ||
1217 | if (sock->state == SS_CONNECTED) { | 1227 | if (sock->state == SS_CONNECTED) { |
1218 | if (!msg_connected(msg)) { | 1228 | if (!msg_connected(msg)) |
1219 | msg_dbg(msg, "dispatch filter 3\n"); | ||
1220 | return TIPC_ERR_NO_PORT; | 1229 | return TIPC_ERR_NO_PORT; |
1221 | } | 1230 | } else if (sock->state == SS_CONNECTING) { |
1222 | } | 1231 | if (!msg_connected(msg) && (msg_errcode(msg) == 0)) |
1223 | else if (sock->state == SS_CONNECTING) { | ||
1224 | if (!msg_connected(msg) && (msg_errcode(msg) == 0)) { | ||
1225 | msg_dbg(msg, "dispatch filter 4\n"); | ||
1226 | return TIPC_ERR_NO_PORT; | 1232 | return TIPC_ERR_NO_PORT; |
1227 | } | 1233 | } else if (sock->state == SS_LISTENING) { |
1228 | } | 1234 | if (msg_connected(msg) || msg_errcode(msg)) |
1229 | else if (sock->state == SS_LISTENING) { | ||
1230 | if (msg_connected(msg) || msg_errcode(msg)) { | ||
1231 | msg_dbg(msg, "dispatch filter 5\n"); | ||
1232 | return TIPC_ERR_NO_PORT; | 1235 | return TIPC_ERR_NO_PORT; |
1233 | } | 1236 | } else if (sock->state == SS_DISCONNECTING) { |
1234 | } | ||
1235 | else if (sock->state == SS_DISCONNECTING) { | ||
1236 | msg_dbg(msg, "dispatch filter 6\n"); | ||
1237 | return TIPC_ERR_NO_PORT; | 1237 | return TIPC_ERR_NO_PORT; |
1238 | } | 1238 | } else /* (sock->state == SS_UNCONNECTED) */ { |
1239 | else /* (sock->state == SS_UNCONNECTED) */ { | 1239 | if (msg_connected(msg) || msg_errcode(msg)) |
1240 | if (msg_connected(msg) || msg_errcode(msg)) { | ||
1241 | msg_dbg(msg, "dispatch filter 7\n"); | ||
1242 | return TIPC_ERR_NO_PORT; | 1240 | return TIPC_ERR_NO_PORT; |
1243 | } | ||
1244 | } | 1241 | } |
1245 | } | 1242 | } |
1246 | 1243 | ||
@@ -1259,7 +1256,6 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf) | |||
1259 | 1256 | ||
1260 | /* Enqueue message (finally!) */ | 1257 | /* Enqueue message (finally!) */ |
1261 | 1258 | ||
1262 | msg_dbg(msg, "<DISP<: "); | ||
1263 | TIPC_SKB_CB(buf)->handle = msg_data(msg); | 1259 | TIPC_SKB_CB(buf)->handle = msg_data(msg); |
1264 | atomic_inc(&tipc_queue_size); | 1260 | atomic_inc(&tipc_queue_size); |
1265 | __skb_queue_tail(&sk->sk_receive_queue, buf); | 1261 | __skb_queue_tail(&sk->sk_receive_queue, buf); |
@@ -1271,8 +1267,8 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf) | |||
1271 | tipc_disconnect_port(tipc_sk_port(sk)); | 1267 | tipc_disconnect_port(tipc_sk_port(sk)); |
1272 | } | 1268 | } |
1273 | 1269 | ||
1274 | if (waitqueue_active(sk->sk_sleep)) | 1270 | if (waitqueue_active(sk_sleep(sk))) |
1275 | wake_up_interruptible(sk->sk_sleep); | 1271 | wake_up_interruptible(sk_sleep(sk)); |
1276 | return TIPC_OK; | 1272 | return TIPC_OK; |
1277 | } | 1273 | } |
1278 | 1274 | ||
@@ -1322,8 +1318,10 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf) | |||
1322 | if (!sock_owned_by_user(sk)) { | 1318 | if (!sock_owned_by_user(sk)) { |
1323 | res = filter_rcv(sk, buf); | 1319 | res = filter_rcv(sk, buf); |
1324 | } else { | 1320 | } else { |
1325 | sk_add_backlog(sk, buf); | 1321 | if (sk_add_backlog(sk, buf)) |
1326 | res = TIPC_OK; | 1322 | res = TIPC_ERR_OVERLOAD; |
1323 | else | ||
1324 | res = TIPC_OK; | ||
1327 | } | 1325 | } |
1328 | bh_unlock_sock(sk); | 1326 | bh_unlock_sock(sk); |
1329 | 1327 | ||
@@ -1341,8 +1339,8 @@ static void wakeupdispatch(struct tipc_port *tport) | |||
1341 | { | 1339 | { |
1342 | struct sock *sk = (struct sock *)tport->usr_handle; | 1340 | struct sock *sk = (struct sock *)tport->usr_handle; |
1343 | 1341 | ||
1344 | if (waitqueue_active(sk->sk_sleep)) | 1342 | if (waitqueue_active(sk_sleep(sk))) |
1345 | wake_up_interruptible(sk->sk_sleep); | 1343 | wake_up_interruptible(sk_sleep(sk)); |
1346 | } | 1344 | } |
1347 | 1345 | ||
1348 | /** | 1346 | /** |
@@ -1363,6 +1361,7 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, | |||
1363 | struct msghdr m = {NULL,}; | 1361 | struct msghdr m = {NULL,}; |
1364 | struct sk_buff *buf; | 1362 | struct sk_buff *buf; |
1365 | struct tipc_msg *msg; | 1363 | struct tipc_msg *msg; |
1364 | long timeout; | ||
1366 | int res; | 1365 | int res; |
1367 | 1366 | ||
1368 | lock_sock(sk); | 1367 | lock_sock(sk); |
@@ -1377,7 +1376,7 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, | |||
1377 | /* For now, TIPC does not support the non-blocking form of connect() */ | 1376 | /* For now, TIPC does not support the non-blocking form of connect() */ |
1378 | 1377 | ||
1379 | if (flags & O_NONBLOCK) { | 1378 | if (flags & O_NONBLOCK) { |
1380 | res = -EWOULDBLOCK; | 1379 | res = -EOPNOTSUPP; |
1381 | goto exit; | 1380 | goto exit; |
1382 | } | 1381 | } |
1383 | 1382 | ||
@@ -1417,17 +1416,17 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, | |||
1417 | m.msg_name = dest; | 1416 | m.msg_name = dest; |
1418 | m.msg_namelen = destlen; | 1417 | m.msg_namelen = destlen; |
1419 | res = send_msg(NULL, sock, &m, 0); | 1418 | res = send_msg(NULL, sock, &m, 0); |
1420 | if (res < 0) { | 1419 | if (res < 0) |
1421 | goto exit; | 1420 | goto exit; |
1422 | } | ||
1423 | 1421 | ||
1424 | /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ | 1422 | /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ |
1425 | 1423 | ||
1424 | timeout = tipc_sk(sk)->conn_timeout; | ||
1426 | release_sock(sk); | 1425 | release_sock(sk); |
1427 | res = wait_event_interruptible_timeout(*sk->sk_sleep, | 1426 | res = wait_event_interruptible_timeout(*sk_sleep(sk), |
1428 | (!skb_queue_empty(&sk->sk_receive_queue) || | 1427 | (!skb_queue_empty(&sk->sk_receive_queue) || |
1429 | (sock->state != SS_CONNECTING)), | 1428 | (sock->state != SS_CONNECTING)), |
1430 | sk->sk_rcvtimeo); | 1429 | timeout ? timeout : MAX_SCHEDULE_TIMEOUT); |
1431 | lock_sock(sk); | 1430 | lock_sock(sk); |
1432 | 1431 | ||
1433 | if (res > 0) { | 1432 | if (res > 0) { |
@@ -1440,11 +1439,10 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, | |||
1440 | advance_rx_queue(sk); | 1439 | advance_rx_queue(sk); |
1441 | } | 1440 | } |
1442 | } else { | 1441 | } else { |
1443 | if (sock->state == SS_CONNECTED) { | 1442 | if (sock->state == SS_CONNECTED) |
1444 | res = -EISCONN; | 1443 | res = -EISCONN; |
1445 | } else { | 1444 | else |
1446 | res = -ECONNREFUSED; | 1445 | res = -ECONNREFUSED; |
1447 | } | ||
1448 | } | 1446 | } |
1449 | } else { | 1447 | } else { |
1450 | if (res == 0) | 1448 | if (res == 0) |
@@ -1519,7 +1517,7 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) | |||
1519 | goto exit; | 1517 | goto exit; |
1520 | } | 1518 | } |
1521 | release_sock(sk); | 1519 | release_sock(sk); |
1522 | res = wait_event_interruptible(*sk->sk_sleep, | 1520 | res = wait_event_interruptible(*sk_sleep(sk), |
1523 | (!skb_queue_empty(&sk->sk_receive_queue))); | 1521 | (!skb_queue_empty(&sk->sk_receive_queue))); |
1524 | lock_sock(sk); | 1522 | lock_sock(sk); |
1525 | if (res) | 1523 | if (res) |
@@ -1528,7 +1526,7 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) | |||
1528 | 1526 | ||
1529 | buf = skb_peek(&sk->sk_receive_queue); | 1527 | buf = skb_peek(&sk->sk_receive_queue); |
1530 | 1528 | ||
1531 | res = tipc_create(sock_net(sock->sk), new_sock, 0); | 1529 | res = tipc_create(sock_net(sock->sk), new_sock, 0, 0); |
1532 | if (!res) { | 1530 | if (!res) { |
1533 | struct sock *new_sk = new_sock->sk; | 1531 | struct sock *new_sk = new_sock->sk; |
1534 | struct tipc_sock *new_tsock = tipc_sk(new_sk); | 1532 | struct tipc_sock *new_tsock = tipc_sk(new_sk); |
@@ -1563,7 +1561,6 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) | |||
1563 | * Respond to 'SYN+' by queuing it on new socket. | 1561 | * Respond to 'SYN+' by queuing it on new socket. |
1564 | */ | 1562 | */ |
1565 | 1563 | ||
1566 | msg_dbg(msg,"<ACC<: "); | ||
1567 | if (!msg_data_sz(msg)) { | 1564 | if (!msg_data_sz(msg)) { |
1568 | struct msghdr m = {NULL,}; | 1565 | struct msghdr m = {NULL,}; |
1569 | 1566 | ||
@@ -1630,8 +1627,8 @@ restart: | |||
1630 | /* Discard any unreceived messages; wake up sleeping tasks */ | 1627 | /* Discard any unreceived messages; wake up sleeping tasks */ |
1631 | 1628 | ||
1632 | discard_rx_queue(sk); | 1629 | discard_rx_queue(sk); |
1633 | if (waitqueue_active(sk->sk_sleep)) | 1630 | if (waitqueue_active(sk_sleep(sk))) |
1634 | wake_up_interruptible(sk->sk_sleep); | 1631 | wake_up_interruptible(sk_sleep(sk)); |
1635 | res = 0; | 1632 | res = 0; |
1636 | break; | 1633 | break; |
1637 | 1634 | ||
@@ -1658,7 +1655,7 @@ restart: | |||
1658 | */ | 1655 | */ |
1659 | 1656 | ||
1660 | static int setsockopt(struct socket *sock, | 1657 | static int setsockopt(struct socket *sock, |
1661 | int lvl, int opt, char __user *ov, int ol) | 1658 | int lvl, int opt, char __user *ov, unsigned int ol) |
1662 | { | 1659 | { |
1663 | struct sock *sk = sock->sk; | 1660 | struct sock *sk = sock->sk; |
1664 | struct tipc_port *tport = tipc_sk_port(sk); | 1661 | struct tipc_port *tport = tipc_sk_port(sk); |
@@ -1671,7 +1668,8 @@ static int setsockopt(struct socket *sock, | |||
1671 | return -ENOPROTOOPT; | 1668 | return -ENOPROTOOPT; |
1672 | if (ol < sizeof(value)) | 1669 | if (ol < sizeof(value)) |
1673 | return -EINVAL; | 1670 | return -EINVAL; |
1674 | if ((res = get_user(value, (u32 __user *)ov))) | 1671 | res = get_user(value, (u32 __user *)ov); |
1672 | if (res) | ||
1675 | return res; | 1673 | return res; |
1676 | 1674 | ||
1677 | lock_sock(sk); | 1675 | lock_sock(sk); |
@@ -1690,7 +1688,7 @@ static int setsockopt(struct socket *sock, | |||
1690 | res = tipc_set_portunreturnable(tport->ref, value); | 1688 | res = tipc_set_portunreturnable(tport->ref, value); |
1691 | break; | 1689 | break; |
1692 | case TIPC_CONN_TIMEOUT: | 1690 | case TIPC_CONN_TIMEOUT: |
1693 | sk->sk_rcvtimeo = msecs_to_jiffies(value); | 1691 | tipc_sk(sk)->conn_timeout = msecs_to_jiffies(value); |
1694 | /* no need to set "res", since already 0 at this point */ | 1692 | /* no need to set "res", since already 0 at this point */ |
1695 | break; | 1693 | break; |
1696 | default: | 1694 | default: |
@@ -1729,7 +1727,8 @@ static int getsockopt(struct socket *sock, | |||
1729 | return put_user(0, ol); | 1727 | return put_user(0, ol); |
1730 | if (lvl != SOL_TIPC) | 1728 | if (lvl != SOL_TIPC) |
1731 | return -ENOPROTOOPT; | 1729 | return -ENOPROTOOPT; |
1732 | if ((res = get_user(len, ol))) | 1730 | res = get_user(len, ol); |
1731 | if (res) | ||
1733 | return res; | 1732 | return res; |
1734 | 1733 | ||
1735 | lock_sock(sk); | 1734 | lock_sock(sk); |
@@ -1745,29 +1744,31 @@ static int getsockopt(struct socket *sock, | |||
1745 | res = tipc_portunreturnable(tport->ref, &value); | 1744 | res = tipc_portunreturnable(tport->ref, &value); |
1746 | break; | 1745 | break; |
1747 | case TIPC_CONN_TIMEOUT: | 1746 | case TIPC_CONN_TIMEOUT: |
1748 | value = jiffies_to_msecs(sk->sk_rcvtimeo); | 1747 | value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout); |
1749 | /* no need to set "res", since already 0 at this point */ | 1748 | /* no need to set "res", since already 0 at this point */ |
1750 | break; | 1749 | break; |
1750 | case TIPC_NODE_RECVQ_DEPTH: | ||
1751 | value = (u32)atomic_read(&tipc_queue_size); | ||
1752 | break; | ||
1753 | case TIPC_SOCK_RECVQ_DEPTH: | ||
1754 | value = skb_queue_len(&sk->sk_receive_queue); | ||
1755 | break; | ||
1751 | default: | 1756 | default: |
1752 | res = -EINVAL; | 1757 | res = -EINVAL; |
1753 | } | 1758 | } |
1754 | 1759 | ||
1755 | release_sock(sk); | 1760 | release_sock(sk); |
1756 | 1761 | ||
1757 | if (res) { | 1762 | if (res) |
1758 | /* "get" failed */ | 1763 | return res; /* "get" failed */ |
1759 | } | ||
1760 | else if (len < sizeof(value)) { | ||
1761 | res = -EINVAL; | ||
1762 | } | ||
1763 | else if (copy_to_user(ov, &value, sizeof(value))) { | ||
1764 | res = -EFAULT; | ||
1765 | } | ||
1766 | else { | ||
1767 | res = put_user(sizeof(value), ol); | ||
1768 | } | ||
1769 | 1764 | ||
1770 | return res; | 1765 | if (len < sizeof(value)) |
1766 | return -EINVAL; | ||
1767 | |||
1768 | if (copy_to_user(ov, &value, sizeof(value))) | ||
1769 | return -EFAULT; | ||
1770 | |||
1771 | return put_user(sizeof(value), ol); | ||
1771 | } | 1772 | } |
1772 | 1773 | ||
1773 | /** | 1774 | /** |
@@ -1775,7 +1776,7 @@ static int getsockopt(struct socket *sock, | |||
1775 | */ | 1776 | */ |
1776 | 1777 | ||
1777 | static const struct proto_ops msg_ops = { | 1778 | static const struct proto_ops msg_ops = { |
1778 | .owner = THIS_MODULE, | 1779 | .owner = THIS_MODULE, |
1779 | .family = AF_TIPC, | 1780 | .family = AF_TIPC, |
1780 | .release = release, | 1781 | .release = release, |
1781 | .bind = bind, | 1782 | .bind = bind, |
@@ -1796,7 +1797,7 @@ static const struct proto_ops msg_ops = { | |||
1796 | }; | 1797 | }; |
1797 | 1798 | ||
1798 | static const struct proto_ops packet_ops = { | 1799 | static const struct proto_ops packet_ops = { |
1799 | .owner = THIS_MODULE, | 1800 | .owner = THIS_MODULE, |
1800 | .family = AF_TIPC, | 1801 | .family = AF_TIPC, |
1801 | .release = release, | 1802 | .release = release, |
1802 | .bind = bind, | 1803 | .bind = bind, |
@@ -1817,7 +1818,7 @@ static const struct proto_ops packet_ops = { | |||
1817 | }; | 1818 | }; |
1818 | 1819 | ||
1819 | static const struct proto_ops stream_ops = { | 1820 | static const struct proto_ops stream_ops = { |
1820 | .owner = THIS_MODULE, | 1821 | .owner = THIS_MODULE, |
1821 | .family = AF_TIPC, | 1822 | .family = AF_TIPC, |
1822 | .release = release, | 1823 | .release = release, |
1823 | .bind = bind, | 1824 | .bind = bind, |
@@ -1838,7 +1839,7 @@ static const struct proto_ops stream_ops = { | |||
1838 | }; | 1839 | }; |
1839 | 1840 | ||
1840 | static const struct net_proto_family tipc_family_ops = { | 1841 | static const struct net_proto_family tipc_family_ops = { |
1841 | .owner = THIS_MODULE, | 1842 | .owner = THIS_MODULE, |
1842 | .family = AF_TIPC, | 1843 | .family = AF_TIPC, |
1843 | .create = tipc_create | 1844 | .create = tipc_create |
1844 | }; | 1845 | }; |