diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2010-12-09 12:17:25 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2010-12-09 12:17:25 -0500 |
commit | d834a9dcecae834cd6b2bc5e50e1907738d9cf6a (patch) | |
tree | 0589d753465d3fe359ba451ba6cb7798df03aaa2 /net/tipc/socket.c | |
parent | a38c5380ef9f088be9f49b6e4c5d80af8b1b5cd4 (diff) | |
parent | f658bcfb2607bf0808966a69cf74135ce98e5c2d (diff) |
Merge branch 'x86/amd-nb' into x86/apic-cleanups
Reason: apic cleanup series depends on x86/apic, x86/amd-nb x86/platform
Conflicts:
arch/x86/include/asm/io_apic.h
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 84 |
1 files changed, 54 insertions, 30 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 66e889ba48fd..e9f0d5004483 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -64,6 +64,7 @@ struct tipc_sock { | |||
64 | struct sock sk; | 64 | struct sock sk; |
65 | struct tipc_port *p; | 65 | struct tipc_port *p; |
66 | struct tipc_portid peer_name; | 66 | struct tipc_portid peer_name; |
67 | long conn_timeout; | ||
67 | }; | 68 | }; |
68 | 69 | ||
69 | #define tipc_sk(sk) ((struct tipc_sock *)(sk)) | 70 | #define tipc_sk(sk) ((struct tipc_sock *)(sk)) |
@@ -240,9 +241,9 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol, | |||
240 | sock->state = state; | 241 | sock->state = state; |
241 | 242 | ||
242 | sock_init_data(sock, sk); | 243 | sock_init_data(sock, sk); |
243 | sk->sk_rcvtimeo = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT); | ||
244 | sk->sk_backlog_rcv = backlog_rcv; | 244 | sk->sk_backlog_rcv = backlog_rcv; |
245 | tipc_sk(sk)->p = tp_ptr; | 245 | tipc_sk(sk)->p = tp_ptr; |
246 | tipc_sk(sk)->conn_timeout = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT); | ||
246 | 247 | ||
247 | spin_unlock_bh(tp_ptr->lock); | 248 | spin_unlock_bh(tp_ptr->lock); |
248 | 249 | ||
@@ -395,6 +396,7 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr, | |||
395 | struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; | 396 | struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; |
396 | struct tipc_sock *tsock = tipc_sk(sock->sk); | 397 | struct tipc_sock *tsock = tipc_sk(sock->sk); |
397 | 398 | ||
399 | memset(addr, 0, sizeof(*addr)); | ||
398 | if (peer) { | 400 | if (peer) { |
399 | if ((sock->state != SS_CONNECTED) && | 401 | if ((sock->state != SS_CONNECTED) && |
400 | ((peer != 2) || (sock->state != SS_DISCONNECTING))) | 402 | ((peer != 2) || (sock->state != SS_DISCONNECTING))) |
@@ -429,36 +431,55 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr, | |||
429 | * to handle any preventable race conditions, so TIPC will do the same ... | 431 | * to handle any preventable race conditions, so TIPC will do the same ... |
430 | * | 432 | * |
431 | * TIPC sets the returned events as follows: | 433 | * TIPC sets the returned events as follows: |
432 | * a) POLLRDNORM and POLLIN are set if the socket's receive queue is non-empty | 434 | * |
433 | * or if a connection-oriented socket is does not have an active connection | 435 | * socket state flags set |
434 | * (i.e. a read operation will not block). | 436 | * ------------ --------- |
435 | * b) POLLOUT is set except when a socket's connection has been terminated | 437 | * unconnected no read flags |
436 | * (i.e. a write operation will not block). | 438 | * no write flags |
437 | * c) POLLHUP is set when a socket's connection has been terminated. | 439 | * |
438 | * | 440 | * connecting POLLIN/POLLRDNORM if ACK/NACK in rx queue |
439 | * IMPORTANT: The fact that a read or write operation will not block does NOT | 441 | * no write flags |
440 | * imply that the operation will succeed! | 442 | * |
443 | * connected POLLIN/POLLRDNORM if data in rx queue | ||
444 | * POLLOUT if port is not congested | ||
445 | * | ||
446 | * disconnecting POLLIN/POLLRDNORM/POLLHUP | ||
447 | * no write flags | ||
448 | * | ||
449 | * listening POLLIN if SYN in rx queue | ||
450 | * no write flags | ||
451 | * | ||
452 | * ready POLLIN/POLLRDNORM if data in rx queue | ||
453 | * [connectionless] POLLOUT (since port cannot be congested) | ||
454 | * | ||
455 | * IMPORTANT: The fact that a read or write operation is indicated does NOT | ||
456 | * imply that the operation will succeed, merely that it should be performed | ||
457 | * and will not block. | ||
441 | */ | 458 | */ |
442 | 459 | ||
443 | static unsigned int poll(struct file *file, struct socket *sock, | 460 | static unsigned int poll(struct file *file, struct socket *sock, |
444 | poll_table *wait) | 461 | poll_table *wait) |
445 | { | 462 | { |
446 | struct sock *sk = sock->sk; | 463 | struct sock *sk = sock->sk; |
447 | u32 mask; | 464 | u32 mask = 0; |
448 | 465 | ||
449 | poll_wait(file, sk_sleep(sk), wait); | 466 | poll_wait(file, sk_sleep(sk), wait); |
450 | 467 | ||
451 | if (!skb_queue_empty(&sk->sk_receive_queue) || | 468 | switch ((int)sock->state) { |
452 | (sock->state == SS_UNCONNECTED) || | 469 | case SS_READY: |
453 | (sock->state == SS_DISCONNECTING)) | 470 | case SS_CONNECTED: |
454 | mask = (POLLRDNORM | POLLIN); | 471 | if (!tipc_sk_port(sk)->congested) |
455 | else | 472 | mask |= POLLOUT; |
456 | mask = 0; | 473 | /* fall thru' */ |
457 | 474 | case SS_CONNECTING: | |
458 | if (sock->state == SS_DISCONNECTING) | 475 | case SS_LISTENING: |
459 | mask |= POLLHUP; | 476 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
460 | else | 477 | mask |= (POLLIN | POLLRDNORM); |
461 | mask |= POLLOUT; | 478 | break; |
479 | case SS_DISCONNECTING: | ||
480 | mask = (POLLIN | POLLRDNORM | POLLHUP); | ||
481 | break; | ||
482 | } | ||
462 | 483 | ||
463 | return mask; | 484 | return mask; |
464 | } | 485 | } |
@@ -1026,9 +1047,8 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, | |||
1026 | struct sk_buff *buf; | 1047 | struct sk_buff *buf; |
1027 | struct tipc_msg *msg; | 1048 | struct tipc_msg *msg; |
1028 | unsigned int sz; | 1049 | unsigned int sz; |
1029 | int sz_to_copy; | 1050 | int sz_to_copy, target, needed; |
1030 | int sz_copied = 0; | 1051 | int sz_copied = 0; |
1031 | int needed; | ||
1032 | char __user *crs = m->msg_iov->iov_base; | 1052 | char __user *crs = m->msg_iov->iov_base; |
1033 | unsigned char *buf_crs; | 1053 | unsigned char *buf_crs; |
1034 | u32 err; | 1054 | u32 err; |
@@ -1050,6 +1070,8 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, | |||
1050 | goto exit; | 1070 | goto exit; |
1051 | } | 1071 | } |
1052 | 1072 | ||
1073 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); | ||
1074 | |||
1053 | restart: | 1075 | restart: |
1054 | 1076 | ||
1055 | /* Look for a message in receive queue; wait if necessary */ | 1077 | /* Look for a message in receive queue; wait if necessary */ |
@@ -1138,7 +1160,7 @@ restart: | |||
1138 | 1160 | ||
1139 | if ((sz_copied < buf_len) && /* didn't get all requested data */ | 1161 | if ((sz_copied < buf_len) && /* didn't get all requested data */ |
1140 | (!skb_queue_empty(&sk->sk_receive_queue) || | 1162 | (!skb_queue_empty(&sk->sk_receive_queue) || |
1141 | (flags & MSG_WAITALL)) && /* and more is ready or required */ | 1163 | (sz_copied < target)) && /* and more is ready or required */ |
1142 | (!(flags & MSG_PEEK)) && /* and aren't just peeking at data */ | 1164 | (!(flags & MSG_PEEK)) && /* and aren't just peeking at data */ |
1143 | (!err)) /* and haven't reached a FIN */ | 1165 | (!err)) /* and haven't reached a FIN */ |
1144 | goto restart; | 1166 | goto restart; |
@@ -1174,7 +1196,7 @@ static int rx_queue_full(struct tipc_msg *msg, u32 queue_size, u32 base) | |||
1174 | if (msg_connected(msg)) | 1196 | if (msg_connected(msg)) |
1175 | threshold *= 4; | 1197 | threshold *= 4; |
1176 | 1198 | ||
1177 | return (queue_size >= threshold); | 1199 | return queue_size >= threshold; |
1178 | } | 1200 | } |
1179 | 1201 | ||
1180 | /** | 1202 | /** |
@@ -1365,6 +1387,7 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, | |||
1365 | struct msghdr m = {NULL,}; | 1387 | struct msghdr m = {NULL,}; |
1366 | struct sk_buff *buf; | 1388 | struct sk_buff *buf; |
1367 | struct tipc_msg *msg; | 1389 | struct tipc_msg *msg; |
1390 | long timeout; | ||
1368 | int res; | 1391 | int res; |
1369 | 1392 | ||
1370 | lock_sock(sk); | 1393 | lock_sock(sk); |
@@ -1379,7 +1402,7 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, | |||
1379 | /* For now, TIPC does not support the non-blocking form of connect() */ | 1402 | /* For now, TIPC does not support the non-blocking form of connect() */ |
1380 | 1403 | ||
1381 | if (flags & O_NONBLOCK) { | 1404 | if (flags & O_NONBLOCK) { |
1382 | res = -EWOULDBLOCK; | 1405 | res = -EOPNOTSUPP; |
1383 | goto exit; | 1406 | goto exit; |
1384 | } | 1407 | } |
1385 | 1408 | ||
@@ -1425,11 +1448,12 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, | |||
1425 | 1448 | ||
1426 | /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ | 1449 | /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ |
1427 | 1450 | ||
1451 | timeout = tipc_sk(sk)->conn_timeout; | ||
1428 | release_sock(sk); | 1452 | release_sock(sk); |
1429 | res = wait_event_interruptible_timeout(*sk_sleep(sk), | 1453 | res = wait_event_interruptible_timeout(*sk_sleep(sk), |
1430 | (!skb_queue_empty(&sk->sk_receive_queue) || | 1454 | (!skb_queue_empty(&sk->sk_receive_queue) || |
1431 | (sock->state != SS_CONNECTING)), | 1455 | (sock->state != SS_CONNECTING)), |
1432 | sk->sk_rcvtimeo); | 1456 | timeout ? timeout : MAX_SCHEDULE_TIMEOUT); |
1433 | lock_sock(sk); | 1457 | lock_sock(sk); |
1434 | 1458 | ||
1435 | if (res > 0) { | 1459 | if (res > 0) { |
@@ -1692,7 +1716,7 @@ static int setsockopt(struct socket *sock, | |||
1692 | res = tipc_set_portunreturnable(tport->ref, value); | 1716 | res = tipc_set_portunreturnable(tport->ref, value); |
1693 | break; | 1717 | break; |
1694 | case TIPC_CONN_TIMEOUT: | 1718 | case TIPC_CONN_TIMEOUT: |
1695 | sk->sk_rcvtimeo = msecs_to_jiffies(value); | 1719 | tipc_sk(sk)->conn_timeout = msecs_to_jiffies(value); |
1696 | /* no need to set "res", since already 0 at this point */ | 1720 | /* no need to set "res", since already 0 at this point */ |
1697 | break; | 1721 | break; |
1698 | default: | 1722 | default: |
@@ -1747,7 +1771,7 @@ static int getsockopt(struct socket *sock, | |||
1747 | res = tipc_portunreturnable(tport->ref, &value); | 1771 | res = tipc_portunreturnable(tport->ref, &value); |
1748 | break; | 1772 | break; |
1749 | case TIPC_CONN_TIMEOUT: | 1773 | case TIPC_CONN_TIMEOUT: |
1750 | value = jiffies_to_msecs(sk->sk_rcvtimeo); | 1774 | value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout); |
1751 | /* no need to set "res", since already 0 at this point */ | 1775 | /* no need to set "res", since already 0 at this point */ |
1752 | break; | 1776 | break; |
1753 | case TIPC_NODE_RECVQ_DEPTH: | 1777 | case TIPC_NODE_RECVQ_DEPTH: |