diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/tipc/node.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c index 34e9a2bb7c19..ee952ad60218 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -600,12 +600,14 @@ u32 tipc_available_nodes(const u32 domain) | |||
600 | struct node *n_ptr; | 600 | struct node *n_ptr; |
601 | u32 cnt = 0; | 601 | u32 cnt = 0; |
602 | 602 | ||
603 | read_lock_bh(&tipc_net_lock); | ||
603 | for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { | 604 | for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { |
604 | if (!in_scope(domain, n_ptr->addr)) | 605 | if (!in_scope(domain, n_ptr->addr)) |
605 | continue; | 606 | continue; |
606 | if (tipc_node_is_up(n_ptr)) | 607 | if (tipc_node_is_up(n_ptr)) |
607 | cnt++; | 608 | cnt++; |
608 | } | 609 | } |
610 | read_unlock_bh(&tipc_net_lock); | ||
609 | return cnt; | 611 | return cnt; |
610 | } | 612 | } |
611 | 613 | ||
@@ -625,19 +627,26 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) | |||
625 | return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE | 627 | return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE |
626 | " (network address)"); | 628 | " (network address)"); |
627 | 629 | ||
628 | if (!tipc_nodes) | 630 | read_lock_bh(&tipc_net_lock); |
631 | if (!tipc_nodes) { | ||
632 | read_unlock_bh(&tipc_net_lock); | ||
629 | return tipc_cfg_reply_none(); | 633 | return tipc_cfg_reply_none(); |
634 | } | ||
630 | 635 | ||
631 | /* For now, get space for all other nodes | 636 | /* For now, get space for all other nodes |
632 | (will need to modify this when slave nodes are supported */ | 637 | (will need to modify this when slave nodes are supported */ |
633 | 638 | ||
634 | payload_size = TLV_SPACE(sizeof(node_info)) * (tipc_max_nodes - 1); | 639 | payload_size = TLV_SPACE(sizeof(node_info)) * (tipc_max_nodes - 1); |
635 | if (payload_size > 32768u) | 640 | if (payload_size > 32768u) { |
641 | read_unlock_bh(&tipc_net_lock); | ||
636 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | 642 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED |
637 | " (too many nodes)"); | 643 | " (too many nodes)"); |
644 | } | ||
638 | buf = tipc_cfg_reply_alloc(payload_size); | 645 | buf = tipc_cfg_reply_alloc(payload_size); |
639 | if (!buf) | 646 | if (!buf) { |
647 | read_unlock_bh(&tipc_net_lock); | ||
640 | return NULL; | 648 | return NULL; |
649 | } | ||
641 | 650 | ||
642 | /* Add TLVs for all nodes in scope */ | 651 | /* Add TLVs for all nodes in scope */ |
643 | 652 | ||
@@ -650,6 +659,7 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) | |||
650 | &node_info, sizeof(node_info)); | 659 | &node_info, sizeof(node_info)); |
651 | } | 660 | } |
652 | 661 | ||
662 | read_unlock_bh(&tipc_net_lock); | ||
653 | return buf; | 663 | return buf; |
654 | } | 664 | } |
655 | 665 | ||
@@ -672,16 +682,22 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space) | |||
672 | if (tipc_mode != TIPC_NET_MODE) | 682 | if (tipc_mode != TIPC_NET_MODE) |
673 | return tipc_cfg_reply_none(); | 683 | return tipc_cfg_reply_none(); |
674 | 684 | ||
685 | read_lock_bh(&tipc_net_lock); | ||
686 | |||
675 | /* Get space for all unicast links + multicast link */ | 687 | /* Get space for all unicast links + multicast link */ |
676 | 688 | ||
677 | payload_size = TLV_SPACE(sizeof(link_info)) * | 689 | payload_size = TLV_SPACE(sizeof(link_info)) * |
678 | (tipc_net.zones[tipc_zone(tipc_own_addr)]->links + 1); | 690 | (tipc_net.zones[tipc_zone(tipc_own_addr)]->links + 1); |
679 | if (payload_size > 32768u) | 691 | if (payload_size > 32768u) { |
692 | read_unlock_bh(&tipc_net_lock); | ||
680 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | 693 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED |
681 | " (too many links)"); | 694 | " (too many links)"); |
695 | } | ||
682 | buf = tipc_cfg_reply_alloc(payload_size); | 696 | buf = tipc_cfg_reply_alloc(payload_size); |
683 | if (!buf) | 697 | if (!buf) { |
698 | read_unlock_bh(&tipc_net_lock); | ||
684 | return NULL; | 699 | return NULL; |
700 | } | ||
685 | 701 | ||
686 | /* Add TLV for broadcast link */ | 702 | /* Add TLV for broadcast link */ |
687 | 703 | ||
@@ -697,6 +713,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space) | |||
697 | 713 | ||
698 | if (!in_scope(domain, n_ptr->addr)) | 714 | if (!in_scope(domain, n_ptr->addr)) |
699 | continue; | 715 | continue; |
716 | tipc_node_lock(n_ptr); | ||
700 | for (i = 0; i < MAX_BEARERS; i++) { | 717 | for (i = 0; i < MAX_BEARERS; i++) { |
701 | if (!n_ptr->links[i]) | 718 | if (!n_ptr->links[i]) |
702 | continue; | 719 | continue; |
@@ -706,7 +723,9 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space) | |||
706 | tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, | 723 | tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, |
707 | &link_info, sizeof(link_info)); | 724 | &link_info, sizeof(link_info)); |
708 | } | 725 | } |
726 | tipc_node_unlock(n_ptr); | ||
709 | } | 727 | } |
710 | 728 | ||
729 | read_unlock_bh(&tipc_net_lock); | ||
711 | return buf; | 730 | return buf; |
712 | } | 731 | } |