diff options
| author | Anton Vorontsov <cbouatmailru@gmail.com> | 2008-07-29 18:05:23 -0400 |
|---|---|---|
| committer | Anton Vorontsov <cbouatmailru@gmail.com> | 2008-07-29 18:05:23 -0400 |
| commit | 9fec6060d9e48ed7db0dac0e16d0f0f0e615b7f6 (patch) | |
| tree | 74b41f31a08f6500ff3dfcf64ba21e2d9a8e87e5 /net/tipc/socket.c | |
| parent | fece418418f51e92dd7e67e17c5e3fe5a28d3279 (diff) | |
| parent | 6e86841d05f371b5b9b86ce76c02aaee83352298 (diff) | |
Merge branch 'master' of /home/cbou/linux-2.6
Conflicts:
drivers/power/Kconfig
drivers/power/Makefile
Diffstat (limited to 'net/tipc/socket.c')
| -rw-r--r-- | net/tipc/socket.c | 62 |
1 files changed, 33 insertions, 29 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 230f9ca2ad6b..1848693ebb82 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * net/tipc/socket.c: TIPC socket API | 2 | * net/tipc/socket.c: TIPC socket API |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2001-2007, Ericsson AB | 4 | * Copyright (c) 2001-2007, Ericsson AB |
| 5 | * Copyright (c) 2004-2007, Wind River Systems | 5 | * Copyright (c) 2004-2008, 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 |
| @@ -63,6 +63,7 @@ | |||
| 63 | struct tipc_sock { | 63 | 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 | }; | 67 | }; |
| 67 | 68 | ||
| 68 | #define tipc_sk(sk) ((struct tipc_sock *)(sk)) | 69 | #define tipc_sk(sk) ((struct tipc_sock *)(sk)) |
| @@ -188,7 +189,7 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol) | |||
| 188 | const struct proto_ops *ops; | 189 | const struct proto_ops *ops; |
| 189 | socket_state state; | 190 | socket_state state; |
| 190 | struct sock *sk; | 191 | struct sock *sk; |
| 191 | u32 portref; | 192 | struct tipc_port *tp_ptr; |
| 192 | 193 | ||
| 193 | /* Validate arguments */ | 194 | /* Validate arguments */ |
| 194 | 195 | ||
| @@ -224,9 +225,9 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol) | |||
| 224 | 225 | ||
| 225 | /* Allocate TIPC port for socket to use */ | 226 | /* Allocate TIPC port for socket to use */ |
| 226 | 227 | ||
| 227 | portref = tipc_createport_raw(sk, &dispatch, &wakeupdispatch, | 228 | tp_ptr = tipc_createport_raw(sk, &dispatch, &wakeupdispatch, |
| 228 | TIPC_LOW_IMPORTANCE); | 229 | TIPC_LOW_IMPORTANCE); |
| 229 | if (unlikely(portref == 0)) { | 230 | if (unlikely(!tp_ptr)) { |
| 230 | sk_free(sk); | 231 | sk_free(sk); |
| 231 | return -ENOMEM; | 232 | return -ENOMEM; |
| 232 | } | 233 | } |
| @@ -239,12 +240,14 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol) | |||
| 239 | sock_init_data(sock, sk); | 240 | sock_init_data(sock, sk); |
| 240 | sk->sk_rcvtimeo = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT); | 241 | sk->sk_rcvtimeo = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT); |
| 241 | sk->sk_backlog_rcv = backlog_rcv; | 242 | sk->sk_backlog_rcv = backlog_rcv; |
| 242 | tipc_sk(sk)->p = tipc_get_port(portref); | 243 | tipc_sk(sk)->p = tp_ptr; |
| 244 | |||
| 245 | spin_unlock_bh(tp_ptr->lock); | ||
| 243 | 246 | ||
| 244 | if (sock->state == SS_READY) { | 247 | if (sock->state == SS_READY) { |
| 245 | tipc_set_portunreturnable(portref, 1); | 248 | tipc_set_portunreturnable(tp_ptr->ref, 1); |
| 246 | if (sock->type == SOCK_DGRAM) | 249 | if (sock->type == SOCK_DGRAM) |
| 247 | tipc_set_portunreliable(portref, 1); | 250 | tipc_set_portunreliable(tp_ptr->ref, 1); |
| 248 | } | 251 | } |
| 249 | 252 | ||
| 250 | atomic_inc(&tipc_user_count); | 253 | atomic_inc(&tipc_user_count); |
| @@ -375,27 +378,29 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) | |||
| 375 | * @sock: socket structure | 378 | * @sock: socket structure |
| 376 | * @uaddr: area for returned socket address | 379 | * @uaddr: area for returned socket address |
| 377 | * @uaddr_len: area for returned length of socket address | 380 | * @uaddr_len: area for returned length of socket address |
| 378 | * @peer: 0 to obtain socket name, 1 to obtain peer socket name | 381 | * @peer: 0 = own ID, 1 = current peer ID, 2 = current/former peer ID |
| 379 | * | 382 | * |
| 380 | * Returns 0 on success, errno otherwise | 383 | * Returns 0 on success, errno otherwise |
| 381 | * | 384 | * |
| 382 | * NOTE: This routine doesn't need to take the socket lock since it doesn't | 385 | * NOTE: This routine doesn't need to take the socket lock since it only |
| 383 | * access any non-constant socket information. | 386 | * accesses socket information that is unchanging (or which changes in |
| 387 | * a completely predictable manner). | ||
| 384 | */ | 388 | */ |
| 385 | 389 | ||
| 386 | static int get_name(struct socket *sock, struct sockaddr *uaddr, | 390 | static int get_name(struct socket *sock, struct sockaddr *uaddr, |
| 387 | int *uaddr_len, int peer) | 391 | int *uaddr_len, int peer) |
| 388 | { | 392 | { |
| 389 | struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; | 393 | struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; |
| 390 | u32 portref = tipc_sk_port(sock->sk)->ref; | 394 | struct tipc_sock *tsock = tipc_sk(sock->sk); |
| 391 | u32 res; | ||
| 392 | 395 | ||
| 393 | if (peer) { | 396 | if (peer) { |
| 394 | res = tipc_peer(portref, &addr->addr.id); | 397 | if ((sock->state != SS_CONNECTED) && |
| 395 | if (res) | 398 | ((peer != 2) || (sock->state != SS_DISCONNECTING))) |
| 396 | return res; | 399 | return -ENOTCONN; |
| 400 | addr->addr.id.ref = tsock->peer_name.ref; | ||
| 401 | addr->addr.id.node = tsock->peer_name.node; | ||
| 397 | } else { | 402 | } else { |
| 398 | tipc_ownidentity(portref, &addr->addr.id); | 403 | tipc_ownidentity(tsock->p->ref, &addr->addr.id); |
| 399 | } | 404 | } |
| 400 | 405 | ||
| 401 | *uaddr_len = sizeof(*addr); | 406 | *uaddr_len = sizeof(*addr); |
| @@ -764,18 +769,17 @@ exit: | |||
| 764 | 769 | ||
| 765 | static int auto_connect(struct socket *sock, struct tipc_msg *msg) | 770 | static int auto_connect(struct socket *sock, struct tipc_msg *msg) |
| 766 | { | 771 | { |
| 767 | struct tipc_port *tport = tipc_sk_port(sock->sk); | 772 | struct tipc_sock *tsock = tipc_sk(sock->sk); |
| 768 | struct tipc_portid peer; | ||
| 769 | 773 | ||
| 770 | if (msg_errcode(msg)) { | 774 | if (msg_errcode(msg)) { |
| 771 | sock->state = SS_DISCONNECTING; | 775 | sock->state = SS_DISCONNECTING; |
| 772 | return -ECONNREFUSED; | 776 | return -ECONNREFUSED; |
| 773 | } | 777 | } |
| 774 | 778 | ||
| 775 | peer.ref = msg_origport(msg); | 779 | tsock->peer_name.ref = msg_origport(msg); |
| 776 | peer.node = msg_orignode(msg); | 780 | tsock->peer_name.node = msg_orignode(msg); |
| 777 | tipc_connect2port(tport->ref, &peer); | 781 | tipc_connect2port(tsock->p->ref, &tsock->peer_name); |
| 778 | tipc_set_portimportance(tport->ref, msg_importance(msg)); | 782 | tipc_set_portimportance(tsock->p->ref, msg_importance(msg)); |
| 779 | sock->state = SS_CONNECTED; | 783 | sock->state = SS_CONNECTED; |
| 780 | return 0; | 784 | return 0; |
| 781 | } | 785 | } |
| @@ -1131,7 +1135,7 @@ restart: | |||
| 1131 | /* Loop around if more data is required */ | 1135 | /* Loop around if more data is required */ |
| 1132 | 1136 | ||
| 1133 | if ((sz_copied < buf_len) /* didn't get all requested data */ | 1137 | if ((sz_copied < buf_len) /* didn't get all requested data */ |
| 1134 | && (!skb_queue_empty(&sock->sk->sk_receive_queue) || | 1138 | && (!skb_queue_empty(&sk->sk_receive_queue) || |
| 1135 | (flags & MSG_WAITALL)) | 1139 | (flags & MSG_WAITALL)) |
| 1136 | /* ... and more is ready or required */ | 1140 | /* ... and more is ready or required */ |
| 1137 | && (!(flags & MSG_PEEK)) /* ... and aren't just peeking at data */ | 1141 | && (!(flags & MSG_PEEK)) /* ... and aren't just peeking at data */ |
| @@ -1527,9 +1531,9 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) | |||
| 1527 | res = tipc_create(sock_net(sock->sk), new_sock, 0); | 1531 | res = tipc_create(sock_net(sock->sk), new_sock, 0); |
| 1528 | if (!res) { | 1532 | if (!res) { |
| 1529 | struct sock *new_sk = new_sock->sk; | 1533 | struct sock *new_sk = new_sock->sk; |
| 1530 | struct tipc_port *new_tport = tipc_sk_port(new_sk); | 1534 | struct tipc_sock *new_tsock = tipc_sk(new_sk); |
| 1535 | struct tipc_port *new_tport = new_tsock->p; | ||
| 1531 | u32 new_ref = new_tport->ref; | 1536 | u32 new_ref = new_tport->ref; |
| 1532 | struct tipc_portid id; | ||
| 1533 | struct tipc_msg *msg = buf_msg(buf); | 1537 | struct tipc_msg *msg = buf_msg(buf); |
| 1534 | 1538 | ||
| 1535 | lock_sock(new_sk); | 1539 | lock_sock(new_sk); |
| @@ -1543,9 +1547,9 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) | |||
| 1543 | 1547 | ||
| 1544 | /* Connect new socket to it's peer */ | 1548 | /* Connect new socket to it's peer */ |
| 1545 | 1549 | ||
| 1546 | id.ref = msg_origport(msg); | 1550 | new_tsock->peer_name.ref = msg_origport(msg); |
| 1547 | id.node = msg_orignode(msg); | 1551 | new_tsock->peer_name.node = msg_orignode(msg); |
| 1548 | tipc_connect2port(new_ref, &id); | 1552 | tipc_connect2port(new_ref, &new_tsock->peer_name); |
| 1549 | new_sock->state = SS_CONNECTED; | 1553 | new_sock->state = SS_CONNECTED; |
| 1550 | 1554 | ||
| 1551 | tipc_set_portimportance(new_ref, msg_importance(msg)); | 1555 | tipc_set_portimportance(new_ref, msg_importance(msg)); |
