diff options
Diffstat (limited to 'net/tipc/name_table.c')
-rw-r--r-- | net/tipc/name_table.c | 142 |
1 files changed, 79 insertions, 63 deletions
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 010f24a59da2..360c478b0b53 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c | |||
@@ -126,7 +126,7 @@ static struct publication *publ_create(u32 type, u32 lower, u32 upper, | |||
126 | { | 126 | { |
127 | struct publication *publ = kzalloc(sizeof(*publ), GFP_ATOMIC); | 127 | struct publication *publ = kzalloc(sizeof(*publ), GFP_ATOMIC); |
128 | if (publ == NULL) { | 128 | if (publ == NULL) { |
129 | warn("Publication creation failure, no memory\n"); | 129 | pr_warn("Publication creation failure, no memory\n"); |
130 | return NULL; | 130 | return NULL; |
131 | } | 131 | } |
132 | 132 | ||
@@ -163,7 +163,7 @@ static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_hea | |||
163 | struct sub_seq *sseq = tipc_subseq_alloc(1); | 163 | struct sub_seq *sseq = tipc_subseq_alloc(1); |
164 | 164 | ||
165 | if (!nseq || !sseq) { | 165 | if (!nseq || !sseq) { |
166 | warn("Name sequence creation failed, no memory\n"); | 166 | pr_warn("Name sequence creation failed, no memory\n"); |
167 | kfree(nseq); | 167 | kfree(nseq); |
168 | kfree(sseq); | 168 | kfree(sseq); |
169 | return NULL; | 169 | return NULL; |
@@ -191,7 +191,7 @@ static void nameseq_delete_empty(struct name_seq *seq) | |||
191 | } | 191 | } |
192 | } | 192 | } |
193 | 193 | ||
194 | /* | 194 | /** |
195 | * nameseq_find_subseq - find sub-sequence (if any) matching a name instance | 195 | * nameseq_find_subseq - find sub-sequence (if any) matching a name instance |
196 | * | 196 | * |
197 | * Very time-critical, so binary searches through sub-sequence array. | 197 | * Very time-critical, so binary searches through sub-sequence array. |
@@ -263,8 +263,8 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
263 | 263 | ||
264 | /* Lower end overlaps existing entry => need an exact match */ | 264 | /* Lower end overlaps existing entry => need an exact match */ |
265 | if ((sseq->lower != lower) || (sseq->upper != upper)) { | 265 | if ((sseq->lower != lower) || (sseq->upper != upper)) { |
266 | warn("Cannot publish {%u,%u,%u}, overlap error\n", | 266 | pr_warn("Cannot publish {%u,%u,%u}, overlap error\n", |
267 | type, lower, upper); | 267 | type, lower, upper); |
268 | return NULL; | 268 | return NULL; |
269 | } | 269 | } |
270 | 270 | ||
@@ -286,8 +286,8 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
286 | /* Fail if upper end overlaps into an existing entry */ | 286 | /* Fail if upper end overlaps into an existing entry */ |
287 | if ((inspos < nseq->first_free) && | 287 | if ((inspos < nseq->first_free) && |
288 | (upper >= nseq->sseqs[inspos].lower)) { | 288 | (upper >= nseq->sseqs[inspos].lower)) { |
289 | warn("Cannot publish {%u,%u,%u}, overlap error\n", | 289 | pr_warn("Cannot publish {%u,%u,%u}, overlap error\n", |
290 | type, lower, upper); | 290 | type, lower, upper); |
291 | return NULL; | 291 | return NULL; |
292 | } | 292 | } |
293 | 293 | ||
@@ -296,8 +296,8 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
296 | struct sub_seq *sseqs = tipc_subseq_alloc(nseq->alloc * 2); | 296 | struct sub_seq *sseqs = tipc_subseq_alloc(nseq->alloc * 2); |
297 | 297 | ||
298 | if (!sseqs) { | 298 | if (!sseqs) { |
299 | warn("Cannot publish {%u,%u,%u}, no memory\n", | 299 | pr_warn("Cannot publish {%u,%u,%u}, no memory\n", |
300 | type, lower, upper); | 300 | type, lower, upper); |
301 | return NULL; | 301 | return NULL; |
302 | } | 302 | } |
303 | memcpy(sseqs, nseq->sseqs, | 303 | memcpy(sseqs, nseq->sseqs, |
@@ -309,8 +309,8 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
309 | 309 | ||
310 | info = kzalloc(sizeof(*info), GFP_ATOMIC); | 310 | info = kzalloc(sizeof(*info), GFP_ATOMIC); |
311 | if (!info) { | 311 | if (!info) { |
312 | warn("Cannot publish {%u,%u,%u}, no memory\n", | 312 | pr_warn("Cannot publish {%u,%u,%u}, no memory\n", |
313 | type, lower, upper); | 313 | type, lower, upper); |
314 | return NULL; | 314 | return NULL; |
315 | } | 315 | } |
316 | 316 | ||
@@ -435,7 +435,7 @@ found: | |||
435 | } | 435 | } |
436 | 436 | ||
437 | /** | 437 | /** |
438 | * tipc_nameseq_subscribe: attach a subscription, and issue | 438 | * tipc_nameseq_subscribe - attach a subscription, and issue |
439 | * the prescribed number of events if there is any sub- | 439 | * the prescribed number of events if there is any sub- |
440 | * sequence overlapping with the requested sequence | 440 | * sequence overlapping with the requested sequence |
441 | */ | 441 | */ |
@@ -492,8 +492,8 @@ struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper, | |||
492 | 492 | ||
493 | if ((scope < TIPC_ZONE_SCOPE) || (scope > TIPC_NODE_SCOPE) || | 493 | if ((scope < TIPC_ZONE_SCOPE) || (scope > TIPC_NODE_SCOPE) || |
494 | (lower > upper)) { | 494 | (lower > upper)) { |
495 | dbg("Failed to publish illegal {%u,%u,%u} with scope %u\n", | 495 | pr_debug("Failed to publish illegal {%u,%u,%u} with scope %u\n", |
496 | type, lower, upper, scope); | 496 | type, lower, upper, scope); |
497 | return NULL; | 497 | return NULL; |
498 | } | 498 | } |
499 | 499 | ||
@@ -520,7 +520,7 @@ struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, | |||
520 | return publ; | 520 | return publ; |
521 | } | 521 | } |
522 | 522 | ||
523 | /* | 523 | /** |
524 | * tipc_nametbl_translate - perform name translation | 524 | * tipc_nametbl_translate - perform name translation |
525 | * | 525 | * |
526 | * On entry, 'destnode' is the search domain used during translation. | 526 | * On entry, 'destnode' is the search domain used during translation. |
@@ -668,8 +668,8 @@ struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper, | |||
668 | struct publication *publ; | 668 | struct publication *publ; |
669 | 669 | ||
670 | if (table.local_publ_count >= tipc_max_publications) { | 670 | if (table.local_publ_count >= tipc_max_publications) { |
671 | warn("Publication failed, local publication limit reached (%u)\n", | 671 | pr_warn("Publication failed, local publication limit reached (%u)\n", |
672 | tipc_max_publications); | 672 | tipc_max_publications); |
673 | return NULL; | 673 | return NULL; |
674 | } | 674 | } |
675 | 675 | ||
@@ -702,9 +702,9 @@ int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key) | |||
702 | return 1; | 702 | return 1; |
703 | } | 703 | } |
704 | write_unlock_bh(&tipc_nametbl_lock); | 704 | write_unlock_bh(&tipc_nametbl_lock); |
705 | err("Unable to remove local publication\n" | 705 | pr_err("Unable to remove local publication\n" |
706 | "(type=%u, lower=%u, ref=%u, key=%u)\n", | 706 | "(type=%u, lower=%u, ref=%u, key=%u)\n", |
707 | type, lower, ref, key); | 707 | type, lower, ref, key); |
708 | return 0; | 708 | return 0; |
709 | } | 709 | } |
710 | 710 | ||
@@ -725,8 +725,8 @@ void tipc_nametbl_subscribe(struct tipc_subscription *s) | |||
725 | tipc_nameseq_subscribe(seq, s); | 725 | tipc_nameseq_subscribe(seq, s); |
726 | spin_unlock_bh(&seq->lock); | 726 | spin_unlock_bh(&seq->lock); |
727 | } else { | 727 | } else { |
728 | warn("Failed to create subscription for {%u,%u,%u}\n", | 728 | pr_warn("Failed to create subscription for {%u,%u,%u}\n", |
729 | s->seq.type, s->seq.lower, s->seq.upper); | 729 | s->seq.type, s->seq.lower, s->seq.upper); |
730 | } | 730 | } |
731 | write_unlock_bh(&tipc_nametbl_lock); | 731 | write_unlock_bh(&tipc_nametbl_lock); |
732 | } | 732 | } |
@@ -751,21 +751,22 @@ void tipc_nametbl_unsubscribe(struct tipc_subscription *s) | |||
751 | 751 | ||
752 | 752 | ||
753 | /** | 753 | /** |
754 | * subseq_list: print specified sub-sequence contents into the given buffer | 754 | * subseq_list - print specified sub-sequence contents into the given buffer |
755 | */ | 755 | */ |
756 | static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, | 756 | static int subseq_list(struct sub_seq *sseq, char *buf, int len, u32 depth, |
757 | u32 index) | 757 | u32 index) |
758 | { | 758 | { |
759 | char portIdStr[27]; | 759 | char portIdStr[27]; |
760 | const char *scope_str[] = {"", " zone", " cluster", " node"}; | 760 | const char *scope_str[] = {"", " zone", " cluster", " node"}; |
761 | struct publication *publ; | 761 | struct publication *publ; |
762 | struct name_info *info; | 762 | struct name_info *info; |
763 | int ret; | ||
763 | 764 | ||
764 | tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper); | 765 | ret = tipc_snprintf(buf, len, "%-10u %-10u ", sseq->lower, sseq->upper); |
765 | 766 | ||
766 | if (depth == 2) { | 767 | if (depth == 2) { |
767 | tipc_printf(buf, "\n"); | 768 | ret += tipc_snprintf(buf - ret, len + ret, "\n"); |
768 | return; | 769 | return ret; |
769 | } | 770 | } |
770 | 771 | ||
771 | info = sseq->info; | 772 | info = sseq->info; |
@@ -774,52 +775,58 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, | |||
774 | sprintf(portIdStr, "<%u.%u.%u:%u>", | 775 | sprintf(portIdStr, "<%u.%u.%u:%u>", |
775 | tipc_zone(publ->node), tipc_cluster(publ->node), | 776 | tipc_zone(publ->node), tipc_cluster(publ->node), |
776 | tipc_node(publ->node), publ->ref); | 777 | tipc_node(publ->node), publ->ref); |
777 | tipc_printf(buf, "%-26s ", portIdStr); | 778 | ret += tipc_snprintf(buf + ret, len - ret, "%-26s ", portIdStr); |
778 | if (depth > 3) { | 779 | if (depth > 3) { |
779 | tipc_printf(buf, "%-10u %s", publ->key, | 780 | ret += tipc_snprintf(buf + ret, len - ret, "%-10u %s", |
780 | scope_str[publ->scope]); | 781 | publ->key, scope_str[publ->scope]); |
781 | } | 782 | } |
782 | if (!list_is_last(&publ->zone_list, &info->zone_list)) | 783 | if (!list_is_last(&publ->zone_list, &info->zone_list)) |
783 | tipc_printf(buf, "\n%33s", " "); | 784 | ret += tipc_snprintf(buf + ret, len - ret, |
785 | "\n%33s", " "); | ||
784 | }; | 786 | }; |
785 | 787 | ||
786 | tipc_printf(buf, "\n"); | 788 | ret += tipc_snprintf(buf + ret, len - ret, "\n"); |
789 | return ret; | ||
787 | } | 790 | } |
788 | 791 | ||
789 | /** | 792 | /** |
790 | * nameseq_list: print specified name sequence contents into the given buffer | 793 | * nameseq_list - print specified name sequence contents into the given buffer |
791 | */ | 794 | */ |
792 | static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth, | 795 | static int nameseq_list(struct name_seq *seq, char *buf, int len, u32 depth, |
793 | u32 type, u32 lowbound, u32 upbound, u32 index) | 796 | u32 type, u32 lowbound, u32 upbound, u32 index) |
794 | { | 797 | { |
795 | struct sub_seq *sseq; | 798 | struct sub_seq *sseq; |
796 | char typearea[11]; | 799 | char typearea[11]; |
800 | int ret = 0; | ||
797 | 801 | ||
798 | if (seq->first_free == 0) | 802 | if (seq->first_free == 0) |
799 | return; | 803 | return 0; |
800 | 804 | ||
801 | sprintf(typearea, "%-10u", seq->type); | 805 | sprintf(typearea, "%-10u", seq->type); |
802 | 806 | ||
803 | if (depth == 1) { | 807 | if (depth == 1) { |
804 | tipc_printf(buf, "%s\n", typearea); | 808 | ret += tipc_snprintf(buf, len, "%s\n", typearea); |
805 | return; | 809 | return ret; |
806 | } | 810 | } |
807 | 811 | ||
808 | for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) { | 812 | for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) { |
809 | if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) { | 813 | if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) { |
810 | tipc_printf(buf, "%s ", typearea); | 814 | ret += tipc_snprintf(buf + ret, len - ret, "%s ", |
815 | typearea); | ||
811 | spin_lock_bh(&seq->lock); | 816 | spin_lock_bh(&seq->lock); |
812 | subseq_list(sseq, buf, depth, index); | 817 | ret += subseq_list(sseq, buf + ret, len - ret, |
818 | depth, index); | ||
813 | spin_unlock_bh(&seq->lock); | 819 | spin_unlock_bh(&seq->lock); |
814 | sprintf(typearea, "%10s", " "); | 820 | sprintf(typearea, "%10s", " "); |
815 | } | 821 | } |
816 | } | 822 | } |
823 | return ret; | ||
817 | } | 824 | } |
818 | 825 | ||
819 | /** | 826 | /** |
820 | * nametbl_header - print name table header into the given buffer | 827 | * nametbl_header - print name table header into the given buffer |
821 | */ | 828 | */ |
822 | static void nametbl_header(struct print_buf *buf, u32 depth) | 829 | static int nametbl_header(char *buf, int len, u32 depth) |
823 | { | 830 | { |
824 | const char *header[] = { | 831 | const char *header[] = { |
825 | "Type ", | 832 | "Type ", |
@@ -829,24 +836,27 @@ static void nametbl_header(struct print_buf *buf, u32 depth) | |||
829 | }; | 836 | }; |
830 | 837 | ||
831 | int i; | 838 | int i; |
839 | int ret = 0; | ||
832 | 840 | ||
833 | if (depth > 4) | 841 | if (depth > 4) |
834 | depth = 4; | 842 | depth = 4; |
835 | for (i = 0; i < depth; i++) | 843 | for (i = 0; i < depth; i++) |
836 | tipc_printf(buf, header[i]); | 844 | ret += tipc_snprintf(buf + ret, len - ret, header[i]); |
837 | tipc_printf(buf, "\n"); | 845 | ret += tipc_snprintf(buf + ret, len - ret, "\n"); |
846 | return ret; | ||
838 | } | 847 | } |
839 | 848 | ||
840 | /** | 849 | /** |
841 | * nametbl_list - print specified name table contents into the given buffer | 850 | * nametbl_list - print specified name table contents into the given buffer |
842 | */ | 851 | */ |
843 | static void nametbl_list(struct print_buf *buf, u32 depth_info, | 852 | static int nametbl_list(char *buf, int len, u32 depth_info, |
844 | u32 type, u32 lowbound, u32 upbound) | 853 | u32 type, u32 lowbound, u32 upbound) |
845 | { | 854 | { |
846 | struct hlist_head *seq_head; | 855 | struct hlist_head *seq_head; |
847 | struct hlist_node *seq_node; | 856 | struct hlist_node *seq_node; |
848 | struct name_seq *seq; | 857 | struct name_seq *seq; |
849 | int all_types; | 858 | int all_types; |
859 | int ret = 0; | ||
850 | u32 depth; | 860 | u32 depth; |
851 | u32 i; | 861 | u32 i; |
852 | 862 | ||
@@ -854,65 +864,69 @@ static void nametbl_list(struct print_buf *buf, u32 depth_info, | |||
854 | depth = (depth_info & ~TIPC_NTQ_ALLTYPES); | 864 | depth = (depth_info & ~TIPC_NTQ_ALLTYPES); |
855 | 865 | ||
856 | if (depth == 0) | 866 | if (depth == 0) |
857 | return; | 867 | return 0; |
858 | 868 | ||
859 | if (all_types) { | 869 | if (all_types) { |
860 | /* display all entries in name table to specified depth */ | 870 | /* display all entries in name table to specified depth */ |
861 | nametbl_header(buf, depth); | 871 | ret += nametbl_header(buf, len, depth); |
862 | lowbound = 0; | 872 | lowbound = 0; |
863 | upbound = ~0; | 873 | upbound = ~0; |
864 | for (i = 0; i < tipc_nametbl_size; i++) { | 874 | for (i = 0; i < tipc_nametbl_size; i++) { |
865 | seq_head = &table.types[i]; | 875 | seq_head = &table.types[i]; |
866 | hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { | 876 | hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { |
867 | nameseq_list(seq, buf, depth, seq->type, | 877 | ret += nameseq_list(seq, buf + ret, len - ret, |
868 | lowbound, upbound, i); | 878 | depth, seq->type, |
879 | lowbound, upbound, i); | ||
869 | } | 880 | } |
870 | } | 881 | } |
871 | } else { | 882 | } else { |
872 | /* display only the sequence that matches the specified type */ | 883 | /* display only the sequence that matches the specified type */ |
873 | if (upbound < lowbound) { | 884 | if (upbound < lowbound) { |
874 | tipc_printf(buf, "invalid name sequence specified\n"); | 885 | ret += tipc_snprintf(buf + ret, len - ret, |
875 | return; | 886 | "invalid name sequence specified\n"); |
887 | return ret; | ||
876 | } | 888 | } |
877 | nametbl_header(buf, depth); | 889 | ret += nametbl_header(buf + ret, len - ret, depth); |
878 | i = hash(type); | 890 | i = hash(type); |
879 | seq_head = &table.types[i]; | 891 | seq_head = &table.types[i]; |
880 | hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { | 892 | hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { |
881 | if (seq->type == type) { | 893 | if (seq->type == type) { |
882 | nameseq_list(seq, buf, depth, type, | 894 | ret += nameseq_list(seq, buf + ret, len - ret, |
883 | lowbound, upbound, i); | 895 | depth, type, |
896 | lowbound, upbound, i); | ||
884 | break; | 897 | break; |
885 | } | 898 | } |
886 | } | 899 | } |
887 | } | 900 | } |
901 | return ret; | ||
888 | } | 902 | } |
889 | 903 | ||
890 | #define MAX_NAME_TBL_QUERY 32768 | ||
891 | |||
892 | struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space) | 904 | struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space) |
893 | { | 905 | { |
894 | struct sk_buff *buf; | 906 | struct sk_buff *buf; |
895 | struct tipc_name_table_query *argv; | 907 | struct tipc_name_table_query *argv; |
896 | struct tlv_desc *rep_tlv; | 908 | struct tlv_desc *rep_tlv; |
897 | struct print_buf b; | 909 | char *pb; |
910 | int pb_len; | ||
898 | int str_len; | 911 | int str_len; |
899 | 912 | ||
900 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NAME_TBL_QUERY)) | 913 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NAME_TBL_QUERY)) |
901 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); | 914 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); |
902 | 915 | ||
903 | buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_NAME_TBL_QUERY)); | 916 | buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); |
904 | if (!buf) | 917 | if (!buf) |
905 | return NULL; | 918 | return NULL; |
906 | 919 | ||
907 | rep_tlv = (struct tlv_desc *)buf->data; | 920 | rep_tlv = (struct tlv_desc *)buf->data; |
908 | tipc_printbuf_init(&b, TLV_DATA(rep_tlv), MAX_NAME_TBL_QUERY); | 921 | pb = TLV_DATA(rep_tlv); |
922 | pb_len = ULTRA_STRING_MAX_LEN; | ||
909 | argv = (struct tipc_name_table_query *)TLV_DATA(req_tlv_area); | 923 | argv = (struct tipc_name_table_query *)TLV_DATA(req_tlv_area); |
910 | read_lock_bh(&tipc_nametbl_lock); | 924 | read_lock_bh(&tipc_nametbl_lock); |
911 | nametbl_list(&b, ntohl(argv->depth), ntohl(argv->type), | 925 | str_len = nametbl_list(pb, pb_len, ntohl(argv->depth), |
912 | ntohl(argv->lowbound), ntohl(argv->upbound)); | 926 | ntohl(argv->type), |
927 | ntohl(argv->lowbound), ntohl(argv->upbound)); | ||
913 | read_unlock_bh(&tipc_nametbl_lock); | 928 | read_unlock_bh(&tipc_nametbl_lock); |
914 | str_len = tipc_printbuf_validate(&b); | 929 | str_len += 1; /* for "\0" */ |
915 | |||
916 | skb_put(buf, TLV_SPACE(str_len)); | 930 | skb_put(buf, TLV_SPACE(str_len)); |
917 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); | 931 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); |
918 | 932 | ||
@@ -940,8 +954,10 @@ void tipc_nametbl_stop(void) | |||
940 | /* Verify name table is empty, then release it */ | 954 | /* Verify name table is empty, then release it */ |
941 | write_lock_bh(&tipc_nametbl_lock); | 955 | write_lock_bh(&tipc_nametbl_lock); |
942 | for (i = 0; i < tipc_nametbl_size; i++) { | 956 | for (i = 0; i < tipc_nametbl_size; i++) { |
943 | if (!hlist_empty(&table.types[i])) | 957 | if (hlist_empty(&table.types[i])) |
944 | err("tipc_nametbl_stop(): hash chain %u is non-null\n", i); | 958 | continue; |
959 | pr_err("nametbl_stop(): orphaned hash chain detected\n"); | ||
960 | break; | ||
945 | } | 961 | } |
946 | kfree(table.types); | 962 | kfree(table.types); |
947 | table.types = NULL; | 963 | table.types = NULL; |