diff options
-rw-r--r-- | net/tipc/bcast.c | 5 | ||||
-rw-r--r-- | net/tipc/link.c | 23 | ||||
-rw-r--r-- | net/tipc/socket.c | 49 |
3 files changed, 37 insertions, 40 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 59b2f2a538e1..295bdc26f103 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
@@ -358,10 +358,9 @@ int tipc_bclink_xmit(struct net *net, struct sk_buff_head *list) | |||
358 | 358 | ||
359 | /* Prepare clone of message for local node */ | 359 | /* Prepare clone of message for local node */ |
360 | skb = tipc_msg_reassemble(list); | 360 | skb = tipc_msg_reassemble(list); |
361 | if (unlikely(!skb)) { | 361 | if (unlikely(!skb)) |
362 | __skb_queue_purge(list); | ||
363 | return -EHOSTUNREACH; | 362 | return -EHOSTUNREACH; |
364 | } | 363 | |
365 | /* Broadcast to all nodes */ | 364 | /* Broadcast to all nodes */ |
366 | if (likely(bclink)) { | 365 | if (likely(bclink)) { |
367 | tipc_bclink_lock(net); | 366 | tipc_bclink_lock(net); |
diff --git a/net/tipc/link.c b/net/tipc/link.c index f8e0e2ceceb4..ea32679b6737 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -340,7 +340,7 @@ void tipc_link_delete_list(struct net *net, unsigned int bearer_id) | |||
340 | * @link: congested link | 340 | * @link: congested link |
341 | * @list: message that was attempted sent | 341 | * @list: message that was attempted sent |
342 | * Create pseudo msg to send back to user when congestion abates | 342 | * Create pseudo msg to send back to user when congestion abates |
343 | * Only consumes message if there is an error | 343 | * Does not consume buffer list |
344 | */ | 344 | */ |
345 | static int link_schedule_user(struct tipc_link *link, struct sk_buff_head *list) | 345 | static int link_schedule_user(struct tipc_link *link, struct sk_buff_head *list) |
346 | { | 346 | { |
@@ -354,7 +354,7 @@ static int link_schedule_user(struct tipc_link *link, struct sk_buff_head *list) | |||
354 | if (unlikely(imp > TIPC_CRITICAL_IMPORTANCE)) { | 354 | if (unlikely(imp > TIPC_CRITICAL_IMPORTANCE)) { |
355 | pr_warn("%s<%s>, send queue full", link_rst_msg, link->name); | 355 | pr_warn("%s<%s>, send queue full", link_rst_msg, link->name); |
356 | tipc_link_reset(link); | 356 | tipc_link_reset(link); |
357 | goto err; | 357 | return -ENOBUFS; |
358 | } | 358 | } |
359 | /* Non-blocking sender: */ | 359 | /* Non-blocking sender: */ |
360 | if (TIPC_SKB_CB(skb_peek(list))->wakeup_pending) | 360 | if (TIPC_SKB_CB(skb_peek(list))->wakeup_pending) |
@@ -364,15 +364,12 @@ static int link_schedule_user(struct tipc_link *link, struct sk_buff_head *list) | |||
364 | skb = tipc_msg_create(SOCK_WAKEUP, 0, INT_H_SIZE, 0, | 364 | skb = tipc_msg_create(SOCK_WAKEUP, 0, INT_H_SIZE, 0, |
365 | addr, addr, oport, 0, 0); | 365 | addr, addr, oport, 0, 0); |
366 | if (!skb) | 366 | if (!skb) |
367 | goto err; | 367 | return -ENOBUFS; |
368 | TIPC_SKB_CB(skb)->chain_sz = skb_queue_len(list); | 368 | TIPC_SKB_CB(skb)->chain_sz = skb_queue_len(list); |
369 | TIPC_SKB_CB(skb)->chain_imp = imp; | 369 | TIPC_SKB_CB(skb)->chain_imp = imp; |
370 | skb_queue_tail(&link->wakeupq, skb); | 370 | skb_queue_tail(&link->wakeupq, skb); |
371 | link->stats.link_congs++; | 371 | link->stats.link_congs++; |
372 | return -ELINKCONG; | 372 | return -ELINKCONG; |
373 | err: | ||
374 | __skb_queue_purge(list); | ||
375 | return -ENOBUFS; | ||
376 | } | 373 | } |
377 | 374 | ||
378 | /** | 375 | /** |
@@ -641,8 +638,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) | |||
641 | * @link: link to use | 638 | * @link: link to use |
642 | * @list: chain of buffers containing message | 639 | * @list: chain of buffers containing message |
643 | * | 640 | * |
644 | * Consumes the buffer chain, except when returning -ELINKCONG, | 641 | * Consumes the buffer chain, except when returning an error code, |
645 | * since the caller then may want to make more send attempts. | ||
646 | * Returns 0 if success, or errno: -ELINKCONG, -EMSGSIZE or -ENOBUFS | 642 | * Returns 0 if success, or errno: -ELINKCONG, -EMSGSIZE or -ENOBUFS |
647 | * Messages at TIPC_SYSTEM_IMPORTANCE are always accepted | 643 | * Messages at TIPC_SYSTEM_IMPORTANCE are always accepted |
648 | */ | 644 | */ |
@@ -666,10 +662,9 @@ int __tipc_link_xmit(struct net *net, struct tipc_link *link, | |||
666 | if (unlikely(link->backlog[i].len >= link->backlog[i].limit)) | 662 | if (unlikely(link->backlog[i].len >= link->backlog[i].limit)) |
667 | return link_schedule_user(link, list); | 663 | return link_schedule_user(link, list); |
668 | } | 664 | } |
669 | if (unlikely(msg_size(msg) > mtu)) { | 665 | if (unlikely(msg_size(msg) > mtu)) |
670 | __skb_queue_purge(list); | ||
671 | return -EMSGSIZE; | 666 | return -EMSGSIZE; |
672 | } | 667 | |
673 | /* Prepare each packet for sending, and add to relevant queue: */ | 668 | /* Prepare each packet for sending, and add to relevant queue: */ |
674 | while (skb_queue_len(list)) { | 669 | while (skb_queue_len(list)) { |
675 | skb = skb_peek(list); | 670 | skb = skb_peek(list); |
@@ -722,7 +717,7 @@ static int __tipc_link_xmit_skb(struct tipc_link *link, struct sk_buff *skb) | |||
722 | 717 | ||
723 | /* tipc_link_xmit_skb(): send single buffer to destination | 718 | /* tipc_link_xmit_skb(): send single buffer to destination |
724 | * Buffers sent via this functon are generally TIPC_SYSTEM_IMPORTANCE | 719 | * Buffers sent via this functon are generally TIPC_SYSTEM_IMPORTANCE |
725 | * messages, which will not be rejected | 720 | * messages, which will not cause link congestion |
726 | * The only exception is datagram messages rerouted after secondary | 721 | * The only exception is datagram messages rerouted after secondary |
727 | * lookup, which are rare and safe to dispose of anyway. | 722 | * lookup, which are rare and safe to dispose of anyway. |
728 | * TODO: Return real return value, and let callers use | 723 | * TODO: Return real return value, and let callers use |
@@ -736,7 +731,7 @@ int tipc_link_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode, | |||
736 | 731 | ||
737 | skb2list(skb, &head); | 732 | skb2list(skb, &head); |
738 | rc = tipc_link_xmit(net, &head, dnode, selector); | 733 | rc = tipc_link_xmit(net, &head, dnode, selector); |
739 | if (rc == -ELINKCONG) | 734 | if (rc) |
740 | kfree_skb(skb); | 735 | kfree_skb(skb); |
741 | return 0; | 736 | return 0; |
742 | } | 737 | } |
@@ -748,7 +743,7 @@ int tipc_link_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode, | |||
748 | * @dsz: amount of user data to be sent | 743 | * @dsz: amount of user data to be sent |
749 | * @dnode: address of destination node | 744 | * @dnode: address of destination node |
750 | * @selector: a number used for deterministic link selection | 745 | * @selector: a number used for deterministic link selection |
751 | * Consumes the buffer chain, except when returning -ELINKCONG | 746 | * Consumes the buffer chain, except when returning error |
752 | * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE | 747 | * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE |
753 | */ | 748 | */ |
754 | int tipc_link_xmit(struct net *net, struct sk_buff_head *list, u32 dnode, | 749 | int tipc_link_xmit(struct net *net, struct sk_buff_head *list, u32 dnode, |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 3a7567f690f3..87fef25f6519 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -686,21 +686,22 @@ new_mtu: | |||
686 | 686 | ||
687 | do { | 687 | do { |
688 | rc = tipc_bclink_xmit(net, pktchain); | 688 | rc = tipc_bclink_xmit(net, pktchain); |
689 | if (likely(rc >= 0)) { | 689 | if (likely(!rc)) |
690 | rc = dsz; | 690 | return dsz; |
691 | break; | 691 | |
692 | if (rc == -ELINKCONG) { | ||
693 | tsk->link_cong = 1; | ||
694 | rc = tipc_wait_for_sndmsg(sock, &timeo); | ||
695 | if (!rc) | ||
696 | continue; | ||
692 | } | 697 | } |
698 | __skb_queue_purge(pktchain); | ||
693 | if (rc == -EMSGSIZE) { | 699 | if (rc == -EMSGSIZE) { |
694 | msg->msg_iter = save; | 700 | msg->msg_iter = save; |
695 | goto new_mtu; | 701 | goto new_mtu; |
696 | } | 702 | } |
697 | if (rc != -ELINKCONG) | 703 | break; |
698 | break; | 704 | } while (1); |
699 | tipc_sk(sk)->link_cong = 1; | ||
700 | rc = tipc_wait_for_sndmsg(sock, &timeo); | ||
701 | if (rc) | ||
702 | __skb_queue_purge(pktchain); | ||
703 | } while (!rc); | ||
704 | return rc; | 705 | return rc; |
705 | } | 706 | } |
706 | 707 | ||
@@ -925,23 +926,24 @@ new_mtu: | |||
925 | skb = skb_peek(pktchain); | 926 | skb = skb_peek(pktchain); |
926 | TIPC_SKB_CB(skb)->wakeup_pending = tsk->link_cong; | 927 | TIPC_SKB_CB(skb)->wakeup_pending = tsk->link_cong; |
927 | rc = tipc_link_xmit(net, pktchain, dnode, tsk->portid); | 928 | rc = tipc_link_xmit(net, pktchain, dnode, tsk->portid); |
928 | if (likely(rc >= 0)) { | 929 | if (likely(!rc)) { |
929 | if (sock->state != SS_READY) | 930 | if (sock->state != SS_READY) |
930 | sock->state = SS_CONNECTING; | 931 | sock->state = SS_CONNECTING; |
931 | rc = dsz; | 932 | return dsz; |
932 | break; | ||
933 | } | 933 | } |
934 | if (rc == -ELINKCONG) { | ||
935 | tsk->link_cong = 1; | ||
936 | rc = tipc_wait_for_sndmsg(sock, &timeo); | ||
937 | if (!rc) | ||
938 | continue; | ||
939 | } | ||
940 | __skb_queue_purge(pktchain); | ||
934 | if (rc == -EMSGSIZE) { | 941 | if (rc == -EMSGSIZE) { |
935 | m->msg_iter = save; | 942 | m->msg_iter = save; |
936 | goto new_mtu; | 943 | goto new_mtu; |
937 | } | 944 | } |
938 | if (rc != -ELINKCONG) | 945 | break; |
939 | break; | 946 | } while (1); |
940 | tsk->link_cong = 1; | ||
941 | rc = tipc_wait_for_sndmsg(sock, &timeo); | ||
942 | if (rc) | ||
943 | __skb_queue_purge(pktchain); | ||
944 | } while (!rc); | ||
945 | 947 | ||
946 | return rc; | 948 | return rc; |
947 | } | 949 | } |
@@ -1048,10 +1050,11 @@ next: | |||
1048 | tsk->sent_unacked++; | 1050 | tsk->sent_unacked++; |
1049 | sent += send; | 1051 | sent += send; |
1050 | if (sent == dsz) | 1052 | if (sent == dsz) |
1051 | break; | 1053 | return dsz; |
1052 | goto next; | 1054 | goto next; |
1053 | } | 1055 | } |
1054 | if (rc == -EMSGSIZE) { | 1056 | if (rc == -EMSGSIZE) { |
1057 | __skb_queue_purge(pktchain); | ||
1055 | tsk->max_pkt = tipc_node_get_mtu(net, dnode, | 1058 | tsk->max_pkt = tipc_node_get_mtu(net, dnode, |
1056 | portid); | 1059 | portid); |
1057 | m->msg_iter = save; | 1060 | m->msg_iter = save; |
@@ -1059,13 +1062,13 @@ next: | |||
1059 | } | 1062 | } |
1060 | if (rc != -ELINKCONG) | 1063 | if (rc != -ELINKCONG) |
1061 | break; | 1064 | break; |
1065 | |||
1062 | tsk->link_cong = 1; | 1066 | tsk->link_cong = 1; |
1063 | } | 1067 | } |
1064 | rc = tipc_wait_for_sndpkt(sock, &timeo); | 1068 | rc = tipc_wait_for_sndpkt(sock, &timeo); |
1065 | if (rc) | ||
1066 | __skb_queue_purge(pktchain); | ||
1067 | } while (!rc); | 1069 | } while (!rc); |
1068 | 1070 | ||
1071 | __skb_queue_purge(pktchain); | ||
1069 | return sent ? sent : rc; | 1072 | return sent ? sent : rc; |
1070 | } | 1073 | } |
1071 | 1074 | ||