Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tipc: phase out most of the struct print_buf usage

The tipc_printf is renamed to tipc_snprintf, as the new name
describes more what the function actually does. It is also
changed to take a buffer and length parameter and return
number of characters written to the buffer. All callers of
this function that used to pass a print_buf are updated.

Final removal of the struct print_buf itself will be done
synchronously with the pending removal of the deprecated
logging code that also was using it.

Functions that build up a response message with a list of
ports, nametable contents etc. are changed to return the number
of characters written to the output buffer. This information
was previously hidden in a field of the print_buf struct, and
the number of chars written was fetched with a call to
tipc_printbuf_validate. This function is removed since it
is no longer referenced nor needed.

A generic max size ULTRA_STRING_MAX_LEN is defined, named
in keeping with the existing TIPC_TLV_ULTRA_STRING, and the
various definitions in port, link and nametable code that
largely duplicated this information are removed. This means
that amount of link statistics that can be returned is now
increased from 2k to 32k.

The buffer overflow check is now done just before the reply
message is passed over netlink or TIPC to a remote node and
the message indicating a truncated buffer is changed to a less
dramatic one (less CAPS), placed at the end of the message.

Signed-off-by: Erik Hugne <erik.hugne@ericsson.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>

authored by

Erik Hugne and committed by
Paul Gortmaker
dc1aed37 e2dbd601

+213 -222
+29 -34
net/tipc/bcast.c
··· 701 701 702 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 707 if (!bcl) 707 708 return 0; 708 709 709 - tipc_printbuf_init(&pb, buf, buf_size); 710 - 711 710 spin_lock_bh(&bc_lock); 712 711 713 - tipc_printf(&pb, "Link <%s>\n" 714 - " Window:%u packets\n", 715 - bcl->name, bcl->queue_limit[0]); 716 - tipc_printf(&pb, " RX packets:%u fragments:%u/%u bundles:%u/%u\n", 717 - bcl->stats.recv_info, 718 - bcl->stats.recv_fragments, 719 - bcl->stats.recv_fragmented, 720 - bcl->stats.recv_bundles, 721 - bcl->stats.recv_bundled); 722 - tipc_printf(&pb, " TX packets:%u fragments:%u/%u bundles:%u/%u\n", 723 - bcl->stats.sent_info, 724 - bcl->stats.sent_fragments, 725 - bcl->stats.sent_fragmented, 726 - bcl->stats.sent_bundles, 727 - bcl->stats.sent_bundled); 728 - tipc_printf(&pb, " RX naks:%u defs:%u dups:%u\n", 729 - bcl->stats.recv_nacks, 730 - bcl->stats.deferred_recv, 731 - bcl->stats.duplicates); 732 - tipc_printf(&pb, " TX naks:%u acks:%u dups:%u\n", 733 - bcl->stats.sent_nacks, 734 - bcl->stats.sent_acks, 735 - bcl->stats.retransmitted); 736 - tipc_printf(&pb, " Congestion bearer:%u link:%u Send queue max:%u avg:%u\n", 737 - bcl->stats.bearer_congs, 738 - bcl->stats.link_congs, 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); 712 + s = &bcl->stats; 713 + 714 + ret = tipc_snprintf(buf, buf_size, "Link <%s>\n" 715 + " Window:%u packets\n", 716 + bcl->name, bcl->queue_limit[0]); 717 + ret += tipc_snprintf(buf + ret, buf_size - ret, 718 + " RX packets:%u fragments:%u/%u bundles:%u/%u\n", 719 + s->recv_info, s->recv_fragments, 720 + s->recv_fragmented, s->recv_bundles, 721 + s->recv_bundled); 722 + ret += tipc_snprintf(buf + ret, buf_size - ret, 723 + " TX packets:%u fragments:%u/%u bundles:%u/%u\n", 724 + s->sent_info, s->sent_fragments, 725 + s->sent_fragmented, s->sent_bundles, 726 + s->sent_bundled); 727 + ret += tipc_snprintf(buf + ret, buf_size - ret, 728 + " RX naks:%u defs:%u dups:%u\n", 729 + s->recv_nacks, s->deferred_recv, s->duplicates); 730 + ret += tipc_snprintf(buf + ret, buf_size - ret, 731 + " TX naks:%u acks:%u dups:%u\n", 732 + s->sent_nacks, s->sent_acks, s->retransmitted); 733 + ret += tipc_snprintf(buf + ret, buf_size - ret, 734 + " Congestion bearer:%u link:%u Send queue max:%u avg:%u\n", 735 + s->bearer_congs, s->link_congs, s->max_queue_sz, 736 + s->queue_sz_counts ? 737 + (s->accu_queue_sz / s->queue_sz_counts) : 0); 743 738 744 739 spin_unlock_bh(&bc_lock); 745 - return tipc_printbuf_validate(&pb); 740 + return ret; 746 741 } 747 742 748 743 int tipc_bclink_reset_stats(void)
+6 -4
net/tipc/bearer.c
··· 130 130 /** 131 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 135 char addr_str[MAX_ADDR_STR]; 136 136 struct tipc_media *m_ptr; 137 + int ret; 137 138 138 139 m_ptr = media_find_id(a->media_id); 139 140 140 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 143 else { 143 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 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
+1 -1
net/tipc/bearer.h
··· 179 179 180 180 int tipc_media_set_priority(const char *name, u32 new_value); 181 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 183 struct sk_buff *tipc_media_get_names(void); 184 184 185 185 struct sk_buff *tipc_bearer_get_names(void);
+18 -9
net/tipc/config.c
··· 39 39 #include "name_table.h" 40 40 #include "config.h" 41 41 42 + #define REPLY_TRUNCATED "<truncated>\n" 43 + 42 44 static u32 config_port_ref; 43 45 44 46 static DEFINE_SPINLOCK(config_lock); ··· 106 104 return buf; 107 105 } 108 106 109 - #define MAX_STATS_INFO 2000 110 - 111 107 static struct sk_buff *tipc_show_stats(void) 112 108 { 113 109 struct sk_buff *buf; 114 110 struct tlv_desc *rep_tlv; 115 - struct print_buf pb; 111 + char *pb; 112 + int pb_len; 116 113 int str_len; 117 114 u32 value; 118 115 ··· 122 121 if (value != 0) 123 122 return tipc_cfg_reply_error_string("unsupported argument"); 124 123 125 - buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_STATS_INFO)); 124 + buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); 126 125 if (buf == NULL) 127 126 return NULL; 128 127 129 128 rep_tlv = (struct tlv_desc *)buf->data; 130 - tipc_printbuf_init(&pb, (char *)TLV_DATA(rep_tlv), MAX_STATS_INFO); 129 + pb = TLV_DATA(rep_tlv); 130 + pb_len = ULTRA_STRING_MAX_LEN; 131 131 132 - tipc_printf(&pb, "TIPC version " TIPC_MOD_VER "\n"); 133 - 134 - /* Use additional tipc_printf()'s to return more info ... */ 135 - str_len = tipc_printbuf_validate(&pb); 132 + str_len = tipc_snprintf(pb, pb_len, "TIPC version " TIPC_MOD_VER "\n"); 133 + str_len += 1; /* for "\0" */ 136 134 skb_put(buf, TLV_SPACE(str_len)); 137 135 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); 138 136 ··· 406 406 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 407 407 " (unknown command)"); 408 408 break; 409 + } 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); 409 418 } 410 419 411 420 /* Return reply buffer */
+3 -1
net/tipc/core.h
··· 60 60 61 61 #define TIPC_MOD_VER "2.0.0" 62 62 63 + #define ULTRA_STRING_MAX_LEN 32768 64 + 63 65 struct tipc_msg; /* msg.h */ 64 66 struct print_buf; /* log.h */ 65 67 ··· 84 82 extern struct print_buf *const TIPC_CONS; 85 83 extern struct print_buf *const TIPC_LOG; 86 84 87 - void tipc_printf(struct print_buf *, const char *fmt, ...); 85 + int tipc_snprintf(char *buf, int len, const char *fmt, ...); 88 86 89 87 /* 90 88 * TIPC_OUTPUT is the destination print buffer for system messages.
+2 -4
net/tipc/discover.c
··· 100 100 { 101 101 char node_addr_str[16]; 102 102 char media_addr_str[64]; 103 - struct print_buf pb; 104 103 105 104 tipc_addr_string_fill(node_addr_str, node_addr); 106 - tipc_printbuf_init(&pb, media_addr_str, sizeof(media_addr_str)); 107 - tipc_media_addr_printf(&pb, media_addr); 108 - tipc_printbuf_validate(&pb); 105 + tipc_media_addr_printf(media_addr_str, sizeof(media_addr_str), 106 + media_addr); 109 107 pr_warn("Duplicate %s using %s seen on <%s>\n", node_addr_str, 110 108 media_addr_str, b_ptr->name); 111 109 }
+66 -64
net/tipc/link.c
··· 2866 2866 */ 2867 2867 static int tipc_link_stats(const char *name, char *buf, const u32 buf_size) 2868 2868 { 2869 - struct print_buf pb; 2870 - struct tipc_link *l_ptr; 2869 + struct tipc_link *l; 2870 + struct tipc_stats *s; 2871 2871 struct tipc_node *node; 2872 2872 char *status; 2873 2873 u32 profile_total = 0; 2874 + int ret; 2874 2875 2875 2876 if (!strcmp(name, tipc_bclink_name)) 2876 2877 return tipc_bclink_stats(buf, buf_size); 2877 2878 2878 - tipc_printbuf_init(&pb, buf, buf_size); 2879 - 2880 2879 read_lock_bh(&tipc_net_lock); 2881 - l_ptr = link_find_link(name, &node); 2882 - if (!l_ptr) { 2880 + l = link_find_link(name, &node); 2881 + if (!l) { 2883 2882 read_unlock_bh(&tipc_net_lock); 2884 2883 return 0; 2885 2884 } 2886 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 2889 status = "ACTIVE"; 2890 - else if (tipc_link_is_up(l_ptr)) 2890 + else if (tipc_link_is_up(l)) 2891 2891 status = "STANDBY"; 2892 2892 else 2893 2893 status = "DEFUNCT"; 2894 - tipc_printf(&pb, "Link <%s>\n" 2895 - " %s MTU:%u Priority:%u Tolerance:%u ms" 2896 - " Window:%u packets\n", 2897 - l_ptr->name, status, l_ptr->max_pkt, 2898 - l_ptr->priority, l_ptr->tolerance, l_ptr->queue_limit[0]); 2899 - tipc_printf(&pb, " RX packets:%u fragments:%u/%u bundles:%u/%u\n", 2900 - l_ptr->next_in_no - l_ptr->stats.recv_info, 2901 - l_ptr->stats.recv_fragments, 2902 - l_ptr->stats.recv_fragmented, 2903 - l_ptr->stats.recv_bundles, 2904 - l_ptr->stats.recv_bundled); 2905 - tipc_printf(&pb, " TX packets:%u fragments:%u/%u bundles:%u/%u\n", 2906 - l_ptr->next_out_no - l_ptr->stats.sent_info, 2907 - l_ptr->stats.sent_fragments, 2908 - l_ptr->stats.sent_fragmented, 2909 - l_ptr->stats.sent_bundles, 2910 - l_ptr->stats.sent_bundled); 2911 - profile_total = l_ptr->stats.msg_length_counts; 2894 + 2895 + ret = tipc_snprintf(buf, buf_size, "Link <%s>\n" 2896 + " %s MTU:%u Priority:%u Tolerance:%u ms" 2897 + " Window:%u packets\n", 2898 + l->name, status, l->max_pkt, l->priority, 2899 + l->tolerance, l->queue_limit[0]); 2900 + 2901 + ret += tipc_snprintf(buf + ret, buf_size - ret, 2902 + " RX packets:%u fragments:%u/%u bundles:%u/%u\n", 2903 + l->next_in_no - s->recv_info, s->recv_fragments, 2904 + s->recv_fragmented, s->recv_bundles, 2905 + s->recv_bundled); 2906 + 2907 + ret += tipc_snprintf(buf + ret, buf_size - ret, 2908 + " TX packets:%u fragments:%u/%u bundles:%u/%u\n", 2909 + l->next_out_no - s->sent_info, s->sent_fragments, 2910 + s->sent_fragmented, s->sent_bundles, 2911 + s->sent_bundled); 2912 + 2913 + profile_total = s->msg_length_counts; 2912 2914 if (!profile_total) 2913 2915 profile_total = 1; 2914 - tipc_printf(&pb, " TX profile sample:%u packets average:%u octets\n" 2915 - " 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% " 2916 - "-16384:%u%% -32768:%u%% -66000:%u%%\n", 2917 - l_ptr->stats.msg_length_counts, 2918 - l_ptr->stats.msg_lengths_total / profile_total, 2919 - percent(l_ptr->stats.msg_length_profile[0], profile_total), 2920 - percent(l_ptr->stats.msg_length_profile[1], profile_total), 2921 - percent(l_ptr->stats.msg_length_profile[2], profile_total), 2922 - percent(l_ptr->stats.msg_length_profile[3], profile_total), 2923 - percent(l_ptr->stats.msg_length_profile[4], profile_total), 2924 - percent(l_ptr->stats.msg_length_profile[5], profile_total), 2925 - percent(l_ptr->stats.msg_length_profile[6], profile_total)); 2926 - tipc_printf(&pb, " RX states:%u probes:%u naks:%u defs:%u dups:%u\n", 2927 - l_ptr->stats.recv_states, 2928 - l_ptr->stats.recv_probes, 2929 - l_ptr->stats.recv_nacks, 2930 - l_ptr->stats.deferred_recv, 2931 - l_ptr->stats.duplicates); 2932 - tipc_printf(&pb, " TX states:%u probes:%u naks:%u acks:%u dups:%u\n", 2933 - l_ptr->stats.sent_states, 2934 - l_ptr->stats.sent_probes, 2935 - l_ptr->stats.sent_nacks, 2936 - l_ptr->stats.sent_acks, 2937 - l_ptr->stats.retransmitted); 2938 - tipc_printf(&pb, " Congestion bearer:%u link:%u Send queue max:%u avg:%u\n", 2939 - l_ptr->stats.bearer_congs, 2940 - l_ptr->stats.link_congs, 2941 - l_ptr->stats.max_queue_sz, 2942 - l_ptr->stats.queue_sz_counts 2943 - ? (l_ptr->stats.accu_queue_sz / l_ptr->stats.queue_sz_counts) 2944 - : 0); 2916 + 2917 + ret += tipc_snprintf(buf + ret, buf_size - ret, 2918 + " TX profile sample:%u packets average:%u octets\n" 2919 + " 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% " 2920 + "-16384:%u%% -32768:%u%% -66000:%u%%\n", 2921 + s->msg_length_counts, 2922 + s->msg_lengths_total / profile_total, 2923 + percent(s->msg_length_profile[0], profile_total), 2924 + percent(s->msg_length_profile[1], profile_total), 2925 + percent(s->msg_length_profile[2], profile_total), 2926 + percent(s->msg_length_profile[3], profile_total), 2927 + percent(s->msg_length_profile[4], profile_total), 2928 + percent(s->msg_length_profile[5], profile_total), 2929 + percent(s->msg_length_profile[6], profile_total)); 2930 + 2931 + ret += tipc_snprintf(buf + ret, buf_size - ret, 2932 + " RX states:%u probes:%u naks:%u defs:%u" 2933 + " dups:%u\n", s->recv_states, s->recv_probes, 2934 + s->recv_nacks, s->deferred_recv, s->duplicates); 2935 + 2936 + ret += tipc_snprintf(buf + ret, buf_size - ret, 2937 + " TX states:%u probes:%u naks:%u acks:%u" 2938 + " dups:%u\n", s->sent_states, s->sent_probes, 2939 + s->sent_nacks, s->sent_acks, s->retransmitted); 2940 + 2941 + ret += tipc_snprintf(buf + ret, buf_size - ret, 2942 + " Congestion bearer:%u link:%u Send queue" 2943 + " max:%u avg:%u\n", s->bearer_congs, s->link_congs, 2944 + s->max_queue_sz, s->queue_sz_counts ? 2945 + (s->accu_queue_sz / s->queue_sz_counts) : 0); 2945 2946 2946 2947 tipc_node_unlock(node); 2947 2948 read_unlock_bh(&tipc_net_lock); 2948 - return tipc_printbuf_validate(&pb); 2949 + return ret; 2949 2950 } 2950 - 2951 - #define MAX_LINK_STATS_INFO 2000 2952 2951 2953 2952 struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_space) 2954 2953 { 2955 2954 struct sk_buff *buf; 2956 2955 struct tlv_desc *rep_tlv; 2957 2956 int str_len; 2957 + int pb_len; 2958 + char *pb; 2958 2959 2959 2960 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME)) 2960 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 2964 if (!buf) 2964 2965 return NULL; 2965 2966 2966 2967 rep_tlv = (struct tlv_desc *)buf->data; 2967 - 2968 + pb = TLV_DATA(rep_tlv); 2969 + pb_len = ULTRA_STRING_MAX_LEN; 2968 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 2972 if (!str_len) { 2971 2973 kfree_skb(buf); 2972 2974 return tipc_cfg_reply_error_string("link not found"); 2973 2975 } 2974 - 2976 + str_len += 1; /* for "\0" */ 2975 2977 skb_put(buf, TLV_SPACE(str_len)); 2976 2978 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); 2977 2979
+5 -42
net/tipc/log.c
··· 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 128 * tipc_printbuf_move - move print buffer contents to another print buffer 163 129 * @pb_to: pointer to destination print buffer structure 164 130 * @pb_from: pointer to source print buffer structure ··· 170 204 } 171 205 172 206 /** 173 - * tipc_printf - append formatted output to print buffer 174 - * @pb: pointer to print buffer 207 + * tipc_snprintf - append formatted output to print buffer 208 + * @buf: pointer to print buffer 209 + * @len: buffer length 175 210 * @fmt: formatted info to be printed 176 211 */ 177 - void tipc_printf(struct print_buf *pb, const char *fmt, ...) 212 + int tipc_snprintf(char *buf, int len, const char *fmt, ...) 178 213 { 179 214 int i; 180 215 va_list args; 181 - char *buf; 182 - int len; 183 216 184 - buf = pb->crs; 185 - len = pb->buf + pb->size - pb->crs; 186 217 va_start(args, fmt); 187 218 i = vscnprintf(buf, len, fmt, args); 188 219 va_end(args); 189 - pb->crs += i; 220 + return i; 190 221 } 191 222 192 223 /**
+51 -37
net/tipc/name_table.c
··· 753 753 /** 754 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 757 u32 index) 758 758 { 759 759 char portIdStr[27]; 760 760 const char *scope_str[] = {"", " zone", " cluster", " node"}; 761 761 struct publication *publ; 762 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 767 if (depth == 2) { 767 - tipc_printf(buf, "\n"); 768 - return; 768 + ret += tipc_snprintf(buf - ret, len + ret, "\n"); 769 + return ret; 769 770 } 770 771 771 772 info = sseq->info; ··· 775 774 sprintf(portIdStr, "<%u.%u.%u:%u>", 776 775 tipc_zone(publ->node), tipc_cluster(publ->node), 777 776 tipc_node(publ->node), publ->ref); 778 - tipc_printf(buf, "%-26s ", portIdStr); 777 + ret += tipc_snprintf(buf + ret, len - ret, "%-26s ", portIdStr); 779 778 if (depth > 3) { 780 - tipc_printf(buf, "%-10u %s", publ->key, 781 - scope_str[publ->scope]); 779 + ret += tipc_snprintf(buf + ret, len - ret, "%-10u %s", 780 + publ->key, scope_str[publ->scope]); 782 781 } 783 782 if (!list_is_last(&publ->zone_list, &info->zone_list)) 784 - tipc_printf(buf, "\n%33s", " "); 783 + ret += tipc_snprintf(buf + ret, len - ret, 784 + "\n%33s", " "); 785 785 }; 786 786 787 - tipc_printf(buf, "\n"); 787 + ret += tipc_snprintf(buf + ret, len - ret, "\n"); 788 + return ret; 788 789 } 789 790 790 791 /** 791 792 * nameseq_list - print specified name sequence contents into the given buffer 792 793 */ 793 - static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth, 794 + static int nameseq_list(struct name_seq *seq, char *buf, int len, u32 depth, 794 795 u32 type, u32 lowbound, u32 upbound, u32 index) 795 796 { 796 797 struct sub_seq *sseq; 797 798 char typearea[11]; 799 + int ret = 0; 798 800 799 801 if (seq->first_free == 0) 800 - return; 802 + return 0; 801 803 802 804 sprintf(typearea, "%-10u", seq->type); 803 805 804 806 if (depth == 1) { 805 - tipc_printf(buf, "%s\n", typearea); 806 - return; 807 + ret += tipc_snprintf(buf, len, "%s\n", typearea); 808 + return ret; 807 809 } 808 810 809 811 for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) { 810 812 if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) { 811 - tipc_printf(buf, "%s ", typearea); 813 + ret += tipc_snprintf(buf + ret, len - ret, "%s ", 814 + typearea); 812 815 spin_lock_bh(&seq->lock); 813 - subseq_list(sseq, buf, depth, index); 816 + ret += subseq_list(sseq, buf + ret, len - ret, 817 + depth, index); 814 818 spin_unlock_bh(&seq->lock); 815 819 sprintf(typearea, "%10s", " "); 816 820 } 817 821 } 822 + return ret; 818 823 } 819 824 820 825 /** 821 826 * nametbl_header - print name table header into the given buffer 822 827 */ 823 - static void nametbl_header(struct print_buf *buf, u32 depth) 828 + static int nametbl_header(char *buf, int len, u32 depth) 824 829 { 825 830 const char *header[] = { 826 831 "Type ", ··· 836 829 }; 837 830 838 831 int i; 832 + int ret = 0; 839 833 840 834 if (depth > 4) 841 835 depth = 4; 842 836 for (i = 0; i < depth; i++) 843 - tipc_printf(buf, header[i]); 844 - tipc_printf(buf, "\n"); 837 + ret += tipc_snprintf(buf + ret, len - ret, header[i]); 838 + ret += tipc_snprintf(buf + ret, len - ret, "\n"); 839 + return ret; 845 840 } 846 841 847 842 /** 848 843 * nametbl_list - print specified name table contents into the given buffer 849 844 */ 850 - static void nametbl_list(struct print_buf *buf, u32 depth_info, 845 + static int nametbl_list(char *buf, int len, u32 depth_info, 851 846 u32 type, u32 lowbound, u32 upbound) 852 847 { 853 848 struct hlist_head *seq_head; 854 849 struct hlist_node *seq_node; 855 850 struct name_seq *seq; 856 851 int all_types; 852 + int ret = 0; 857 853 u32 depth; 858 854 u32 i; 859 855 ··· 864 854 depth = (depth_info & ~TIPC_NTQ_ALLTYPES); 865 855 866 856 if (depth == 0) 867 - return; 857 + return 0; 868 858 869 859 if (all_types) { 870 860 /* display all entries in name table to specified depth */ 871 - nametbl_header(buf, depth); 861 + ret += nametbl_header(buf, len, depth); 872 862 lowbound = 0; 873 863 upbound = ~0; 874 864 for (i = 0; i < tipc_nametbl_size; i++) { 875 865 seq_head = &table.types[i]; 876 866 hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { 877 - nameseq_list(seq, buf, depth, seq->type, 878 - lowbound, upbound, i); 867 + ret += nameseq_list(seq, buf + ret, len - ret, 868 + depth, seq->type, 869 + lowbound, upbound, i); 879 870 } 880 871 } 881 872 } else { 882 873 /* display only the sequence that matches the specified type */ 883 874 if (upbound < lowbound) { 884 - tipc_printf(buf, "invalid name sequence specified\n"); 885 - return; 875 + ret += tipc_snprintf(buf + ret, len - ret, 876 + "invalid name sequence specified\n"); 877 + return ret; 886 878 } 887 - nametbl_header(buf, depth); 879 + ret += nametbl_header(buf + ret, len - ret, depth); 888 880 i = hash(type); 889 881 seq_head = &table.types[i]; 890 882 hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { 891 883 if (seq->type == type) { 892 - nameseq_list(seq, buf, depth, type, 893 - lowbound, upbound, i); 884 + ret += nameseq_list(seq, buf + ret, len - ret, 885 + depth, type, 886 + lowbound, upbound, i); 894 887 break; 895 888 } 896 889 } 897 890 } 891 + return ret; 898 892 } 899 - 900 - #define MAX_NAME_TBL_QUERY 32768 901 893 902 894 struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space) 903 895 { 904 896 struct sk_buff *buf; 905 897 struct tipc_name_table_query *argv; 906 898 struct tlv_desc *rep_tlv; 907 - struct print_buf b; 899 + char *pb; 900 + int pb_len; 908 901 int str_len; 909 902 910 903 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NAME_TBL_QUERY)) 911 904 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 912 905 913 - buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_NAME_TBL_QUERY)); 906 + buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); 914 907 if (!buf) 915 908 return NULL; 916 909 917 910 rep_tlv = (struct tlv_desc *)buf->data; 918 - tipc_printbuf_init(&b, TLV_DATA(rep_tlv), MAX_NAME_TBL_QUERY); 911 + pb = TLV_DATA(rep_tlv); 912 + pb_len = ULTRA_STRING_MAX_LEN; 919 913 argv = (struct tipc_name_table_query *)TLV_DATA(req_tlv_area); 920 914 read_lock_bh(&tipc_nametbl_lock); 921 - nametbl_list(&b, ntohl(argv->depth), ntohl(argv->type), 922 - ntohl(argv->lowbound), ntohl(argv->upbound)); 915 + str_len = nametbl_list(pb, pb_len, ntohl(argv->depth), 916 + ntohl(argv->type), 917 + ntohl(argv->lowbound), ntohl(argv->upbound)); 923 918 read_unlock_bh(&tipc_nametbl_lock); 924 - str_len = tipc_printbuf_validate(&b); 925 - 919 + str_len += 1; /* for "\0" */ 926 920 skb_put(buf, TLV_SPACE(str_len)); 927 921 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); 928 922
+32 -26
net/tipc/port.c
··· 581 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 586 struct publication *publ; 587 + int ret; 587 588 588 589 if (full_id) 589 - tipc_printf(buf, "<%u.%u.%u:%u>:", 590 - tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr), 591 - tipc_node(tipc_own_addr), p_ptr->ref); 590 + ret = tipc_snprintf(buf, len, "<%u.%u.%u:%u>:", 591 + tipc_zone(tipc_own_addr), 592 + tipc_cluster(tipc_own_addr), 593 + tipc_node(tipc_own_addr), p_ptr->ref); 592 594 else 593 - tipc_printf(buf, "%-10u:", p_ptr->ref); 595 + ret = tipc_snprintf(buf, len, "%-10u:", p_ptr->ref); 594 596 595 597 if (p_ptr->connected) { 596 598 u32 dport = port_peerport(p_ptr); 597 599 u32 destnode = port_peernode(p_ptr); 598 600 599 - tipc_printf(buf, " connected to <%u.%u.%u:%u>", 600 - tipc_zone(destnode), tipc_cluster(destnode), 601 - tipc_node(destnode), dport); 601 + ret += tipc_snprintf(buf + ret, len - ret, 602 + " connected to <%u.%u.%u:%u>", 603 + tipc_zone(destnode), 604 + tipc_cluster(destnode), 605 + tipc_node(destnode), dport); 602 606 if (p_ptr->conn_type != 0) 603 - tipc_printf(buf, " via {%u,%u}", 604 - p_ptr->conn_type, 605 - p_ptr->conn_instance); 607 + ret += tipc_snprintf(buf + ret, len - ret, 608 + " via {%u,%u}", p_ptr->conn_type, 609 + p_ptr->conn_instance); 606 610 } else if (p_ptr->published) { 607 - tipc_printf(buf, " bound to"); 611 + ret += tipc_snprintf(buf + ret, len - ret, " bound to"); 608 612 list_for_each_entry(publ, &p_ptr->publications, pport_list) { 609 613 if (publ->lower == publ->upper) 610 - tipc_printf(buf, " {%u,%u}", publ->type, 611 - publ->lower); 614 + ret += tipc_snprintf(buf + ret, len - ret, 615 + " {%u,%u}", publ->type, 616 + publ->lower); 612 617 else 613 - tipc_printf(buf, " {%u,%u,%u}", publ->type, 614 - publ->lower, publ->upper); 618 + ret += tipc_snprintf(buf + ret, len - ret, 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 - 620 - #define MAX_PORT_QUERY 32768 621 626 622 627 struct sk_buff *tipc_port_get_ports(void) 623 628 { 624 629 struct sk_buff *buf; 625 630 struct tlv_desc *rep_tlv; 626 - struct print_buf pb; 631 + char *pb; 632 + int pb_len; 627 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 637 if (!buf) 632 638 return NULL; 633 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 643 spin_lock_bh(&tipc_port_list_lock); 637 644 list_for_each_entry(p_ptr, &ports, port_list) { 638 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 647 spin_unlock_bh(p_ptr->lock); 641 648 } 642 649 spin_unlock_bh(&tipc_port_list_lock); 643 - str_len = tipc_printbuf_validate(&pb); 644 - 650 + str_len += 1; /* for "\0" */ 645 651 skb_put(buf, TLV_SPACE(str_len)); 646 652 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); 647 653