diff options
Diffstat (limited to 'net/tipc')
| -rw-r--r-- | net/tipc/addr.c | 2 | ||||
| -rw-r--r-- | net/tipc/bcast.c | 41 | ||||
| -rw-r--r-- | net/tipc/bearer.c | 2 | ||||
| -rw-r--r-- | net/tipc/core.c | 6 | ||||
| -rw-r--r-- | net/tipc/dbg.c | 4 | ||||
| -rw-r--r-- | net/tipc/discover.c | 8 | ||||
| -rw-r--r-- | net/tipc/eth_media.c | 48 | ||||
| -rw-r--r-- | net/tipc/link.c | 31 | ||||
| -rw-r--r-- | net/tipc/link.h | 16 | ||||
| -rw-r--r-- | net/tipc/msg.h | 6 | ||||
| -rw-r--r-- | net/tipc/name_table.c | 50 | ||||
| -rw-r--r-- | net/tipc/net.c | 1 | ||||
| -rw-r--r-- | net/tipc/node.c | 28 | ||||
| -rw-r--r-- | net/tipc/node.h | 2 | ||||
| -rw-r--r-- | net/tipc/port.c | 19 | ||||
| -rw-r--r-- | net/tipc/port.h | 2 | ||||
| -rw-r--r-- | net/tipc/socket.c | 83 | ||||
| -rw-r--r-- | net/tipc/subscr.c | 2 |
18 files changed, 213 insertions, 138 deletions
diff --git a/net/tipc/addr.c b/net/tipc/addr.c index c048543ffbeb..2ddc351b3be9 100644 --- a/net/tipc/addr.c +++ b/net/tipc/addr.c | |||
| @@ -89,7 +89,7 @@ int tipc_addr_domain_valid(u32 addr) | |||
| 89 | 89 | ||
| 90 | int tipc_addr_node_valid(u32 addr) | 90 | int tipc_addr_node_valid(u32 addr) |
| 91 | { | 91 | { |
| 92 | return (tipc_addr_domain_valid(addr) && tipc_node(addr)); | 92 | return tipc_addr_domain_valid(addr) && tipc_node(addr); |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | int tipc_in_scope(u32 domain, u32 addr) | 95 | int tipc_in_scope(u32 domain, u32 addr) |
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index a008c6689305..ecfaac10d0b4 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
| @@ -143,6 +143,19 @@ static void bcbuf_decr_acks(struct sk_buff *buf) | |||
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | 145 | ||
| 146 | static void bclink_set_last_sent(void) | ||
| 147 | { | ||
| 148 | if (bcl->next_out) | ||
| 149 | bcl->fsm_msg_cnt = mod(buf_seqno(bcl->next_out) - 1); | ||
| 150 | else | ||
| 151 | bcl->fsm_msg_cnt = mod(bcl->next_out_no - 1); | ||
| 152 | } | ||
| 153 | |||
| 154 | u32 tipc_bclink_get_last_sent(void) | ||
| 155 | { | ||
| 156 | return bcl->fsm_msg_cnt; | ||
| 157 | } | ||
| 158 | |||
| 146 | /** | 159 | /** |
| 147 | * bclink_set_gap - set gap according to contents of current deferred pkt queue | 160 | * bclink_set_gap - set gap according to contents of current deferred pkt queue |
| 148 | * | 161 | * |
| @@ -171,7 +184,7 @@ static void bclink_set_gap(struct tipc_node *n_ptr) | |||
| 171 | 184 | ||
| 172 | static int bclink_ack_allowed(u32 n) | 185 | static int bclink_ack_allowed(u32 n) |
| 173 | { | 186 | { |
| 174 | return((n % TIPC_MIN_LINK_WIN) == tipc_own_tag); | 187 | return (n % TIPC_MIN_LINK_WIN) == tipc_own_tag; |
| 175 | } | 188 | } |
| 176 | 189 | ||
| 177 | 190 | ||
| @@ -237,8 +250,10 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked) | |||
| 237 | 250 | ||
| 238 | /* Try resolving broadcast link congestion, if necessary */ | 251 | /* Try resolving broadcast link congestion, if necessary */ |
| 239 | 252 | ||
| 240 | if (unlikely(bcl->next_out)) | 253 | if (unlikely(bcl->next_out)) { |
| 241 | tipc_link_push_queue(bcl); | 254 | tipc_link_push_queue(bcl); |
| 255 | bclink_set_last_sent(); | ||
| 256 | } | ||
| 242 | if (unlikely(released && !list_empty(&bcl->waiting_ports))) | 257 | if (unlikely(released && !list_empty(&bcl->waiting_ports))) |
| 243 | tipc_link_wakeup_ports(bcl, 0); | 258 | tipc_link_wakeup_ports(bcl, 0); |
| 244 | spin_unlock_bh(&bc_lock); | 259 | spin_unlock_bh(&bc_lock); |
| @@ -395,7 +410,7 @@ int tipc_bclink_send_msg(struct sk_buff *buf) | |||
| 395 | if (unlikely(res == -ELINKCONG)) | 410 | if (unlikely(res == -ELINKCONG)) |
| 396 | buf_discard(buf); | 411 | buf_discard(buf); |
| 397 | else | 412 | else |
| 398 | bcl->stats.sent_info++; | 413 | bclink_set_last_sent(); |
| 399 | 414 | ||
| 400 | if (bcl->out_queue_size > bcl->stats.max_queue_sz) | 415 | if (bcl->out_queue_size > bcl->stats.max_queue_sz) |
| 401 | bcl->stats.max_queue_sz = bcl->out_queue_size; | 416 | bcl->stats.max_queue_sz = bcl->out_queue_size; |
| @@ -529,15 +544,6 @@ receive: | |||
| 529 | tipc_node_unlock(node); | 544 | tipc_node_unlock(node); |
| 530 | } | 545 | } |
| 531 | 546 | ||
| 532 | u32 tipc_bclink_get_last_sent(void) | ||
| 533 | { | ||
| 534 | u32 last_sent = mod(bcl->next_out_no - 1); | ||
| 535 | |||
| 536 | if (bcl->next_out) | ||
| 537 | last_sent = mod(buf_seqno(bcl->next_out) - 1); | ||
| 538 | return last_sent; | ||
| 539 | } | ||
| 540 | |||
| 541 | u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr) | 547 | u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr) |
| 542 | { | 548 | { |
| 543 | return (n_ptr->bclink.supported && | 549 | return (n_ptr->bclink.supported && |
| @@ -570,6 +576,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
| 570 | msg = buf_msg(buf); | 576 | msg = buf_msg(buf); |
| 571 | msg_set_non_seq(msg, 1); | 577 | msg_set_non_seq(msg, 1); |
| 572 | msg_set_mc_netid(msg, tipc_net_id); | 578 | msg_set_mc_netid(msg, tipc_net_id); |
| 579 | bcl->stats.sent_info++; | ||
| 573 | } | 580 | } |
| 574 | 581 | ||
| 575 | /* Send buffer over bearers until all targets reached */ | 582 | /* Send buffer over bearers until all targets reached */ |
| @@ -609,11 +616,13 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
| 609 | bcbearer->remains = bcbearer->remains_new; | 616 | bcbearer->remains = bcbearer->remains_new; |
| 610 | } | 617 | } |
| 611 | 618 | ||
| 612 | /* Unable to reach all targets */ | 619 | /* |
| 620 | * Unable to reach all targets (indicate success, since currently | ||
| 621 | * there isn't code in place to properly block & unblock the | ||
| 622 | * pseudo-bearer used by the broadcast link) | ||
| 623 | */ | ||
| 613 | 624 | ||
| 614 | bcbearer->bearer.publ.blocked = 1; | 625 | return TIPC_OK; |
| 615 | bcl->stats.bearer_congs++; | ||
| 616 | return 1; | ||
| 617 | } | 626 | } |
| 618 | 627 | ||
| 619 | /** | 628 | /** |
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 52ae17b2583e..9c10c6b7c12b 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c | |||
| @@ -63,7 +63,7 @@ static int media_name_valid(const char *name) | |||
| 63 | len = strlen(name); | 63 | len = strlen(name); |
| 64 | if ((len + 1) > TIPC_MAX_MEDIA_NAME) | 64 | if ((len + 1) > TIPC_MAX_MEDIA_NAME) |
| 65 | return 0; | 65 | return 0; |
| 66 | return (strspn(name, tipc_alphabet) == len); | 66 | return strspn(name, tipc_alphabet) == len; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | /** | 69 | /** |
diff --git a/net/tipc/core.c b/net/tipc/core.c index 696468117985..466b861dab91 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c | |||
| @@ -169,6 +169,7 @@ void tipc_core_stop(void) | |||
| 169 | tipc_nametbl_stop(); | 169 | tipc_nametbl_stop(); |
| 170 | tipc_ref_table_stop(); | 170 | tipc_ref_table_stop(); |
| 171 | tipc_socket_stop(); | 171 | tipc_socket_stop(); |
| 172 | tipc_log_resize(0); | ||
| 172 | } | 173 | } |
| 173 | 174 | ||
| 174 | /** | 175 | /** |
| @@ -203,7 +204,9 @@ static int __init tipc_init(void) | |||
| 203 | { | 204 | { |
| 204 | int res; | 205 | int res; |
| 205 | 206 | ||
| 206 | tipc_log_resize(CONFIG_TIPC_LOG); | 207 | if (tipc_log_resize(CONFIG_TIPC_LOG) != 0) |
| 208 | warn("Unable to create log buffer\n"); | ||
| 209 | |||
| 207 | info("Activated (version " TIPC_MOD_VER | 210 | info("Activated (version " TIPC_MOD_VER |
| 208 | " compiled " __DATE__ " " __TIME__ ")\n"); | 211 | " compiled " __DATE__ " " __TIME__ ")\n"); |
| 209 | 212 | ||
| @@ -230,7 +233,6 @@ static void __exit tipc_exit(void) | |||
| 230 | tipc_core_stop_net(); | 233 | tipc_core_stop_net(); |
| 231 | tipc_core_stop(); | 234 | tipc_core_stop(); |
| 232 | info("Deactivated\n"); | 235 | info("Deactivated\n"); |
| 233 | tipc_log_resize(0); | ||
| 234 | } | 236 | } |
| 235 | 237 | ||
| 236 | module_init(tipc_init); | 238 | module_init(tipc_init); |
diff --git a/net/tipc/dbg.c b/net/tipc/dbg.c index 1885a7edb0c8..6569d45bfb9a 100644 --- a/net/tipc/dbg.c +++ b/net/tipc/dbg.c | |||
| @@ -134,7 +134,7 @@ void tipc_printbuf_reset(struct print_buf *pb) | |||
| 134 | 134 | ||
| 135 | int tipc_printbuf_empty(struct print_buf *pb) | 135 | int tipc_printbuf_empty(struct print_buf *pb) |
| 136 | { | 136 | { |
| 137 | return (!pb->buf || (pb->crs == pb->buf)); | 137 | return !pb->buf || (pb->crs == pb->buf); |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | /** | 140 | /** |
| @@ -169,7 +169,7 @@ int tipc_printbuf_validate(struct print_buf *pb) | |||
| 169 | tipc_printf(pb, err); | 169 | tipc_printf(pb, err); |
| 170 | } | 170 | } |
| 171 | } | 171 | } |
| 172 | return (pb->crs - pb->buf + 1); | 172 | return pb->crs - pb->buf + 1; |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | /** | 175 | /** |
diff --git a/net/tipc/discover.c b/net/tipc/discover.c index fc1fcf5e6b53..f28d1ae93125 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c | |||
| @@ -203,6 +203,14 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr) | |||
| 203 | return; | 203 | return; |
| 204 | } | 204 | } |
| 205 | spin_lock_bh(&n_ptr->lock); | 205 | spin_lock_bh(&n_ptr->lock); |
| 206 | |||
| 207 | /* Don't talk to neighbor during cleanup after last session */ | ||
| 208 | |||
| 209 | if (n_ptr->cleanup_required) { | ||
| 210 | spin_unlock_bh(&n_ptr->lock); | ||
| 211 | return; | ||
| 212 | } | ||
| 213 | |||
| 206 | link = n_ptr->links[b_ptr->identity]; | 214 | link = n_ptr->links[b_ptr->identity]; |
| 207 | if (!link) { | 215 | if (!link) { |
| 208 | dbg("creating link\n"); | 216 | dbg("creating link\n"); |
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c index 6230d16020c4..6e988ba485fd 100644 --- a/net/tipc/eth_media.c +++ b/net/tipc/eth_media.c | |||
| @@ -72,17 +72,26 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr, | |||
| 72 | { | 72 | { |
| 73 | struct sk_buff *clone; | 73 | struct sk_buff *clone; |
| 74 | struct net_device *dev; | 74 | struct net_device *dev; |
| 75 | int delta; | ||
| 75 | 76 | ||
| 76 | clone = skb_clone(buf, GFP_ATOMIC); | 77 | clone = skb_clone(buf, GFP_ATOMIC); |
| 77 | if (clone) { | 78 | if (!clone) |
| 78 | skb_reset_network_header(clone); | 79 | return 0; |
| 79 | dev = ((struct eth_bearer *)(tb_ptr->usr_handle))->dev; | 80 | |
| 80 | clone->dev = dev; | 81 | dev = ((struct eth_bearer *)(tb_ptr->usr_handle))->dev; |
| 81 | dev_hard_header(clone, dev, ETH_P_TIPC, | 82 | delta = dev->hard_header_len - skb_headroom(buf); |
| 82 | &dest->dev_addr.eth_addr, | 83 | |
| 83 | dev->dev_addr, clone->len); | 84 | if ((delta > 0) && |
| 84 | dev_queue_xmit(clone); | 85 | pskb_expand_head(clone, SKB_DATA_ALIGN(delta), 0, GFP_ATOMIC)) { |
| 86 | kfree_skb(clone); | ||
| 87 | return 0; | ||
| 85 | } | 88 | } |
| 89 | |||
| 90 | skb_reset_network_header(clone); | ||
| 91 | clone->dev = dev; | ||
| 92 | dev_hard_header(clone, dev, ETH_P_TIPC, &dest->dev_addr.eth_addr, | ||
| 93 | dev->dev_addr, clone->len); | ||
| 94 | dev_queue_xmit(clone); | ||
| 86 | return 0; | 95 | return 0; |
| 87 | } | 96 | } |
| 88 | 97 | ||
| @@ -92,15 +101,12 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr, | |||
| 92 | * Accept only packets explicitly sent to this node, or broadcast packets; | 101 | * Accept only packets explicitly sent to this node, or broadcast packets; |
| 93 | * ignores packets sent using Ethernet multicast, and traffic sent to other | 102 | * ignores packets sent using Ethernet multicast, and traffic sent to other |
| 94 | * nodes (which can happen if interface is running in promiscuous mode). | 103 | * nodes (which can happen if interface is running in promiscuous mode). |
| 95 | * Routine truncates any Ethernet padding/CRC appended to the message, | ||
| 96 | * and ensures message size matches actual length | ||
| 97 | */ | 104 | */ |
| 98 | 105 | ||
| 99 | static int recv_msg(struct sk_buff *buf, struct net_device *dev, | 106 | static int recv_msg(struct sk_buff *buf, struct net_device *dev, |
| 100 | struct packet_type *pt, struct net_device *orig_dev) | 107 | struct packet_type *pt, struct net_device *orig_dev) |
| 101 | { | 108 | { |
| 102 | struct eth_bearer *eb_ptr = (struct eth_bearer *)pt->af_packet_priv; | 109 | struct eth_bearer *eb_ptr = (struct eth_bearer *)pt->af_packet_priv; |
| 103 | u32 size; | ||
| 104 | 110 | ||
| 105 | if (!net_eq(dev_net(dev), &init_net)) { | 111 | if (!net_eq(dev_net(dev), &init_net)) { |
| 106 | kfree_skb(buf); | 112 | kfree_skb(buf); |
| @@ -109,13 +115,9 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev, | |||
| 109 | 115 | ||
| 110 | if (likely(eb_ptr->bearer)) { | 116 | if (likely(eb_ptr->bearer)) { |
| 111 | if (likely(buf->pkt_type <= PACKET_BROADCAST)) { | 117 | if (likely(buf->pkt_type <= PACKET_BROADCAST)) { |
| 112 | size = msg_size((struct tipc_msg *)buf->data); | 118 | buf->next = NULL; |
| 113 | skb_trim(buf, size); | 119 | tipc_recv_msg(buf, eb_ptr->bearer); |
| 114 | if (likely(buf->len == size)) { | 120 | return 0; |
| 115 | buf->next = NULL; | ||
| 116 | tipc_recv_msg(buf, eb_ptr->bearer); | ||
| 117 | return 0; | ||
| 118 | } | ||
| 119 | } | 121 | } |
| 120 | } | 122 | } |
| 121 | kfree_skb(buf); | 123 | kfree_skb(buf); |
| @@ -133,6 +135,16 @@ static int enable_bearer(struct tipc_bearer *tb_ptr) | |||
| 133 | struct eth_bearer *eb_ptr = ð_bearers[0]; | 135 | struct eth_bearer *eb_ptr = ð_bearers[0]; |
| 134 | struct eth_bearer *stop = ð_bearers[MAX_ETH_BEARERS]; | 136 | struct eth_bearer *stop = ð_bearers[MAX_ETH_BEARERS]; |
| 135 | char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1; | 137 | char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1; |
| 138 | int pending_dev = 0; | ||
| 139 | |||
| 140 | /* Find unused Ethernet bearer structure */ | ||
| 141 | |||
| 142 | while (eb_ptr->dev) { | ||
| 143 | if (!eb_ptr->bearer) | ||
| 144 | pending_dev++; | ||
| 145 | if (++eb_ptr == stop) | ||
| 146 | return pending_dev ? -EAGAIN : -EDQUOT; | ||
| 147 | } | ||
| 136 | 148 | ||
| 137 | /* Find device with specified name */ | 149 | /* Find device with specified name */ |
| 138 | 150 | ||
diff --git a/net/tipc/link.c b/net/tipc/link.c index a3616b99529b..b8cf1e9d0b86 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
| @@ -239,13 +239,13 @@ int tipc_link_is_up(struct link *l_ptr) | |||
| 239 | { | 239 | { |
| 240 | if (!l_ptr) | 240 | if (!l_ptr) |
| 241 | return 0; | 241 | return 0; |
| 242 | return (link_working_working(l_ptr) || link_working_unknown(l_ptr)); | 242 | return link_working_working(l_ptr) || link_working_unknown(l_ptr); |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | int tipc_link_is_active(struct link *l_ptr) | 245 | int tipc_link_is_active(struct link *l_ptr) |
| 246 | { | 246 | { |
| 247 | return ((l_ptr->owner->active_links[0] == l_ptr) || | 247 | return (l_ptr->owner->active_links[0] == l_ptr) || |
| 248 | (l_ptr->owner->active_links[1] == l_ptr)); | 248 | (l_ptr->owner->active_links[1] == l_ptr); |
| 249 | } | 249 | } |
| 250 | 250 | ||
| 251 | /** | 251 | /** |
| @@ -1802,6 +1802,15 @@ static int link_recv_buf_validate(struct sk_buff *buf) | |||
| 1802 | return pskb_may_pull(buf, hdr_size); | 1802 | return pskb_may_pull(buf, hdr_size); |
| 1803 | } | 1803 | } |
| 1804 | 1804 | ||
| 1805 | /** | ||
| 1806 | * tipc_recv_msg - process TIPC messages arriving from off-node | ||
| 1807 | * @head: pointer to message buffer chain | ||
| 1808 | * @tb_ptr: pointer to bearer message arrived on | ||
| 1809 | * | ||
| 1810 | * Invoked with no locks held. Bearer pointer must point to a valid bearer | ||
| 1811 | * structure (i.e. cannot be NULL), but bearer can be inactive. | ||
| 1812 | */ | ||
| 1813 | |||
| 1805 | void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) | 1814 | void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) |
| 1806 | { | 1815 | { |
| 1807 | read_lock_bh(&tipc_net_lock); | 1816 | read_lock_bh(&tipc_net_lock); |
| @@ -1819,6 +1828,11 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) | |||
| 1819 | 1828 | ||
| 1820 | head = head->next; | 1829 | head = head->next; |
| 1821 | 1830 | ||
| 1831 | /* Ensure bearer is still enabled */ | ||
| 1832 | |||
| 1833 | if (unlikely(!b_ptr->active)) | ||
| 1834 | goto cont; | ||
| 1835 | |||
| 1822 | /* Ensure message is well-formed */ | 1836 | /* Ensure message is well-formed */ |
| 1823 | 1837 | ||
| 1824 | if (unlikely(!link_recv_buf_validate(buf))) | 1838 | if (unlikely(!link_recv_buf_validate(buf))) |
| @@ -1855,13 +1869,22 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) | |||
| 1855 | goto cont; | 1869 | goto cont; |
| 1856 | } | 1870 | } |
| 1857 | 1871 | ||
| 1858 | /* Locate unicast link endpoint that should handle message */ | 1872 | /* Locate neighboring node that sent message */ |
| 1859 | 1873 | ||
| 1860 | n_ptr = tipc_node_find(msg_prevnode(msg)); | 1874 | n_ptr = tipc_node_find(msg_prevnode(msg)); |
| 1861 | if (unlikely(!n_ptr)) | 1875 | if (unlikely(!n_ptr)) |
| 1862 | goto cont; | 1876 | goto cont; |
| 1863 | tipc_node_lock(n_ptr); | 1877 | tipc_node_lock(n_ptr); |
| 1864 | 1878 | ||
| 1879 | /* Don't talk to neighbor during cleanup after last session */ | ||
| 1880 | |||
| 1881 | if (n_ptr->cleanup_required) { | ||
| 1882 | tipc_node_unlock(n_ptr); | ||
| 1883 | goto cont; | ||
| 1884 | } | ||
| 1885 | |||
| 1886 | /* Locate unicast link endpoint that should handle message */ | ||
| 1887 | |||
| 1865 | l_ptr = n_ptr->links[b_ptr->identity]; | 1888 | l_ptr = n_ptr->links[b_ptr->identity]; |
| 1866 | if (unlikely(!l_ptr)) { | 1889 | if (unlikely(!l_ptr)) { |
| 1867 | tipc_node_unlock(n_ptr); | 1890 | tipc_node_unlock(n_ptr); |
diff --git a/net/tipc/link.h b/net/tipc/link.h index 2e5385c47d30..26151d30589d 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h | |||
| @@ -279,12 +279,12 @@ static inline int between(u32 lower, u32 upper, u32 n) | |||
| 279 | 279 | ||
| 280 | static inline int less_eq(u32 left, u32 right) | 280 | static inline int less_eq(u32 left, u32 right) |
| 281 | { | 281 | { |
| 282 | return (mod(right - left) < 32768u); | 282 | return mod(right - left) < 32768u; |
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | static inline int less(u32 left, u32 right) | 285 | static inline int less(u32 left, u32 right) |
| 286 | { | 286 | { |
| 287 | return (less_eq(left, right) && (mod(right) != mod(left))); | 287 | return less_eq(left, right) && (mod(right) != mod(left)); |
| 288 | } | 288 | } |
| 289 | 289 | ||
| 290 | static inline u32 lesser(u32 left, u32 right) | 290 | static inline u32 lesser(u32 left, u32 right) |
| @@ -299,32 +299,32 @@ static inline u32 lesser(u32 left, u32 right) | |||
| 299 | 299 | ||
| 300 | static inline int link_working_working(struct link *l_ptr) | 300 | static inline int link_working_working(struct link *l_ptr) |
| 301 | { | 301 | { |
| 302 | return (l_ptr->state == WORKING_WORKING); | 302 | return l_ptr->state == WORKING_WORKING; |
| 303 | } | 303 | } |
| 304 | 304 | ||
| 305 | static inline int link_working_unknown(struct link *l_ptr) | 305 | static inline int link_working_unknown(struct link *l_ptr) |
| 306 | { | 306 | { |
| 307 | return (l_ptr->state == WORKING_UNKNOWN); | 307 | return l_ptr->state == WORKING_UNKNOWN; |
| 308 | } | 308 | } |
| 309 | 309 | ||
| 310 | static inline int link_reset_unknown(struct link *l_ptr) | 310 | static inline int link_reset_unknown(struct link *l_ptr) |
| 311 | { | 311 | { |
| 312 | return (l_ptr->state == RESET_UNKNOWN); | 312 | return l_ptr->state == RESET_UNKNOWN; |
| 313 | } | 313 | } |
| 314 | 314 | ||
| 315 | static inline int link_reset_reset(struct link *l_ptr) | 315 | static inline int link_reset_reset(struct link *l_ptr) |
| 316 | { | 316 | { |
| 317 | return (l_ptr->state == RESET_RESET); | 317 | return l_ptr->state == RESET_RESET; |
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | static inline int link_blocked(struct link *l_ptr) | 320 | static inline int link_blocked(struct link *l_ptr) |
| 321 | { | 321 | { |
| 322 | return (l_ptr->exp_msg_count || l_ptr->blocked); | 322 | return l_ptr->exp_msg_count || l_ptr->blocked; |
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | static inline int link_congested(struct link *l_ptr) | 325 | static inline int link_congested(struct link *l_ptr) |
| 326 | { | 326 | { |
| 327 | return (l_ptr->out_queue_size >= l_ptr->queue_limit[0]); | 327 | return l_ptr->out_queue_size >= l_ptr->queue_limit[0]; |
| 328 | } | 328 | } |
| 329 | 329 | ||
| 330 | #endif | 330 | #endif |
diff --git a/net/tipc/msg.h b/net/tipc/msg.h index 995d2da35b01..031aad18efce 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h | |||
| @@ -104,7 +104,7 @@ static inline u32 msg_user(struct tipc_msg *m) | |||
| 104 | 104 | ||
| 105 | static inline u32 msg_isdata(struct tipc_msg *m) | 105 | static inline u32 msg_isdata(struct tipc_msg *m) |
| 106 | { | 106 | { |
| 107 | return (msg_user(m) <= TIPC_CRITICAL_IMPORTANCE); | 107 | return msg_user(m) <= TIPC_CRITICAL_IMPORTANCE; |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | static inline void msg_set_user(struct tipc_msg *m, u32 n) | 110 | static inline void msg_set_user(struct tipc_msg *m, u32 n) |
| @@ -289,7 +289,7 @@ static inline void msg_set_destnode(struct tipc_msg *m, u32 a) | |||
| 289 | 289 | ||
| 290 | static inline int msg_is_dest(struct tipc_msg *m, u32 d) | 290 | static inline int msg_is_dest(struct tipc_msg *m, u32 d) |
| 291 | { | 291 | { |
| 292 | return(msg_short(m) || (msg_destnode(m) == d)); | 292 | return msg_short(m) || (msg_destnode(m) == d); |
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | static inline u32 msg_routed(struct tipc_msg *m) | 295 | static inline u32 msg_routed(struct tipc_msg *m) |
| @@ -632,7 +632,7 @@ static inline void msg_set_bcast_tag(struct tipc_msg *m, u32 n) | |||
| 632 | 632 | ||
| 633 | static inline u32 msg_max_pkt(struct tipc_msg *m) | 633 | static inline u32 msg_max_pkt(struct tipc_msg *m) |
| 634 | { | 634 | { |
| 635 | return (msg_bits(m, 9, 16, 0xffff) * 4); | 635 | return msg_bits(m, 9, 16, 0xffff) * 4; |
| 636 | } | 636 | } |
| 637 | 637 | ||
| 638 | static inline void msg_set_max_pkt(struct tipc_msg *m, u32 n) | 638 | static inline void msg_set_max_pkt(struct tipc_msg *m, u32 n) |
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 8ba79620db3f..9ca4b0689237 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c | |||
| @@ -116,7 +116,7 @@ DEFINE_RWLOCK(tipc_nametbl_lock); | |||
| 116 | 116 | ||
| 117 | static int hash(int x) | 117 | static int hash(int x) |
| 118 | { | 118 | { |
| 119 | return(x & (tipc_nametbl_size - 1)); | 119 | return x & (tipc_nametbl_size - 1); |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | /** | 122 | /** |
| @@ -613,8 +613,7 @@ struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, | |||
| 613 | } | 613 | } |
| 614 | 614 | ||
| 615 | /* | 615 | /* |
| 616 | * tipc_nametbl_translate(): Translate tipc_name -> tipc_portid. | 616 | * tipc_nametbl_translate - translate name to port id |
| 617 | * Very time-critical. | ||
| 618 | * | 617 | * |
| 619 | * Note: on entry 'destnode' is the search domain used during translation; | 618 | * Note: on entry 'destnode' is the search domain used during translation; |
| 620 | * on exit it passes back the node address of the matching port (if any) | 619 | * on exit it passes back the node address of the matching port (if any) |
| @@ -685,7 +684,6 @@ found: | |||
| 685 | } | 684 | } |
| 686 | spin_unlock_bh(&seq->lock); | 685 | spin_unlock_bh(&seq->lock); |
| 687 | not_found: | 686 | not_found: |
| 688 | *destnode = 0; | ||
| 689 | read_unlock_bh(&tipc_nametbl_lock); | 687 | read_unlock_bh(&tipc_nametbl_lock); |
| 690 | return 0; | 688 | return 0; |
| 691 | } | 689 | } |
| @@ -877,7 +875,7 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, | |||
| 877 | u32 index) | 875 | u32 index) |
| 878 | { | 876 | { |
| 879 | char portIdStr[27]; | 877 | char portIdStr[27]; |
| 880 | char *scopeStr; | 878 | const char *scope_str[] = {"", " zone", " cluster", " node"}; |
| 881 | struct publication *publ = sseq->zone_list; | 879 | struct publication *publ = sseq->zone_list; |
| 882 | 880 | ||
| 883 | tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper); | 881 | tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper); |
| @@ -893,15 +891,8 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, | |||
| 893 | tipc_node(publ->node), publ->ref); | 891 | tipc_node(publ->node), publ->ref); |
| 894 | tipc_printf(buf, "%-26s ", portIdStr); | 892 | tipc_printf(buf, "%-26s ", portIdStr); |
| 895 | if (depth > 3) { | 893 | if (depth > 3) { |
| 896 | if (publ->node != tipc_own_addr) | 894 | tipc_printf(buf, "%-10u %s", publ->key, |
| 897 | scopeStr = ""; | 895 | scope_str[publ->scope]); |
| 898 | else if (publ->scope == TIPC_NODE_SCOPE) | ||
| 899 | scopeStr = "node"; | ||
| 900 | else if (publ->scope == TIPC_CLUSTER_SCOPE) | ||
| 901 | scopeStr = "cluster"; | ||
| 902 | else | ||
| 903 | scopeStr = "zone"; | ||
| 904 | tipc_printf(buf, "%-10u %s", publ->key, scopeStr); | ||
| 905 | } | 896 | } |
| 906 | 897 | ||
| 907 | publ = publ->zone_list_next; | 898 | publ = publ->zone_list_next; |
| @@ -951,24 +942,19 @@ static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth, | |||
| 951 | 942 | ||
| 952 | static void nametbl_header(struct print_buf *buf, u32 depth) | 943 | static void nametbl_header(struct print_buf *buf, u32 depth) |
| 953 | { | 944 | { |
| 954 | tipc_printf(buf, "Type "); | 945 | const char *header[] = { |
| 955 | 946 | "Type ", | |
| 956 | if (depth > 1) | 947 | "Lower Upper ", |
| 957 | tipc_printf(buf, "Lower Upper "); | 948 | "Port Identity ", |
| 958 | if (depth > 2) | 949 | "Publication Scope" |
| 959 | tipc_printf(buf, "Port Identity "); | 950 | }; |
| 960 | if (depth > 3) | 951 | |
| 961 | tipc_printf(buf, "Publication"); | 952 | int i; |
| 962 | 953 | ||
| 963 | tipc_printf(buf, "\n-----------"); | 954 | if (depth > 4) |
| 964 | 955 | depth = 4; | |
| 965 | if (depth > 1) | 956 | for (i = 0; i < depth; i++) |
| 966 | tipc_printf(buf, "--------------------- "); | 957 | tipc_printf(buf, header[i]); |
| 967 | if (depth > 2) | ||
| 968 | tipc_printf(buf, "-------------------------- "); | ||
| 969 | if (depth > 3) | ||
| 970 | tipc_printf(buf, "------------------"); | ||
| 971 | |||
| 972 | tipc_printf(buf, "\n"); | 958 | tipc_printf(buf, "\n"); |
| 973 | } | 959 | } |
| 974 | 960 | ||
diff --git a/net/tipc/net.c b/net/tipc/net.c index f61b7694138b..7e05af47a196 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c | |||
| @@ -248,6 +248,7 @@ void tipc_net_route_msg(struct sk_buff *buf) | |||
| 248 | 248 | ||
| 249 | /* Handle message for another node */ | 249 | /* Handle message for another node */ |
| 250 | msg_dbg(msg, "NET>SEND>: "); | 250 | msg_dbg(msg, "NET>SEND>: "); |
| 251 | skb_trim(buf, msg_size(msg)); | ||
| 251 | tipc_link_send(buf, dnode, msg_link_selector(msg)); | 252 | tipc_link_send(buf, dnode, msg_link_selector(msg)); |
| 252 | } | 253 | } |
| 253 | 254 | ||
diff --git a/net/tipc/node.c b/net/tipc/node.c index b634942caba5..7c49cd056df7 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
| @@ -237,23 +237,22 @@ void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr) | |||
| 237 | 237 | ||
| 238 | int tipc_node_has_active_links(struct tipc_node *n_ptr) | 238 | int tipc_node_has_active_links(struct tipc_node *n_ptr) |
| 239 | { | 239 | { |
| 240 | return (n_ptr && | 240 | return n_ptr->active_links[0] != NULL; |
| 241 | ((n_ptr->active_links[0]) || (n_ptr->active_links[1]))); | ||
| 242 | } | 241 | } |
| 243 | 242 | ||
| 244 | int tipc_node_has_redundant_links(struct tipc_node *n_ptr) | 243 | int tipc_node_has_redundant_links(struct tipc_node *n_ptr) |
| 245 | { | 244 | { |
| 246 | return (n_ptr->working_links > 1); | 245 | return n_ptr->working_links > 1; |
| 247 | } | 246 | } |
| 248 | 247 | ||
| 249 | static int tipc_node_has_active_routes(struct tipc_node *n_ptr) | 248 | static int tipc_node_has_active_routes(struct tipc_node *n_ptr) |
| 250 | { | 249 | { |
| 251 | return (n_ptr && (n_ptr->last_router >= 0)); | 250 | return n_ptr && (n_ptr->last_router >= 0); |
| 252 | } | 251 | } |
| 253 | 252 | ||
| 254 | int tipc_node_is_up(struct tipc_node *n_ptr) | 253 | int tipc_node_is_up(struct tipc_node *n_ptr) |
| 255 | { | 254 | { |
| 256 | return (tipc_node_has_active_links(n_ptr) || tipc_node_has_active_routes(n_ptr)); | 255 | return tipc_node_has_active_links(n_ptr) || tipc_node_has_active_routes(n_ptr); |
| 257 | } | 256 | } |
| 258 | 257 | ||
| 259 | struct tipc_node *tipc_node_attach_link(struct link *l_ptr) | 258 | struct tipc_node *tipc_node_attach_link(struct link *l_ptr) |
| @@ -384,6 +383,20 @@ static void node_established_contact(struct tipc_node *n_ptr) | |||
| 384 | tipc_highest_allowed_slave); | 383 | tipc_highest_allowed_slave); |
| 385 | } | 384 | } |
| 386 | 385 | ||
| 386 | static void node_cleanup_finished(unsigned long node_addr) | ||
| 387 | { | ||
| 388 | struct tipc_node *n_ptr; | ||
| 389 | |||
| 390 | read_lock_bh(&tipc_net_lock); | ||
| 391 | n_ptr = tipc_node_find(node_addr); | ||
| 392 | if (n_ptr) { | ||
| 393 | tipc_node_lock(n_ptr); | ||
| 394 | n_ptr->cleanup_required = 0; | ||
| 395 | tipc_node_unlock(n_ptr); | ||
| 396 | } | ||
| 397 | read_unlock_bh(&tipc_net_lock); | ||
| 398 | } | ||
| 399 | |||
| 387 | static void node_lost_contact(struct tipc_node *n_ptr) | 400 | static void node_lost_contact(struct tipc_node *n_ptr) |
| 388 | { | 401 | { |
| 389 | struct cluster *c_ptr; | 402 | struct cluster *c_ptr; |
| @@ -458,6 +471,11 @@ static void node_lost_contact(struct tipc_node *n_ptr) | |||
| 458 | tipc_k_signal((Handler)ns->handle_node_down, | 471 | tipc_k_signal((Handler)ns->handle_node_down, |
| 459 | (unsigned long)ns->usr_handle); | 472 | (unsigned long)ns->usr_handle); |
| 460 | } | 473 | } |
| 474 | |||
| 475 | /* Prevent re-contact with node until all cleanup is done */ | ||
| 476 | |||
| 477 | n_ptr->cleanup_required = 1; | ||
| 478 | tipc_k_signal((Handler)node_cleanup_finished, n_ptr->addr); | ||
| 461 | } | 479 | } |
| 462 | 480 | ||
| 463 | /** | 481 | /** |
diff --git a/net/tipc/node.h b/net/tipc/node.h index 6f990da5d143..45f3db3a595d 100644 --- a/net/tipc/node.h +++ b/net/tipc/node.h | |||
| @@ -52,6 +52,7 @@ | |||
| 52 | * @active_links: pointers to active links to node | 52 | * @active_links: pointers to active links to node |
| 53 | * @links: pointers to all links to node | 53 | * @links: pointers to all links to node |
| 54 | * @working_links: number of working links to node (both active and standby) | 54 | * @working_links: number of working links to node (both active and standby) |
| 55 | * @cleanup_required: non-zero if cleaning up after a prior loss of contact | ||
| 55 | * @link_cnt: number of links to node | 56 | * @link_cnt: number of links to node |
| 56 | * @permit_changeover: non-zero if node has redundant links to this system | 57 | * @permit_changeover: non-zero if node has redundant links to this system |
| 57 | * @routers: bitmap (used for multicluster communication) | 58 | * @routers: bitmap (used for multicluster communication) |
| @@ -78,6 +79,7 @@ struct tipc_node { | |||
| 78 | struct link *links[MAX_BEARERS]; | 79 | struct link *links[MAX_BEARERS]; |
| 79 | int link_cnt; | 80 | int link_cnt; |
| 80 | int working_links; | 81 | int working_links; |
| 82 | int cleanup_required; | ||
| 81 | int permit_changeover; | 83 | int permit_changeover; |
| 82 | u32 routers[512/32]; | 84 | u32 routers[512/32]; |
| 83 | int last_router; | 85 | int last_router; |
diff --git a/net/tipc/port.c b/net/tipc/port.c index 0737680e9266..d760336f2ca8 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c | |||
| @@ -588,19 +588,10 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf) | |||
| 588 | if (!p_ptr) { | 588 | if (!p_ptr) { |
| 589 | err = TIPC_ERR_NO_PORT; | 589 | err = TIPC_ERR_NO_PORT; |
| 590 | } else if (p_ptr->publ.connected) { | 590 | } else if (p_ptr->publ.connected) { |
| 591 | if (port_peernode(p_ptr) != msg_orignode(msg)) | 591 | if ((port_peernode(p_ptr) != msg_orignode(msg)) || |
| 592 | (port_peerport(p_ptr) != msg_origport(msg))) { | ||
| 592 | err = TIPC_ERR_NO_PORT; | 593 | err = TIPC_ERR_NO_PORT; |
| 593 | if (port_peerport(p_ptr) != msg_origport(msg)) | 594 | } else if (msg_type(msg) == CONN_ACK) { |
| 594 | err = TIPC_ERR_NO_PORT; | ||
| 595 | if (!err && msg_routed(msg)) { | ||
| 596 | u32 seqno = msg_transp_seqno(msg); | ||
| 597 | u32 myno = ++p_ptr->last_in_seqno; | ||
| 598 | if (seqno != myno) { | ||
| 599 | err = TIPC_ERR_NO_PORT; | ||
| 600 | abort_buf = port_build_self_abort_msg(p_ptr, err); | ||
| 601 | } | ||
| 602 | } | ||
| 603 | if (msg_type(msg) == CONN_ACK) { | ||
| 604 | int wakeup = tipc_port_congested(p_ptr) && | 595 | int wakeup = tipc_port_congested(p_ptr) && |
| 605 | p_ptr->publ.congested && | 596 | p_ptr->publ.congested && |
| 606 | p_ptr->wakeup; | 597 | p_ptr->wakeup; |
| @@ -1473,7 +1464,7 @@ int tipc_forward2name(u32 ref, | |||
| 1473 | msg_set_destnode(msg, destnode); | 1464 | msg_set_destnode(msg, destnode); |
| 1474 | msg_set_destport(msg, destport); | 1465 | msg_set_destport(msg, destport); |
| 1475 | 1466 | ||
| 1476 | if (likely(destport || destnode)) { | 1467 | if (likely(destport)) { |
| 1477 | p_ptr->sent++; | 1468 | p_ptr->sent++; |
| 1478 | if (likely(destnode == tipc_own_addr)) | 1469 | if (likely(destnode == tipc_own_addr)) |
| 1479 | return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); | 1470 | return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); |
| @@ -1551,7 +1542,7 @@ int tipc_forward_buf2name(u32 ref, | |||
| 1551 | skb_push(buf, LONG_H_SIZE); | 1542 | skb_push(buf, LONG_H_SIZE); |
| 1552 | skb_copy_to_linear_data(buf, msg, LONG_H_SIZE); | 1543 | skb_copy_to_linear_data(buf, msg, LONG_H_SIZE); |
| 1553 | msg_dbg(buf_msg(buf),"PREP:"); | 1544 | msg_dbg(buf_msg(buf),"PREP:"); |
| 1554 | if (likely(destport || destnode)) { | 1545 | if (likely(destport)) { |
| 1555 | p_ptr->sent++; | 1546 | p_ptr->sent++; |
| 1556 | if (destnode == tipc_own_addr) | 1547 | if (destnode == tipc_own_addr) |
| 1557 | return tipc_port_recv_msg(buf); | 1548 | return tipc_port_recv_msg(buf); |
diff --git a/net/tipc/port.h b/net/tipc/port.h index 8d1652aab298..e74bd9563739 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h | |||
| @@ -157,7 +157,7 @@ static inline u32 tipc_peer_node(struct port *p_ptr) | |||
| 157 | 157 | ||
| 158 | static inline int tipc_port_congested(struct port *p_ptr) | 158 | static inline int tipc_port_congested(struct port *p_ptr) |
| 159 | { | 159 | { |
| 160 | return((p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2)); | 160 | return (p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2); |
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | /** | 163 | /** |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 66e889ba48fd..33217fc3d697 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 | ||
| @@ -429,36 +430,55 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr, | |||
| 429 | * to handle any preventable race conditions, so TIPC will do the same ... | 430 | * to handle any preventable race conditions, so TIPC will do the same ... |
| 430 | * | 431 | * |
| 431 | * TIPC sets the returned events as follows: | 432 | * TIPC sets the returned events as follows: |
| 432 | * a) POLLRDNORM and POLLIN are set if the socket's receive queue is non-empty | 433 | * |
| 433 | * or if a connection-oriented socket is does not have an active connection | 434 | * socket state flags set |
| 434 | * (i.e. a read operation will not block). | 435 | * ------------ --------- |
| 435 | * b) POLLOUT is set except when a socket's connection has been terminated | 436 | * unconnected no read flags |
| 436 | * (i.e. a write operation will not block). | 437 | * no write flags |
| 437 | * c) POLLHUP is set when a socket's connection has been terminated. | 438 | * |
| 438 | * | 439 | * connecting POLLIN/POLLRDNORM if ACK/NACK in rx queue |
| 439 | * IMPORTANT: The fact that a read or write operation will not block does NOT | 440 | * no write flags |
| 440 | * imply that the operation will succeed! | 441 | * |
| 442 | * connected POLLIN/POLLRDNORM if data in rx queue | ||
| 443 | * POLLOUT if port is not congested | ||
| 444 | * | ||
| 445 | * disconnecting POLLIN/POLLRDNORM/POLLHUP | ||
| 446 | * no write flags | ||
| 447 | * | ||
| 448 | * listening POLLIN if SYN in rx queue | ||
| 449 | * no write flags | ||
| 450 | * | ||
| 451 | * ready POLLIN/POLLRDNORM if data in rx queue | ||
| 452 | * [connectionless] POLLOUT (since port cannot be congested) | ||
| 453 | * | ||
| 454 | * IMPORTANT: The fact that a read or write operation is indicated does NOT | ||
| 455 | * imply that the operation will succeed, merely that it should be performed | ||
| 456 | * and will not block. | ||
| 441 | */ | 457 | */ |
| 442 | 458 | ||
| 443 | static unsigned int poll(struct file *file, struct socket *sock, | 459 | static unsigned int poll(struct file *file, struct socket *sock, |
| 444 | poll_table *wait) | 460 | poll_table *wait) |
| 445 | { | 461 | { |
| 446 | struct sock *sk = sock->sk; | 462 | struct sock *sk = sock->sk; |
| 447 | u32 mask; | 463 | u32 mask = 0; |
| 448 | 464 | ||
| 449 | poll_wait(file, sk_sleep(sk), wait); | 465 | poll_wait(file, sk_sleep(sk), wait); |
| 450 | 466 | ||
| 451 | if (!skb_queue_empty(&sk->sk_receive_queue) || | 467 | switch ((int)sock->state) { |
| 452 | (sock->state == SS_UNCONNECTED) || | 468 | case SS_READY: |
| 453 | (sock->state == SS_DISCONNECTING)) | 469 | case SS_CONNECTED: |
| 454 | mask = (POLLRDNORM | POLLIN); | 470 | if (!tipc_sk_port(sk)->congested) |
| 455 | else | 471 | mask |= POLLOUT; |
| 456 | mask = 0; | 472 | /* fall thru' */ |
| 457 | 473 | case SS_CONNECTING: | |
| 458 | if (sock->state == SS_DISCONNECTING) | 474 | case SS_LISTENING: |
| 459 | mask |= POLLHUP; | 475 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
| 460 | else | 476 | mask |= (POLLIN | POLLRDNORM); |
| 461 | mask |= POLLOUT; | 477 | break; |
| 478 | case SS_DISCONNECTING: | ||
| 479 | mask = (POLLIN | POLLRDNORM | POLLHUP); | ||
| 480 | break; | ||
| 481 | } | ||
| 462 | 482 | ||
| 463 | return mask; | 483 | return mask; |
| 464 | } | 484 | } |
| @@ -1026,9 +1046,8 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, | |||
| 1026 | struct sk_buff *buf; | 1046 | struct sk_buff *buf; |
| 1027 | struct tipc_msg *msg; | 1047 | struct tipc_msg *msg; |
| 1028 | unsigned int sz; | 1048 | unsigned int sz; |
| 1029 | int sz_to_copy; | 1049 | int sz_to_copy, target, needed; |
| 1030 | int sz_copied = 0; | 1050 | int sz_copied = 0; |
| 1031 | int needed; | ||
| 1032 | char __user *crs = m->msg_iov->iov_base; | 1051 | char __user *crs = m->msg_iov->iov_base; |
| 1033 | unsigned char *buf_crs; | 1052 | unsigned char *buf_crs; |
| 1034 | u32 err; | 1053 | u32 err; |
| @@ -1050,6 +1069,8 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, | |||
| 1050 | goto exit; | 1069 | goto exit; |
| 1051 | } | 1070 | } |
| 1052 | 1071 | ||
| 1072 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); | ||
| 1073 | |||
| 1053 | restart: | 1074 | restart: |
| 1054 | 1075 | ||
| 1055 | /* Look for a message in receive queue; wait if necessary */ | 1076 | /* Look for a message in receive queue; wait if necessary */ |
| @@ -1138,7 +1159,7 @@ restart: | |||
| 1138 | 1159 | ||
| 1139 | if ((sz_copied < buf_len) && /* didn't get all requested data */ | 1160 | if ((sz_copied < buf_len) && /* didn't get all requested data */ |
| 1140 | (!skb_queue_empty(&sk->sk_receive_queue) || | 1161 | (!skb_queue_empty(&sk->sk_receive_queue) || |
| 1141 | (flags & MSG_WAITALL)) && /* and more is ready or required */ | 1162 | (sz_copied < target)) && /* and more is ready or required */ |
| 1142 | (!(flags & MSG_PEEK)) && /* and aren't just peeking at data */ | 1163 | (!(flags & MSG_PEEK)) && /* and aren't just peeking at data */ |
| 1143 | (!err)) /* and haven't reached a FIN */ | 1164 | (!err)) /* and haven't reached a FIN */ |
| 1144 | goto restart; | 1165 | goto restart; |
| @@ -1174,7 +1195,7 @@ static int rx_queue_full(struct tipc_msg *msg, u32 queue_size, u32 base) | |||
| 1174 | if (msg_connected(msg)) | 1195 | if (msg_connected(msg)) |
| 1175 | threshold *= 4; | 1196 | threshold *= 4; |
| 1176 | 1197 | ||
| 1177 | return (queue_size >= threshold); | 1198 | return queue_size >= threshold; |
| 1178 | } | 1199 | } |
| 1179 | 1200 | ||
| 1180 | /** | 1201 | /** |
| @@ -1365,6 +1386,7 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, | |||
| 1365 | struct msghdr m = {NULL,}; | 1386 | struct msghdr m = {NULL,}; |
| 1366 | struct sk_buff *buf; | 1387 | struct sk_buff *buf; |
| 1367 | struct tipc_msg *msg; | 1388 | struct tipc_msg *msg; |
| 1389 | long timeout; | ||
| 1368 | int res; | 1390 | int res; |
| 1369 | 1391 | ||
| 1370 | lock_sock(sk); | 1392 | lock_sock(sk); |
| @@ -1379,7 +1401,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() */ | 1401 | /* For now, TIPC does not support the non-blocking form of connect() */ |
| 1380 | 1402 | ||
| 1381 | if (flags & O_NONBLOCK) { | 1403 | if (flags & O_NONBLOCK) { |
| 1382 | res = -EWOULDBLOCK; | 1404 | res = -EOPNOTSUPP; |
| 1383 | goto exit; | 1405 | goto exit; |
| 1384 | } | 1406 | } |
| 1385 | 1407 | ||
| @@ -1425,11 +1447,12 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, | |||
| 1425 | 1447 | ||
| 1426 | /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ | 1448 | /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ |
| 1427 | 1449 | ||
| 1450 | timeout = tipc_sk(sk)->conn_timeout; | ||
| 1428 | release_sock(sk); | 1451 | release_sock(sk); |
| 1429 | res = wait_event_interruptible_timeout(*sk_sleep(sk), | 1452 | res = wait_event_interruptible_timeout(*sk_sleep(sk), |
| 1430 | (!skb_queue_empty(&sk->sk_receive_queue) || | 1453 | (!skb_queue_empty(&sk->sk_receive_queue) || |
| 1431 | (sock->state != SS_CONNECTING)), | 1454 | (sock->state != SS_CONNECTING)), |
| 1432 | sk->sk_rcvtimeo); | 1455 | timeout ? timeout : MAX_SCHEDULE_TIMEOUT); |
| 1433 | lock_sock(sk); | 1456 | lock_sock(sk); |
| 1434 | 1457 | ||
| 1435 | if (res > 0) { | 1458 | if (res > 0) { |
| @@ -1692,7 +1715,7 @@ static int setsockopt(struct socket *sock, | |||
| 1692 | res = tipc_set_portunreturnable(tport->ref, value); | 1715 | res = tipc_set_portunreturnable(tport->ref, value); |
| 1693 | break; | 1716 | break; |
| 1694 | case TIPC_CONN_TIMEOUT: | 1717 | case TIPC_CONN_TIMEOUT: |
| 1695 | sk->sk_rcvtimeo = msecs_to_jiffies(value); | 1718 | tipc_sk(sk)->conn_timeout = msecs_to_jiffies(value); |
| 1696 | /* no need to set "res", since already 0 at this point */ | 1719 | /* no need to set "res", since already 0 at this point */ |
| 1697 | break; | 1720 | break; |
| 1698 | default: | 1721 | default: |
| @@ -1747,7 +1770,7 @@ static int getsockopt(struct socket *sock, | |||
| 1747 | res = tipc_portunreturnable(tport->ref, &value); | 1770 | res = tipc_portunreturnable(tport->ref, &value); |
| 1748 | break; | 1771 | break; |
| 1749 | case TIPC_CONN_TIMEOUT: | 1772 | case TIPC_CONN_TIMEOUT: |
| 1750 | value = jiffies_to_msecs(sk->sk_rcvtimeo); | 1773 | value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout); |
| 1751 | /* no need to set "res", since already 0 at this point */ | 1774 | /* no need to set "res", since already 0 at this point */ |
| 1752 | break; | 1775 | break; |
| 1753 | case TIPC_NODE_RECVQ_DEPTH: | 1776 | case TIPC_NODE_RECVQ_DEPTH: |
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index ab6eab4c45e2..1a5b9a6bd128 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c | |||
| @@ -604,6 +604,6 @@ int tipc_ispublished(struct tipc_name const *name) | |||
| 604 | { | 604 | { |
| 605 | u32 domain = 0; | 605 | u32 domain = 0; |
| 606 | 606 | ||
| 607 | return(tipc_nametbl_translate(name->type, name->instance,&domain) != 0); | 607 | return tipc_nametbl_translate(name->type, name->instance, &domain) != 0; |
| 608 | } | 608 | } |
| 609 | 609 | ||
