aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/svc_xprt.c56
1 files changed, 39 insertions, 17 deletions
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index f200393ac87..6f33d33cc06 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -1098,36 +1098,58 @@ struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
1098} 1098}
1099EXPORT_SYMBOL_GPL(svc_find_xprt); 1099EXPORT_SYMBOL_GPL(svc_find_xprt);
1100 1100
1101/* 1101static int svc_one_xprt_name(const struct svc_xprt *xprt,
1102 * Format a buffer with a list of the active transports. A zero for 1102 char *pos, int remaining)
1103 * the buflen parameter disables target buffer overflow checking. 1103{
1104 int len;
1105
1106 len = snprintf(pos, remaining, "%s %u\n",
1107 xprt->xpt_class->xcl_name,
1108 svc_xprt_local_port(xprt));
1109 if (len >= remaining)
1110 return -ENAMETOOLONG;
1111 return len;
1112}
1113
1114/**
1115 * svc_xprt_names - format a buffer with a list of transport names
1116 * @serv: pointer to an RPC service
1117 * @buf: pointer to a buffer to be filled in
1118 * @buflen: length of buffer to be filled in
1119 *
1120 * Fills in @buf with a string containing a list of transport names,
1121 * each name terminated with '\n'.
1122 *
1123 * Returns positive length of the filled-in string on success; otherwise
1124 * a negative errno value is returned if an error occurs.
1104 */ 1125 */
1105int svc_xprt_names(struct svc_serv *serv, char *buf, int buflen) 1126int svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen)
1106{ 1127{
1107 struct svc_xprt *xprt; 1128 struct svc_xprt *xprt;
1108 char xprt_str[64]; 1129 int len, totlen;
1109 int totlen = 0; 1130 char *pos;
1110 int len;
1111 1131
1112 /* Sanity check args */ 1132 /* Sanity check args */
1113 if (!serv) 1133 if (!serv)
1114 return 0; 1134 return 0;
1115 1135
1116 spin_lock_bh(&serv->sv_lock); 1136 spin_lock_bh(&serv->sv_lock);
1137
1138 pos = buf;
1139 totlen = 0;
1117 list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list) { 1140 list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list) {
1118 len = snprintf(xprt_str, sizeof(xprt_str), 1141 len = svc_one_xprt_name(xprt, pos, buflen - totlen);
1119 "%s %d\n", xprt->xpt_class->xcl_name, 1142 if (len < 0) {
1120 svc_xprt_local_port(xprt)); 1143 *buf = '\0';
1121 /* If the string was truncated, replace with error string */ 1144 totlen = len;
1122 if (len >= sizeof(xprt_str)) 1145 }
1123 strcpy(xprt_str, "name-too-long\n"); 1146 if (len <= 0)
1124 /* Don't overflow buffer */
1125 len = strlen(xprt_str);
1126 if (buflen && (len + totlen >= buflen))
1127 break; 1147 break;
1128 strcpy(buf+totlen, xprt_str); 1148
1149 pos += len;
1129 totlen += len; 1150 totlen += len;
1130 } 1151 }
1152
1131 spin_unlock_bh(&serv->sv_lock); 1153 spin_unlock_bh(&serv->sv_lock);
1132 return totlen; 1154 return totlen;
1133} 1155}