diff options
-rw-r--r-- | net/tipc/bcast.c | 63 | ||||
-rw-r--r-- | net/tipc/bearer.c | 10 | ||||
-rw-r--r-- | net/tipc/bearer.h | 2 | ||||
-rw-r--r-- | net/tipc/config.c | 27 | ||||
-rw-r--r-- | net/tipc/core.h | 4 | ||||
-rw-r--r-- | net/tipc/discover.c | 6 | ||||
-rw-r--r-- | net/tipc/link.c | 130 | ||||
-rw-r--r-- | net/tipc/log.c | 47 | ||||
-rw-r--r-- | net/tipc/name_table.c | 88 | ||||
-rw-r--r-- | net/tipc/port.c | 58 |
10 files changed, 213 insertions, 222 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index fef3689bcf23..e4e6d8cd47e6 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
@@ -701,48 +701,43 @@ void tipc_bcbearer_sort(void) | |||
701 | 701 | ||
702 | int tipc_bclink_stats(char *buf, const u32 buf_size) | 702 | int tipc_bclink_stats(char *buf, const u32 buf_size) |
703 | { | 703 | { |
704 | struct print_buf pb; | 704 | int ret; |
705 | struct tipc_stats *s; | ||
705 | 706 | ||
706 | if (!bcl) | 707 | if (!bcl) |
707 | return 0; | 708 | return 0; |
708 | 709 | ||
709 | tipc_printbuf_init(&pb, buf, buf_size); | ||
710 | |||
711 | spin_lock_bh(&bc_lock); | 710 | spin_lock_bh(&bc_lock); |
712 | 711 | ||
713 | tipc_printf(&pb, "Link <%s>\n" | 712 | s = &bcl->stats; |
714 | " Window:%u packets\n", | 713 | |
715 | bcl->name, bcl->queue_limit[0]); | 714 | ret = tipc_snprintf(buf, buf_size, "Link <%s>\n" |
716 | tipc_printf(&pb, " RX packets:%u fragments:%u/%u bundles:%u/%u\n", | 715 | " Window:%u packets\n", |
717 | bcl->stats.recv_info, | 716 | bcl->name, bcl->queue_limit[0]); |
718 | bcl->stats.recv_fragments, | 717 | ret += tipc_snprintf(buf + ret, buf_size - ret, |
719 | bcl->stats.recv_fragmented, | 718 | " RX packets:%u fragments:%u/%u bundles:%u/%u\n", |
720 | bcl->stats.recv_bundles, | 719 | s->recv_info, s->recv_fragments, |
721 | bcl->stats.recv_bundled); | 720 | s->recv_fragmented, s->recv_bundles, |
722 | tipc_printf(&pb, " TX packets:%u fragments:%u/%u bundles:%u/%u\n", | 721 | s->recv_bundled); |
723 | bcl->stats.sent_info, | 722 | ret += tipc_snprintf(buf + ret, buf_size - ret, |
724 | bcl->stats.sent_fragments, | 723 | " TX packets:%u fragments:%u/%u bundles:%u/%u\n", |
725 | bcl->stats.sent_fragmented, | 724 | s->sent_info, s->sent_fragments, |
726 | bcl->stats.sent_bundles, | 725 | s->sent_fragmented, s->sent_bundles, |
727 | bcl->stats.sent_bundled); | 726 | s->sent_bundled); |
728 | tipc_printf(&pb, " RX naks:%u defs:%u dups:%u\n", | 727 | ret += tipc_snprintf(buf + ret, buf_size - ret, |
729 | bcl->stats.recv_nacks, | 728 | " RX naks:%u defs:%u dups:%u\n", |
730 | bcl->stats.deferred_recv, | 729 | s->recv_nacks, s->deferred_recv, s->duplicates); |
731 | bcl->stats.duplicates); | 730 | ret += tipc_snprintf(buf + ret, buf_size - ret, |
732 | tipc_printf(&pb, " TX naks:%u acks:%u dups:%u\n", | 731 | " TX naks:%u acks:%u dups:%u\n", |
733 | bcl->stats.sent_nacks, | 732 | s->sent_nacks, s->sent_acks, s->retransmitted); |
734 | bcl->stats.sent_acks, | 733 | ret += tipc_snprintf(buf + ret, buf_size - ret, |
735 | bcl->stats.retransmitted); | 734 | " Congestion bearer:%u link:%u Send queue max:%u avg:%u\n", |
736 | tipc_printf(&pb, " Congestion bearer:%u link:%u Send queue max:%u avg:%u\n", | 735 | s->bearer_congs, s->link_congs, s->max_queue_sz, |
737 | bcl->stats.bearer_congs, | 736 | s->queue_sz_counts ? |
738 | bcl->stats.link_congs, | 737 | (s->accu_queue_sz / s->queue_sz_counts) : 0); |
739 | bcl->stats.max_queue_sz, | ||
740 | bcl->stats.queue_sz_counts | ||
741 | ? (bcl->stats.accu_queue_sz / bcl->stats.queue_sz_counts) | ||
742 | : 0); | ||
743 | 738 | ||
744 | spin_unlock_bh(&bc_lock); | 739 | spin_unlock_bh(&bc_lock); |
745 | return tipc_printbuf_validate(&pb); | 740 | return ret; |
746 | } | 741 | } |
747 | 742 | ||
748 | int tipc_bclink_reset_stats(void) | 743 | int tipc_bclink_reset_stats(void) |
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 1840e1fadd2e..09e71241265d 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c | |||
@@ -130,21 +130,23 @@ exit: | |||
130 | /** | 130 | /** |
131 | * tipc_media_addr_printf - record media address in print buffer | 131 | * tipc_media_addr_printf - record media address in print buffer |
132 | */ | 132 | */ |
133 | void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a) | 133 | void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a) |
134 | { | 134 | { |
135 | char addr_str[MAX_ADDR_STR]; | 135 | char addr_str[MAX_ADDR_STR]; |
136 | struct tipc_media *m_ptr; | 136 | struct tipc_media *m_ptr; |
137 | int ret; | ||
137 | 138 | ||
138 | m_ptr = media_find_id(a->media_id); | 139 | m_ptr = media_find_id(a->media_id); |
139 | 140 | ||
140 | if (m_ptr && !m_ptr->addr2str(a, addr_str, sizeof(addr_str))) | 141 | if (m_ptr && !m_ptr->addr2str(a, addr_str, sizeof(addr_str))) |
141 | tipc_printf(pb, "%s(%s)", m_ptr->name, addr_str); | 142 | ret = tipc_snprintf(buf, len, "%s(%s)", m_ptr->name, addr_str); |
142 | else { | 143 | else { |
143 | u32 i; | 144 | u32 i; |
144 | 145 | ||
145 | tipc_printf(pb, "UNKNOWN(%u)", a->media_id); | 146 | ret = tipc_snprintf(buf, len, "UNKNOWN(%u)", a->media_id); |
146 | for (i = 0; i < sizeof(a->value); i++) | 147 | for (i = 0; i < sizeof(a->value); i++) |
147 | tipc_printf(pb, "-%02x", a->value[i]); | 148 | ret += tipc_snprintf(buf - ret, len + ret, |
149 | "-%02x", a->value[i]); | ||
148 | } | 150 | } |
149 | } | 151 | } |
150 | 152 | ||
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index 4680de118aff..dd4c2abf08e7 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h | |||
@@ -179,7 +179,7 @@ void tipc_eth_media_stop(void); | |||
179 | 179 | ||
180 | int tipc_media_set_priority(const char *name, u32 new_value); | 180 | int tipc_media_set_priority(const char *name, u32 new_value); |
181 | int tipc_media_set_window(const char *name, u32 new_value); | 181 | int tipc_media_set_window(const char *name, u32 new_value); |
182 | void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a); | 182 | void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a); |
183 | struct sk_buff *tipc_media_get_names(void); | 183 | struct sk_buff *tipc_media_get_names(void); |
184 | 184 | ||
185 | struct sk_buff *tipc_bearer_get_names(void); | 185 | struct sk_buff *tipc_bearer_get_names(void); |
diff --git a/net/tipc/config.c b/net/tipc/config.c index 7978fdd99299..96cfbf834a10 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include "name_table.h" | 39 | #include "name_table.h" |
40 | #include "config.h" | 40 | #include "config.h" |
41 | 41 | ||
42 | #define REPLY_TRUNCATED "<truncated>\n" | ||
43 | |||
42 | static u32 config_port_ref; | 44 | static u32 config_port_ref; |
43 | 45 | ||
44 | static DEFINE_SPINLOCK(config_lock); | 46 | static DEFINE_SPINLOCK(config_lock); |
@@ -104,13 +106,12 @@ struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string) | |||
104 | return buf; | 106 | return buf; |
105 | } | 107 | } |
106 | 108 | ||
107 | #define MAX_STATS_INFO 2000 | ||
108 | |||
109 | static struct sk_buff *tipc_show_stats(void) | 109 | static struct sk_buff *tipc_show_stats(void) |
110 | { | 110 | { |
111 | struct sk_buff *buf; | 111 | struct sk_buff *buf; |
112 | struct tlv_desc *rep_tlv; | 112 | struct tlv_desc *rep_tlv; |
113 | struct print_buf pb; | 113 | char *pb; |
114 | int pb_len; | ||
114 | int str_len; | 115 | int str_len; |
115 | u32 value; | 116 | u32 value; |
116 | 117 | ||
@@ -121,17 +122,16 @@ static struct sk_buff *tipc_show_stats(void) | |||
121 | if (value != 0) | 122 | if (value != 0) |
122 | return tipc_cfg_reply_error_string("unsupported argument"); | 123 | return tipc_cfg_reply_error_string("unsupported argument"); |
123 | 124 | ||
124 | buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_STATS_INFO)); | 125 | buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); |
125 | if (buf == NULL) | 126 | if (buf == NULL) |
126 | return NULL; | 127 | return NULL; |
127 | 128 | ||
128 | rep_tlv = (struct tlv_desc *)buf->data; | 129 | rep_tlv = (struct tlv_desc *)buf->data; |
129 | tipc_printbuf_init(&pb, (char *)TLV_DATA(rep_tlv), MAX_STATS_INFO); | 130 | pb = TLV_DATA(rep_tlv); |
130 | 131 | pb_len = ULTRA_STRING_MAX_LEN; | |
131 | tipc_printf(&pb, "TIPC version " TIPC_MOD_VER "\n"); | ||
132 | 132 | ||
133 | /* Use additional tipc_printf()'s to return more info ... */ | 133 | str_len = tipc_snprintf(pb, pb_len, "TIPC version " TIPC_MOD_VER "\n"); |
134 | str_len = tipc_printbuf_validate(&pb); | 134 | str_len += 1; /* for "\0" */ |
135 | skb_put(buf, TLV_SPACE(str_len)); | 135 | skb_put(buf, TLV_SPACE(str_len)); |
136 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); | 136 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); |
137 | 137 | ||
@@ -408,6 +408,15 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area | |||
408 | break; | 408 | break; |
409 | } | 409 | } |
410 | 410 | ||
411 | WARN_ON(rep_tlv_buf->len > TLV_SPACE(ULTRA_STRING_MAX_LEN)); | ||
412 | |||
413 | /* Append an error message if we cannot return all requested data */ | ||
414 | if (rep_tlv_buf->len == TLV_SPACE(ULTRA_STRING_MAX_LEN)) { | ||
415 | if (*(rep_tlv_buf->data + ULTRA_STRING_MAX_LEN) != '\0') | ||
416 | sprintf(rep_tlv_buf->data + rep_tlv_buf->len - | ||
417 | sizeof(REPLY_TRUNCATED) - 1, REPLY_TRUNCATED); | ||
418 | } | ||
419 | |||
411 | /* Return reply buffer */ | 420 | /* Return reply buffer */ |
412 | exit: | 421 | exit: |
413 | spin_unlock_bh(&config_lock); | 422 | spin_unlock_bh(&config_lock); |
diff --git a/net/tipc/core.h b/net/tipc/core.h index 600c433e1467..4dcdb4859026 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h | |||
@@ -60,6 +60,8 @@ | |||
60 | 60 | ||
61 | #define TIPC_MOD_VER "2.0.0" | 61 | #define TIPC_MOD_VER "2.0.0" |
62 | 62 | ||
63 | #define ULTRA_STRING_MAX_LEN 32768 | ||
64 | |||
63 | struct tipc_msg; /* msg.h */ | 65 | struct tipc_msg; /* msg.h */ |
64 | struct print_buf; /* log.h */ | 66 | struct print_buf; /* log.h */ |
65 | 67 | ||
@@ -82,7 +84,7 @@ extern struct print_buf *const TIPC_NULL; | |||
82 | extern struct print_buf *const TIPC_CONS; | 84 | extern struct print_buf *const TIPC_CONS; |
83 | extern struct print_buf *const TIPC_LOG; | 85 | extern struct print_buf *const TIPC_LOG; |
84 | 86 | ||
85 | void tipc_printf(struct print_buf *, const char *fmt, ...); | 87 | int tipc_snprintf(char *buf, int len, const char *fmt, ...); |
86 | 88 | ||
87 | /* | 89 | /* |
88 | * TIPC_OUTPUT is the destination print buffer for system messages. | 90 | * TIPC_OUTPUT is the destination print buffer for system messages. |
diff --git a/net/tipc/discover.c b/net/tipc/discover.c index 2f91f3770097..50eaa403eb6e 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c | |||
@@ -100,12 +100,10 @@ static void disc_dupl_alert(struct tipc_bearer *b_ptr, u32 node_addr, | |||
100 | { | 100 | { |
101 | char node_addr_str[16]; | 101 | char node_addr_str[16]; |
102 | char media_addr_str[64]; | 102 | char media_addr_str[64]; |
103 | struct print_buf pb; | ||
104 | 103 | ||
105 | tipc_addr_string_fill(node_addr_str, node_addr); | 104 | tipc_addr_string_fill(node_addr_str, node_addr); |
106 | tipc_printbuf_init(&pb, media_addr_str, sizeof(media_addr_str)); | 105 | tipc_media_addr_printf(media_addr_str, sizeof(media_addr_str), |
107 | tipc_media_addr_printf(&pb, media_addr); | 106 | media_addr); |
108 | tipc_printbuf_validate(&pb); | ||
109 | pr_warn("Duplicate %s using %s seen on <%s>\n", node_addr_str, | 107 | pr_warn("Duplicate %s using %s seen on <%s>\n", node_addr_str, |
110 | media_addr_str, b_ptr->name); | 108 | media_addr_str, b_ptr->name); |
111 | } | 109 | } |
diff --git a/net/tipc/link.c b/net/tipc/link.c index a9a8b866d30a..1c1e6151875e 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -2866,112 +2866,114 @@ static u32 percent(u32 count, u32 total) | |||
2866 | */ | 2866 | */ |
2867 | static int tipc_link_stats(const char *name, char *buf, const u32 buf_size) | 2867 | static int tipc_link_stats(const char *name, char *buf, const u32 buf_size) |
2868 | { | 2868 | { |
2869 | struct print_buf pb; | 2869 | struct tipc_link *l; |
2870 | struct tipc_link *l_ptr; | 2870 | struct tipc_stats *s; |
2871 | struct tipc_node *node; | 2871 | struct tipc_node *node; |
2872 | char *status; | 2872 | char *status; |
2873 | u32 profile_total = 0; | 2873 | u32 profile_total = 0; |
2874 | int ret; | ||
2874 | 2875 | ||
2875 | if (!strcmp(name, tipc_bclink_name)) | 2876 | if (!strcmp(name, tipc_bclink_name)) |
2876 | return tipc_bclink_stats(buf, buf_size); | 2877 | return tipc_bclink_stats(buf, buf_size); |
2877 | 2878 | ||
2878 | tipc_printbuf_init(&pb, buf, buf_size); | ||
2879 | |||
2880 | read_lock_bh(&tipc_net_lock); | 2879 | read_lock_bh(&tipc_net_lock); |
2881 | l_ptr = link_find_link(name, &node); | 2880 | l = link_find_link(name, &node); |
2882 | if (!l_ptr) { | 2881 | if (!l) { |
2883 | read_unlock_bh(&tipc_net_lock); | 2882 | read_unlock_bh(&tipc_net_lock); |
2884 | return 0; | 2883 | return 0; |
2885 | } | 2884 | } |
2886 | tipc_node_lock(node); | 2885 | tipc_node_lock(node); |
2886 | s = &l->stats; | ||
2887 | 2887 | ||
2888 | if (tipc_link_is_active(l_ptr)) | 2888 | if (tipc_link_is_active(l)) |
2889 | status = "ACTIVE"; | 2889 | status = "ACTIVE"; |
2890 | else if (tipc_link_is_up(l_ptr)) | 2890 | else if (tipc_link_is_up(l)) |
2891 | status = "STANDBY"; | 2891 | status = "STANDBY"; |
2892 | else | 2892 | else |
2893 | status = "DEFUNCT"; | 2893 | status = "DEFUNCT"; |
2894 | tipc_printf(&pb, "Link <%s>\n" | 2894 | |
2895 | " %s MTU:%u Priority:%u Tolerance:%u ms" | 2895 | ret = tipc_snprintf(buf, buf_size, "Link <%s>\n" |
2896 | " Window:%u packets\n", | 2896 | " %s MTU:%u Priority:%u Tolerance:%u ms" |
2897 | l_ptr->name, status, l_ptr->max_pkt, | 2897 | " Window:%u packets\n", |
2898 | l_ptr->priority, l_ptr->tolerance, l_ptr->queue_limit[0]); | 2898 | l->name, status, l->max_pkt, l->priority, |
2899 | tipc_printf(&pb, " RX packets:%u fragments:%u/%u bundles:%u/%u\n", | 2899 | l->tolerance, l->queue_limit[0]); |
2900 | l_ptr->next_in_no - l_ptr->stats.recv_info, | 2900 | |
2901 | l_ptr->stats.recv_fragments, | 2901 | ret += tipc_snprintf(buf + ret, buf_size - ret, |
2902 | l_ptr->stats.recv_fragmented, | 2902 | " RX packets:%u fragments:%u/%u bundles:%u/%u\n", |
2903 | l_ptr->stats.recv_bundles, | 2903 | l->next_in_no - s->recv_info, s->recv_fragments, |
2904 | l_ptr->stats.recv_bundled); | 2904 | s->recv_fragmented, s->recv_bundles, |
2905 | tipc_printf(&pb, " TX packets:%u fragments:%u/%u bundles:%u/%u\n", | 2905 | s->recv_bundled); |
2906 | l_ptr->next_out_no - l_ptr->stats.sent_info, | 2906 | |
2907 | l_ptr->stats.sent_fragments, | 2907 | ret += tipc_snprintf(buf + ret, buf_size - ret, |
2908 | l_ptr->stats.sent_fragmented, | 2908 | " TX packets:%u fragments:%u/%u bundles:%u/%u\n", |
2909 | l_ptr->stats.sent_bundles, | 2909 | l->next_out_no - s->sent_info, s->sent_fragments, |
2910 | l_ptr->stats.sent_bundled); | 2910 | s->sent_fragmented, s->sent_bundles, |
2911 | profile_total = l_ptr->stats.msg_length_counts; | 2911 | s->sent_bundled); |
2912 | |||
2913 | profile_total = s->msg_length_counts; | ||
2912 | if (!profile_total) | 2914 | if (!profile_total) |
2913 | profile_total = 1; | 2915 | profile_total = 1; |
2914 | tipc_printf(&pb, " TX profile sample:%u packets average:%u octets\n" | 2916 | |
2915 | " 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% " | 2917 | ret += tipc_snprintf(buf + ret, buf_size - ret, |
2916 | "-16384:%u%% -32768:%u%% -66000:%u%%\n", | 2918 | " TX profile sample:%u packets average:%u octets\n" |
2917 | l_ptr->stats.msg_length_counts, | 2919 | " 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% " |
2918 | l_ptr->stats.msg_lengths_total / profile_total, | 2920 | "-16384:%u%% -32768:%u%% -66000:%u%%\n", |
2919 | percent(l_ptr->stats.msg_length_profile[0], profile_total), | 2921 | s->msg_length_counts, |
2920 | percent(l_ptr->stats.msg_length_profile[1], profile_total), | 2922 | s->msg_lengths_total / profile_total, |
2921 | percent(l_ptr->stats.msg_length_profile[2], profile_total), | 2923 | percent(s->msg_length_profile[0], profile_total), |
2922 | percent(l_ptr->stats.msg_length_profile[3], profile_total), | 2924 | percent(s->msg_length_profile[1], profile_total), |
2923 | percent(l_ptr->stats.msg_length_profile[4], profile_total), | 2925 | percent(s->msg_length_profile[2], profile_total), |
2924 | percent(l_ptr->stats.msg_length_profile[5], profile_total), | 2926 | percent(s->msg_length_profile[3], profile_total), |
2925 | percent(l_ptr->stats.msg_length_profile[6], profile_total)); | 2927 | percent(s->msg_length_profile[4], profile_total), |
2926 | tipc_printf(&pb, " RX states:%u probes:%u naks:%u defs:%u dups:%u\n", | 2928 | percent(s->msg_length_profile[5], profile_total), |
2927 | l_ptr->stats.recv_states, | 2929 | percent(s->msg_length_profile[6], profile_total)); |
2928 | l_ptr->stats.recv_probes, | 2930 | |
2929 | l_ptr->stats.recv_nacks, | 2931 | ret += tipc_snprintf(buf + ret, buf_size - ret, |
2930 | l_ptr->stats.deferred_recv, | 2932 | " RX states:%u probes:%u naks:%u defs:%u" |
2931 | l_ptr->stats.duplicates); | 2933 | " dups:%u\n", s->recv_states, s->recv_probes, |
2932 | tipc_printf(&pb, " TX states:%u probes:%u naks:%u acks:%u dups:%u\n", | 2934 | s->recv_nacks, s->deferred_recv, s->duplicates); |
2933 | l_ptr->stats.sent_states, | 2935 | |
2934 | l_ptr->stats.sent_probes, | 2936 | ret += tipc_snprintf(buf + ret, buf_size - ret, |
2935 | l_ptr->stats.sent_nacks, | 2937 | " TX states:%u probes:%u naks:%u acks:%u" |
2936 | l_ptr->stats.sent_acks, | 2938 | " dups:%u\n", s->sent_states, s->sent_probes, |
2937 | l_ptr->stats.retransmitted); | 2939 | s->sent_nacks, s->sent_acks, s->retransmitted); |
2938 | tipc_printf(&pb, " Congestion bearer:%u link:%u Send queue max:%u avg:%u\n", | 2940 | |
2939 | l_ptr->stats.bearer_congs, | 2941 | ret += tipc_snprintf(buf + ret, buf_size - ret, |
2940 | l_ptr->stats.link_congs, | 2942 | " Congestion bearer:%u link:%u Send queue" |
2941 | l_ptr->stats.max_queue_sz, | 2943 | " max:%u avg:%u\n", s->bearer_congs, s->link_congs, |
2942 | l_ptr->stats.queue_sz_counts | 2944 | s->max_queue_sz, s->queue_sz_counts ? |
2943 | ? (l_ptr->stats.accu_queue_sz / l_ptr->stats.queue_sz_counts) | 2945 | (s->accu_queue_sz / s->queue_sz_counts) : 0); |
2944 | : 0); | ||
2945 | 2946 | ||
2946 | tipc_node_unlock(node); | 2947 | tipc_node_unlock(node); |
2947 | read_unlock_bh(&tipc_net_lock); | 2948 | read_unlock_bh(&tipc_net_lock); |
2948 | return tipc_printbuf_validate(&pb); | 2949 | return ret; |
2949 | } | 2950 | } |
2950 | 2951 | ||
2951 | #define MAX_LINK_STATS_INFO 2000 | ||
2952 | |||
2953 | struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_space) | 2952 | struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_space) |
2954 | { | 2953 | { |
2955 | struct sk_buff *buf; | 2954 | struct sk_buff *buf; |
2956 | struct tlv_desc *rep_tlv; | 2955 | struct tlv_desc *rep_tlv; |
2957 | int str_len; | 2956 | int str_len; |
2957 | int pb_len; | ||
2958 | char *pb; | ||
2958 | 2959 | ||
2959 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME)) | 2960 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME)) |
2960 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); | 2961 | return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); |
2961 | 2962 | ||
2962 | buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_LINK_STATS_INFO)); | 2963 | buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); |
2963 | if (!buf) | 2964 | if (!buf) |
2964 | return NULL; | 2965 | return NULL; |
2965 | 2966 | ||
2966 | rep_tlv = (struct tlv_desc *)buf->data; | 2967 | rep_tlv = (struct tlv_desc *)buf->data; |
2967 | 2968 | pb = TLV_DATA(rep_tlv); | |
2969 | pb_len = ULTRA_STRING_MAX_LEN; | ||
2968 | str_len = tipc_link_stats((char *)TLV_DATA(req_tlv_area), | 2970 | str_len = tipc_link_stats((char *)TLV_DATA(req_tlv_area), |
2969 | (char *)TLV_DATA(rep_tlv), MAX_LINK_STATS_INFO); | 2971 | pb, pb_len); |
2970 | if (!str_len) { | 2972 | if (!str_len) { |
2971 | kfree_skb(buf); | 2973 | kfree_skb(buf); |
2972 | return tipc_cfg_reply_error_string("link not found"); | 2974 | return tipc_cfg_reply_error_string("link not found"); |
2973 | } | 2975 | } |
2974 | 2976 | str_len += 1; /* for "\0" */ | |
2975 | skb_put(buf, TLV_SPACE(str_len)); | 2977 | skb_put(buf, TLV_SPACE(str_len)); |
2976 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); | 2978 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); |
2977 | 2979 | ||
diff --git a/net/tipc/log.c b/net/tipc/log.c index d01e37a61b93..fa7ce927fda5 100644 --- a/net/tipc/log.c +++ b/net/tipc/log.c | |||
@@ -125,40 +125,6 @@ static int tipc_printbuf_empty(struct print_buf *pb) | |||
125 | } | 125 | } |
126 | 126 | ||
127 | /** | 127 | /** |
128 | * tipc_printbuf_validate - check for print buffer overflow | ||
129 | * @pb: pointer to print buffer structure | ||
130 | * | ||
131 | * Verifies that a print buffer has captured all data written to it. | ||
132 | * If data has been lost, linearize buffer and prepend an error message | ||
133 | * | ||
134 | * Returns length of print buffer data string (including trailing NUL) | ||
135 | */ | ||
136 | int tipc_printbuf_validate(struct print_buf *pb) | ||
137 | { | ||
138 | char *err = "\n\n*** PRINT BUFFER OVERFLOW ***\n\n"; | ||
139 | char *cp_buf; | ||
140 | struct print_buf cb; | ||
141 | |||
142 | if (!pb->buf) | ||
143 | return 0; | ||
144 | |||
145 | if (pb->buf[pb->size - 1] == 0) { | ||
146 | cp_buf = kmalloc(pb->size, GFP_ATOMIC); | ||
147 | if (cp_buf) { | ||
148 | tipc_printbuf_init(&cb, cp_buf, pb->size); | ||
149 | tipc_printbuf_move(&cb, pb); | ||
150 | tipc_printbuf_move(pb, &cb); | ||
151 | kfree(cp_buf); | ||
152 | memcpy(pb->buf, err, strlen(err)); | ||
153 | } else { | ||
154 | tipc_printbuf_reset(pb); | ||
155 | tipc_printf(pb, err); | ||
156 | } | ||
157 | } | ||
158 | return pb->crs - pb->buf + 1; | ||
159 | } | ||
160 | |||
161 | /** | ||
162 | * tipc_printbuf_move - move print buffer contents to another print buffer | 128 | * tipc_printbuf_move - move print buffer contents to another print buffer |
163 | * @pb_to: pointer to destination print buffer structure | 129 | * @pb_to: pointer to destination print buffer structure |
164 | * @pb_from: pointer to source print buffer structure | 130 | * @pb_from: pointer to source print buffer structure |
@@ -204,23 +170,20 @@ static void tipc_printbuf_move(struct print_buf *pb_to, | |||
204 | } | 170 | } |
205 | 171 | ||
206 | /** | 172 | /** |
207 | * tipc_printf - append formatted output to print buffer | 173 | * tipc_snprintf - append formatted output to print buffer |
208 | * @pb: pointer to print buffer | 174 | * @buf: pointer to print buffer |
175 | * @len: buffer length | ||
209 | * @fmt: formatted info to be printed | 176 | * @fmt: formatted info to be printed |
210 | */ | 177 | */ |
211 | void tipc_printf(struct print_buf *pb, const char *fmt, ...) | 178 | int tipc_snprintf(char *buf, int len, const char *fmt, ...) |
212 | { | 179 | { |
213 | int i; | 180 | int i; |
214 | va_list args; | 181 | va_list args; |
215 | char *buf; | ||
216 | int len; | ||
217 | 182 | ||
218 | buf = pb->crs; | ||
219 | len = pb->buf + pb->size - pb->crs; | ||
220 | va_start(args, fmt); | 183 | va_start(args, fmt); |
221 | i = vscnprintf(buf, len, fmt, args); | 184 | i = vscnprintf(buf, len, fmt, args); |
222 | va_end(args); | 185 | va_end(args); |
223 | pb->crs += i; | 186 | return i; |
224 | } | 187 | } |
225 | 188 | ||
226 | /** | 189 | /** |
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index c8b0b5c3c56e..360c478b0b53 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c | |||
@@ -753,19 +753,20 @@ void tipc_nametbl_unsubscribe(struct tipc_subscription *s) | |||
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 | ||
diff --git a/net/tipc/port.c b/net/tipc/port.c index 2cbac3956fc9..07c42fba672b 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c | |||
@@ -581,67 +581,73 @@ exit: | |||
581 | kfree_skb(buf); | 581 | kfree_skb(buf); |
582 | } | 582 | } |
583 | 583 | ||
584 | static void port_print(struct tipc_port *p_ptr, struct print_buf *buf, int full_id) | 584 | static int port_print(struct tipc_port *p_ptr, char *buf, int len, int full_id) |
585 | { | 585 | { |
586 | struct publication *publ; | 586 | struct publication *publ; |
587 | int ret; | ||
587 | 588 | ||
588 | if (full_id) | 589 | if (full_id) |
589 | tipc_printf(buf, "<%u.%u.%u:%u>:", | 590 | ret = tipc_snprintf(buf, len, "<%u.%u.%u:%u>:", |
590 | tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr), | 591 | tipc_zone(tipc_own_addr), |
591 | tipc_node(tipc_own_addr), p_ptr->ref); | 592 | tipc_cluster(tipc_own_addr), |
593 | tipc_node(tipc_own_addr), p_ptr->ref); | ||
592 | else | 594 | else |
593 | tipc_printf(buf, "%-10u:", p_ptr->ref); | 595 | ret = tipc_snprintf(buf, len, "%-10u:", p_ptr->ref); |
594 | 596 | ||
595 | if (p_ptr->connected) { | 597 | if (p_ptr->connected) { |
596 | u32 dport = port_peerport(p_ptr); | 598 | u32 dport = port_peerport(p_ptr); |
597 | u32 destnode = port_peernode(p_ptr); | 599 | u32 destnode = port_peernode(p_ptr); |
598 | 600 | ||
599 | tipc_printf(buf, " connected to <%u.%u.%u:%u>", | 601 | ret += tipc_snprintf(buf + ret, len - ret, |
600 | tipc_zone(destnode), tipc_cluster(destnode), | 602 | " connected to <%u.%u.%u:%u>", |
601 | tipc_node(destnode), dport); | 603 | tipc_zone(destnode), |
604 | tipc_cluster(destnode), | ||
605 | tipc_node(destnode), dport); | ||
602 | if (p_ptr->conn_type != 0) | 606 | if (p_ptr->conn_type != 0) |
603 | tipc_printf(buf, " via {%u,%u}", | 607 | ret += tipc_snprintf(buf + ret, len - ret, |
604 | p_ptr->conn_type, | 608 | " via {%u,%u}", p_ptr->conn_type, |
605 | p_ptr->conn_instance); | 609 | p_ptr->conn_instance); |
606 | } else if (p_ptr->published) { | 610 | } else if (p_ptr->published) { |
607 | tipc_printf(buf, " bound to"); | 611 | ret += tipc_snprintf(buf + ret, len - ret, " bound to"); |
608 | list_for_each_entry(publ, &p_ptr->publications, pport_list) { | 612 | list_for_each_entry(publ, &p_ptr->publications, pport_list) { |
609 | if (publ->lower == publ->upper) | 613 | if (publ->lower == publ->upper) |
610 | tipc_printf(buf, " {%u,%u}", publ->type, | 614 | ret += tipc_snprintf(buf + ret, len - ret, |
611 | publ->lower); | 615 | " {%u,%u}", publ->type, |
616 | publ->lower); | ||
612 | else | 617 | else |
613 | tipc_printf(buf, " {%u,%u,%u}", publ->type, | 618 | ret += tipc_snprintf(buf + ret, len - ret, |
614 | publ->lower, publ->upper); | 619 | " {%u,%u,%u}", publ->type, |
620 | publ->lower, publ->upper); | ||
615 | } | 621 | } |
616 | } | 622 | } |
617 | tipc_printf(buf, "\n"); | 623 | ret += tipc_snprintf(buf + ret, len - ret, "\n"); |
624 | return ret; | ||
618 | } | 625 | } |
619 | 626 | ||
620 | #define MAX_PORT_QUERY 32768 | ||
621 | |||
622 | struct sk_buff *tipc_port_get_ports(void) | 627 | struct sk_buff *tipc_port_get_ports(void) |
623 | { | 628 | { |
624 | struct sk_buff *buf; | 629 | struct sk_buff *buf; |
625 | struct tlv_desc *rep_tlv; | 630 | struct tlv_desc *rep_tlv; |
626 | struct print_buf pb; | 631 | char *pb; |
632 | int pb_len; | ||
627 | struct tipc_port *p_ptr; | 633 | struct tipc_port *p_ptr; |
628 | int str_len; | 634 | int str_len = 0; |
629 | 635 | ||
630 | buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_QUERY)); | 636 | buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); |
631 | if (!buf) | 637 | if (!buf) |
632 | return NULL; | 638 | return NULL; |
633 | rep_tlv = (struct tlv_desc *)buf->data; | 639 | rep_tlv = (struct tlv_desc *)buf->data; |
640 | pb = TLV_DATA(rep_tlv); | ||
641 | pb_len = ULTRA_STRING_MAX_LEN; | ||
634 | 642 | ||
635 | tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_QUERY); | ||
636 | spin_lock_bh(&tipc_port_list_lock); | 643 | spin_lock_bh(&tipc_port_list_lock); |
637 | list_for_each_entry(p_ptr, &ports, port_list) { | 644 | list_for_each_entry(p_ptr, &ports, port_list) { |
638 | spin_lock_bh(p_ptr->lock); | 645 | spin_lock_bh(p_ptr->lock); |
639 | port_print(p_ptr, &pb, 0); | 646 | str_len += port_print(p_ptr, pb, pb_len, 0); |
640 | spin_unlock_bh(p_ptr->lock); | 647 | spin_unlock_bh(p_ptr->lock); |
641 | } | 648 | } |
642 | spin_unlock_bh(&tipc_port_list_lock); | 649 | spin_unlock_bh(&tipc_port_list_lock); |
643 | str_len = tipc_printbuf_validate(&pb); | 650 | str_len += 1; /* for "\0" */ |
644 | |||
645 | skb_put(buf, TLV_SPACE(str_len)); | 651 | skb_put(buf, TLV_SPACE(str_len)); |
646 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); | 652 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); |
647 | 653 | ||